Отличным источником для устранения путаницы является Питер Ван дер Линден, эксперт по программированию на C, секреты Deep C - то, что массивы и указатели не совпадают с тем, как они адресуются в памяти.
С массивом
char new_str[];
компилятор дал new_str адрес памяти, который известен как при компиляции, так и во время выполнения, например, 0x1234, следовательно, индексирование new_str просто с помощью
[]
. Например,
new_str[4]
, во время выполнения код выбирает адрес, где находится
new_str
, например, 0x1234 (это адрес в физической памяти). добавив к нему спецификатор индекса
[4]
, 0x1234 + 0x4, можно получить значение.
Принимая во внимание, что с указателем компилятор дает символу
char *newstr
адрес, например. 0x9876, но во время выполнения этот используемый адрес является схемой косвенной адресации. Предполагая, что newstr был malloc'd
newstr = malloc(10);
, происходит то, что каждый раз, когда в коде делается ссылка на использование newstr, так как адрес newstr известен компилятору, т. Е. 0x9876, но то, на что указывает newstr, является переменной , Во время выполнения код извлекает данные из физической памяти 0x9876 (т.е. newstr), но по этому адресу есть другой адрес памяти (поскольку мы его использовали malloc), например, 0x8765 именно здесь, код извлекает данные из этого адреса памяти, который malloc присваивается newstr, то есть 0x8765.
char new_str[]
и char *newstr
используются взаимозаменяемо, поскольку индекс нулевого элемента массива превращается в указатель , и это объясняет, почему вы могли newstr[5]
или *(newstr + 5)
Заметьте, как указатель выражение используется, хотя мы объявили char *newstr
, следовательно
<code>*(new_str + 1)</code> = *newstr;
ИЛИ
<code>*(new_str + 1)</code> = newstr[1];
Таким образом, реальная разница между ними заключается в том, как к ним обращаются в памяти.
Получите книгу, прочитайте ее, живите и дышите. Это блестящая книга! :)