Разница между ptr, ptr [0] и & ptr [0] в строках C - PullRequest
0 голосов
/ 02 ноября 2018

Я изучал строки в C и столкнулся со следующей проблемой в следующем коде:

#include <stdio.h>
int main()
{
   char *p = "foo";
   printf("%p\t%p\t%p",&p[0],p,p[0]);
   return 0;

}

И у меня есть следующий вывод:

00403024        00403024        00000066
Process returned 0 (0x0)   execution time : 0.057 s
Press any key to continue.

Поскольку p указывает на первый элемент строки, не должен ли p [0] указывать на тот же адрес, что и p (и, как следствие, & p [0])?

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Вы поняли это почти правильно. Указатель просто хранит адрес указателя, на который он указывает. Таким образом, вывод p выводит адрес строки.

Так что же делает [x] применительно к такому адресу p? Это *(p+x); то есть он оценивается как значение, которое хранится по этому адресу плюс x. Таким образом, в случае p[0] вы получите значение ASCII символа 'f', которое равно 66.

Повторный адрес этого адреса с префиксом & дает адрес, где он хранится. Конечно, это просто адрес исходной строки, потому что, как вы заметили, адрес строки совпадает с адресом ее первого элемента.

0 голосов
/ 02 ноября 2018

p[0] это не указатель, это char.

Поскольку вы запрашиваете %p в строке формата, он принудительно приводится к неверному указателю со значением 0x00000066, которое является просто значением ASCII f, первого символа в строке.

Если вы включите все предупреждения, которые предлагает ваш компилятор, вы можете увидеть предупреждение, которое подчеркивает это преобразование и его потенциальную ошибку.

p относится к типу char*. &p[0] похоже на &(*(p + 0)), то есть вы отменяете ссылку на char, а затем превращаете его обратно в указатель с помощью &. Конечный результат такой же, как и в оригинале.

...