-------- ------ p:| *--|----->| '0' | char -------- | '1' | char ...
тогда как char a[20]; это адрес начала массива (а вовсе не переменная):
------ a:| '0' | char | '1' | char ...
В нашем примере в файле b.c мы объявили внешний массив s как переменную. В результате компилятор будет интерпретировать начало массива s как переменную, содержащую указатель на char.
------ s:| '0' | \ это будет воспринято как | '1' | / адрес других данных. | '2' | ...
И индексироваться будет уже ЭТОТ адрес! Результат - обращение по несуществующему адресу. То, что написано у нас, эквивалентно
char s[] = "012345678"; char **ss = s; /* s - как бы "массив указателей" */ /* первые байты s интерпретируются как указатель: */ char *p = ss[0]; p[2] = '+';
Мы же должны были объявить в b.c
extern char s[]; /* размер указывать не требуется */
Вот еще один аналогичный пример, который пояснит вам, что происходит (а заодно покажет порядок байтов в long). Пример выполнялся на IBM PC 80386, на которой
sizeof(char *) = sizeof(long) = 4 a.c b.c
-------------------------------------------------- char s[20] = {1,2,3,4}; extern char *s; main(){ f(){ /*печать указателя как long */ f(); printf( "%08lX\n", s ); } }
печатается 04030201.
Что напечатает программа?static char str1[ ] = "abc"; static char str2[4]; strcpy( str2, str1 ); /* можно ли написать str2 = str1; ? */ printf( str1 == str2 ? "равно":"не равно" );
Как надо правильно сравнивать строки? Что на самом деле сравнивается в данном примере?
Ответ: сравниваются адреса массивов, хранящих строки. Так
char str1[2]; char str2[2]; main(){ printf( str1 < str2 ? "<":">"); }
печатает <, а если написать
char str2[2]; char str1[2];
то напечатается >.
Напишите программу, спрашивающую ваше имя до тех пор, пока вы его правильно не введете. Для сравнения строк используйте функцию strcmp() (ее реализация есть в главе "Мобильность").