Указатели содержат только адреса к другим переменным? - PullRequest
0 голосов
/ 13 февраля 2012

Я немного запутался, когда дело доходит до указателей.

Пример кода:

char str1[80];
char *p1;
cout <<"Enter a string"<<endl;
cin >> str1;

p1 = str1;

В последней строке кода, если str1 содержит «Test», почему p1 теперь содержит «Test». Разве p1 все еще не указатель? Я думал, что указатели содержат только адреса к другим переменным.

Ответы [ 6 ]

4 голосов
/ 13 февраля 2012

p1 не содержит Test. Он содержит адрес байта в памяти, для которого установлено значение ASCII символа T, за которым следуют e, s, t и 0. Этот адрес является адресом массива str1, массив 80 char.

Если вы попытаетесь напечатать str1 или p1, вы получите вывод Test. Это потому, что вы не можете передавать массивы в функции, поэтому, если вы попытаетесь это сделать, имя массива превратится в указатель на первый элемент, как p1. Так что str1 затухает до указателя на T, а p1 уже является указателем на T, поэтому вы получаете одинаковый вывод при печати либо потому, что они оба указывают на один и тот же адрес в памяти.

1 голос
/ 13 февраля 2012

Помните, что для массива:

int array[N];

Использование array будет по существу означать &array[0], и, следовательно, следующее будет таким же:

PrintAddress(&array[0]); // void PrintAddress(int*);
PrintAddress(array);

Таким образом, когда вы делаете:

int *pAddress;
pAddress = &array[0];
PrintAddress(pAddress);

Вы можете изменить вторую строку следующим образом:

pAddress = array;

И, просто для полноты, то же самое:

PrintAddress(&array[2]);
PrintAddress(array+2);

Ипоэтому следующее:

pAddress = array+5;
pAddress = &array[5];
1 голос
/ 13 февраля 2012

Что говорит вам, что p1 не является указателем?

Функции и операторы, такие как cout::<< и printf, предназначены для печати строк (а также других типов данных)поэтому они будут соответствующим образом разыменовывать аргументы указателя для вас: дайте ему указатель на строку, и он напечатает строку по этому адресу.Если вы действительно хотите, чтобы он указывал значение указателя в виде адреса, вы должны привести его к (void *).

1 голос
/ 13 февраля 2012

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

Например:

p1 = 0;  //Point to invalid memory address, but an address nonetheless
p1 = str1 //Point to a valid buffer. p1 now holds an new address, nothing else
if(*p1 == 'A')   //Dereference the pointer (gives a character)
    printf("The first character in str1 is A.\n");

Вы можете подчеркнуть тот факт, что p1 не содержит данных, кроме указателя, реорганизовав вашу программу следующим образом:

char str1[80];
char *p1;

p1 = str1; //Point to un-initialized memory, your compiler might complain.
           //but p1 is happy. It holds an address, it will never "hold" anything else.

//*p1 is valid (will not crash) but holds random garbage, do not use it!

cout <<"Enter a string"<<endl;
cin >> str1; //Now str1 was initialized

if(*p1 == 'A')   //Dereference the pointer (it is now a character)
    printf("The first character in str1 is A.\n");

Теперь, чтобы подчеркнуть тот факт, что p1 и str1 - это одно и то же (один и тот же адрес в памяти), добавьте это в программу:

str1[0] = 'A';   //Put a capital A in str1
if(*p1 == 'A')   //Dereference the pointer (it is now a character)
    printf("Now that we forced an A, this test is always true.\n");
1 голос
/ 13 февраля 2012

p1 - указатель.

Это означает, что p1 содержит адрес памяти , первый символ str1.

Когда вы пошли посмотреть, что "1010 *" удерживало ", вы, вероятно, сделали что-то вроде cout << p1 или cout << p1[3]. Любой из них будет разыменовываться p1, обрабатывая его как указатель на массив символов.

Чтобы увидеть фактическое значение p1, попробуйте cout << (void*)p1. Это будет то же самое, что и действительное значение str1 - ячейка памяти, которая содержит «T», если вы ввели «Test».

0 голосов
/ 13 февраля 2012
printf("Address: %p\n", (void *)p1);

напечатает адрес (из как посмотреть адрес структуры в printf ).

printf("String: %s\n", p1);

напечатает строку.

Первое - это фактическое содержимое p1, второе - это то, что означает в контексте вашей программы: p1 - указатель на char,обычный способ в C для представления строк (заканчивающийся на 0 - '\0').

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