简体   繁体   中英

what's the difference between char *s[] and char s[][20] in C?

Check this first code, If I write char *tracks[] instead of char tracks[][80] , it seems still working same perfectly.

#include <stdio.h>
#include <string.h>

char tracks[][80] = { "I left my heart in Harvard Med School",
        "Newark, Newark - a wonderful town", "Dancing with a Dork",
        "From here to maternity", "The girl from Iwo Jima", };

void find_track(char search_for[]) {    //'char *search_for' is equivalent.
    int i;
    for (i = 0; i < 5; i++) {
        if (strstr(tracks[i], search_for))
            printf("Track %i(Line %i):'%s'\n", i, i + 1, tracks[i]);
    }
}

int main() {
    char search_for[80];
    printf("Search for: ");
    scanf("%79s", search_for);  //fgets(search_for,80,stdin);
    find_track(search_for);
    return 0;
}

But check this second code, If I try to use char juices[][20] instead of char *juices[] , the compiler give error, I want to know why?

#include <stdio.h>
#include <string.h>

void print_reverse(char *s) {
    size_t len = strlen(s);
    char *t = s + len - 1;
    while (t >= s) {
        printf("%c", *t);
        t = t - 1; //pointer arithmetic
    }
    puts("");
}

int main() {
    char *juices[] = { "dragonfruit", "waterberry", "sharonfruit", "uglifruit",
            "rumberry", "kiwifruit", "mulberry", "strawberry", "blueberry",
            "blackberry", "starfruit" };

    char *a;

    puts(juices[6]);
    print_reverse(juices[7]);
    a = juices[2];
    juices[2] = juices[8];
    juices[8] = a;
    puts(juices[8]);
    print_reverse(juices[(18 + 7) / 5]);

    puts(juices[2]);
    print_reverse(juices[9]);
    juices[1] = juices[3];
    puts(juices[10]);
    print_reverse(juices[1]);

    return 0;
}

This is quite strange, because if you check third code below, it will give error because pointer to a string literal can not be updated. If the thing is like this, then in second code char *juices[] is array of pointers to string literals, and then juices[2] is a pointer to "sharonfruit" , how can it be updated?

#include <stdio.h>

int main()
{

char *cards = "JQK";  //you should use char cards[]="JQK";
char a_card = cards[2];

cards[2] = cards[1];
cards[1] = cards[0];
cards[0] = cards[2];
cards[2] = cards[1];
cards[1] = a_card;

puts(cards);

return 0;

}
char tracks[][80] = { "I left my heart in Harvard Med School",
    "Newark, Newark - a wonderful town", "Dancing with a Dork",
    "From here to maternity", "The girl from Iwo Jima", };

Creates an array of array of char or in other words, creates a two dimensional array of char and initializes each index with each strings. The number of strings is determined by the compiler during compile-time and the maximum size of each string is 80.

char *tracks[] = { "I left my heart in Harvard Med School",
    "Newark, Newark - a wonderful town", "Dancing with a Dork",
    "From here to maternity", "The girl from Iwo Jima", };

declares an array of char pointers. Each pointer points to each string literal. The number of pointers is determined by the compiler during compile-time.

String Literals are immutable meaning that it cannot be changed.

In your first two programs using tracks , the first version( char tracks[][80] ) and the second version( char* tracks[] ) works as strings aren't changed and arrays are not assigned .

In the second two programs using juices , the first version works( char* juices[] ) because pointers can be altered,ie, the location where they point to can be changed, but the second version( char juices[][80] ) doesn't because you assign arrays. Keep in mind that Arrays are not assignable .

To fix the problem, you can use the strcpy function from the string.h library to interchange the strings stored in char juices[][80] . Do note that memory needs to be allocated for variable a if you are going to attempt this.

In C, the "outermost" array (ie. the first [] ) are automatically type-converted to a pointer to the first element.

Thus,

char tracks[][80] 

declares a pointer to a char array (of length 80).

However

char *tracks[]

obviously is an array of char-pointers, which is something different. The compiler knows that and won't let you do that.

Also, these things are something different in memory: the array-compound definitely is linear in memory, the array of pointers might contain pointers that point anywhere in memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM