c - почему имеет смысл, что указатель на символьный указатель является int? - PullRequest
4 голосов
/ 18 апреля 2010
char *a = "apple";
printf("%s\n", a);  // fine
printf("%s\n", a[1]);  // compiler complains an int is being passed

Почему индексирование указателя строки дает мне int? Я ожидал, что он просто напечатает строку, начиная с первой позиции (что на самом деле происходит, когда я использую &a[1]). зачем мне нужен адрес?

Ответы [ 5 ]

13 голосов
/ 18 апреля 2010

Так определен оператор [] - a[1], когда a равен char *, получает следующий char после того, на который указывает a (a[0] - первый один).

Вторая часть головоломки состоит в том, что значения char всегда повышаются до int (или редко unsigned int), когда передаются как часть списка аргументов переменной длины функции.

a эквивалентен &a[0] и печатается с первого символа - поэтому имеет смысл, что &a[1] будет печататься, начиная со второго символа. Вы также можете просто использовать a + 1 - это полностью эквивалентно.

Если вы используете спецификатор преобразования %c, который печатает один символ, вы можете использовать a[1] для печати только второго символа:

printf("%c\n", a[1]);
6 голосов
/ 18 апреля 2010

Выражение a[1] дает один символ , а в выражениях это расширение int .
Вы можете напечатать символ с помощью %c:

char *a = "apple";
printf("%c\n", a[1]);   // prints 'p'

Вы можете достичь того, что хотите, используя a+1, например

printf("%s\n", a+1);    // prints 'pple'

Другой способ объяснить это:

char *a2 = a+1;   // a2 points to 'pple'   
a[1] ≡ *(a+1)  ≡ *a2 
2 голосов
/ 18 апреля 2010

Символы (то есть то, что оценивается в [1]) являются целыми числами, но средство форматирования "% s" для printf () ожидает указатель. Обратите внимание, что тот факт, что эта ошибка была обнаружена вообще, является расширенной функцией, предлагаемой некоторыми компиляторами - она ​​не является частью стандарта C. Другие компиляторы просто потерпят неудачу во время выполнения, возможно, с дампом ядра.

2 голосов
/ 18 апреля 2010

% s ожидает указатель на символ *. Только символ Char интерпретируется как целое число. Более того, [1] дает вам второй элемент, а не первый!

0 голосов
/ 18 апреля 2010
char *a = "bla"

a: char*, и вы должны использовать %s для printf(...);

a[1] эквивалентно *(a+1), тогда a[1] - это char, и вы должны использовать %c для printf(...);

&a[1] эквивалентно &(*(a+1)), тогда &a[1] - это char*, и вы должны использовать %s для printf(...);

Это больше похоже на вопрос указателя. Чтобы лучше понять, как работают указатели, подумайте так:

char *j;

j является char*
*j является char и эквивалентно j[0]
*(j+1) является char и эквивалентно j[1]
&(*j) - это char*, и эквивалентно &j[0], эквивалентно j
&j char** 1045 *

Другой пример:

char j**

j является char**
*j является char*
**j - это char, и эквивалентно *(*(j+0)+0), и эквивалентно j[0][0]
&j является char***

и так далее ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...