Попробуйте:
printf("Address of theString = %p, value of theString = %s\n", (void *) theString, theString);
printf("Address of i = %p, value of i = %p\n", (void *) &i, (void *) i );
printf("Address of j = %p, value of j = %p\n", (void *) &j, (void *) j );
theString
, i
и j
- все отдельные объекты в памяти, поэтому они будут иметь разные адреса.i
и j
будут иметь одинаковое значение , то есть адрес theString
.
Некоторые примечания:
За исключением случаев, когда он является операндом операторов sizeof
или унарных &
или является строковым литералом, используемым для инициализации массива символовв объявлении выражение типа «массив N-элементов из T
» будет преобразовано («распад») в выражение типа «указатель на T
» и значениевыражение будет адресом первого элемента.Таким образом, в первом операторе printf
вам не нужен оператор &
для получения адреса theString
.Оба выражения theString
и &theString
будут вычисляться по адресу первого элемента массива, но типы выражений будут разными (char *
против char (*)[MAX]
).
Спецификатор преобразования %p
ожидает, что его соответствующий аргумент будет иметь тип void *
.Это единственное место в C, где вам нужно явно привести выражение указателя к void *
.
Типы i
и j
равны char *
, поэтому типы выражений &i
и &j
равны char **
,
РЕДАКТИРОВАТЬ
Я взял ваши объявления и запустил их через собственную утилиту дампа памяти:
#include "dumper.h"
#define MAX 32
int main( void )
{
char theString[MAX+1] = "All your base are belong to us";
char *i = theString;
char *j = theString;
char *names[] = {"theString", "i", "j" };
void *addrs[] = {theString, &i, &j};
size_t sizes[] = { sizeof theString, sizeof i, sizeof j };
dumper( names, addrs, sizes, 3, stdout );
return 0;
}
И вотвывод:
Item Address 00 01 02 03
---- ------- -- -- -- --
theString 0x7ffee727fa90 41 6c 6c 20 All.
0x7ffee727fa94 79 6f 75 72 your
0x7ffee727fa98 20 62 61 73 .bas
0x7ffee727fa9c 65 20 61 72 e.ar
0x7ffee727faa0 65 20 62 65 e.be
0x7ffee727faa4 6c 6f 6e 67 long
0x7ffee727faa8 20 74 6f 20 .to.
0x7ffee727faac 75 73 00 00 us..
0x7ffee727fab0 00 00 00 00 ....
i 0x7ffee727fa20 90 fa 27 e7 ..'.
0x7ffee727fa24 fe 7f 00 00 ....
j 0x7ffee727fa18 90 fa 27 e7 ..'.
0x7ffee727fa1c fe 7f 00 00 ....
x86 имеет младший порядок, поэтому многобайтовые значения нужно читать справа налево, снизу вверх.Вы увидите, что i
и j
содержат одно и то же значение (0x7ffee727fa90
), которое является адресом первого элемента theString
.