Работа с программами в отладчике и проверка значений всего, что помогло мне понять указатели. Также нарисуйте много картинок на доске, чтобы укрепить ваше понимание. То, что по-настоящему закрепило это для меня, это изучение ассемблера и создание MIPS с нуля ...
Попробуйте пройти через это в своем отладчике и нарисуйте несколько диаграмм на доске, чтобы отследить выполнение.
#include <stdio.h>
int main()
{
char c_arr[3] = {'a', 'b', '\0'}; // Array of 3 chars.
char* c_ptr = c_arr; // Now c_ptr contains the address of c_arr.
// What does it mean that c_ptr "contains the address of c_arr"?
// Underneath all this talk of "pointers" and "arrays", it's all
// just numbers stored in memory or registers. So right now, c_ptr is
// just a number stored somewhere in your computer.
printf("%p\n", c_ptr);
// I got `0xbf94393d`. You'll get something different each time you run it.
// That number (0xbf94393d) is a particular memory location. If you
// want to use the contents of that memory location, you use the *
// operator.
char ch = *c_ptr;
// Now ch holds the contents of whatever was in memory location 0xbf94393d.
// You can print it.
printf("%c\n", ch);
// You should see `a`.
// Let's say you want to work with the next memory location. Since
// the pointer is just a number, you can increment it with the ++ operator.
c_ptr++;
// Let's print it to see what it contains.
printf("%p\n", c_ptr);
// I got 0xbf94393e. No surprises here, it's just a number -- the
// next memory location after what was printed above.
// Again, if we want to work with the value we can use the *
// operator. You can put this on the left side of an assignment
// to modify the memory location.
*c_ptr = 'z';
// Since c_ptr was pointing to the middle of our array when we
// performed that assignment, we can inspect the array to see
// the change.
printf("%c\n", c_arr[1]);
// Again, c_ptr is just a number, so we can point it back to
// where it was. You could use -- for this, but I'll show -=.
c_ptr -= 1;
// We can also move by more than one. This will make the pointer
// contain the address of the last memory location in the array.
c_ptr = c_ptr + 2;
return 0;
}
Вот моя попытка сделать снимок. Эта коробка - память вашего компьютера. Каждому месту в памяти присваивается номер, мы называем этот номер адресом.
++++++++++++++++++++++++++++++++++++++++++++
| NAME | ADDRESS | VALUE |
+=========+==============+=================+
| c_arr | 0xbf94393d | 'a' |
| | 0xbf94393e | 'b' |
| | 0xbf94393f | '\0' |
+---------+--------------+-----------------+
| c_ptr + <someaddr> | 0xbf94393d |
+------------------------------------------+
Когда вы открываете, скажем, c_arr[0]
, вы работаете с верхней строкой в таблице. Обратите внимание, что c_ptr
имеет в качестве значения адрес верхней строки в таблице. Когда вы говорите *c_ptr
, вы указываете ЦПУ использовать 0xbf94393d
в качестве адреса для работы. Так что *c_ptr = 'z'
немного похоже на высказывание «Эй, иди на 0xbf94393d и оставь там« z »» - на этой улице адреса действительно большие.