简体   繁体   English

指针仅保存其他变量的地址吗?

[英]Do pointers only hold addresses to other variables?

I am a bit confused when it comes to pointers. 当涉及到指针时,我有点困惑。

Some sample code: 一些示例代码:

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

p1 = str1;

On the the last line of code, if str1 contains 'Test', how come p1 now contains 'Test'. 在代码的最后一行,如果str1包含“ Test”,那么p1现在怎么包含“ Test”。 Isn't p1 still a pointer? p1还是指针吗? I thought pointers only contain addresses to other variables. 我认为指针仅包含指向其他变量的地址。

p1 doesn't contain Test . p1不包含Test It contains the address of a byte in memory that is set to the ASCII value of the character T , followed by e , s , t , and a 0. That address is the address of the array str1 , an 80 char array. 它包含一个内存中的字节地址,该地址设置为字符T的ASCII值,后跟est和0。该地址是数组str1的地址,即80个char数组。

If you try to print str1 or p1 , you'll get the output Test . 如果尝试打印str1p1 ,则会得到输出Test This is because you cannot pass arrays to functions, so if you try to, the array name will decay into a pointer to the first element, just like p1 . 这是因为您无法将数组传递给函数,因此,如果尝试这样做,数组名称将衰减为指向第一个元素的指针,就像p1一样。 So str1 will decay to a pointer to the T and p1 is already a pointer to the T so you get the same output when printing either because they both point to the same address in memory. 因此str1将衰减为指向T的指针,而p1已经为指向T的指针,因此您在打印时将获得相同的输出,因为它们都指向内存中的相同地址。

p1 is a pointer. p1是一个指针。

That means that p1 contains the memory address of the first character of str1 . 这意味着p1包含str1 第一个字符的内存地址。

When you went to see what p1 "held", you probably did something like cout << p1 , or cout << p1[3] . 当您去查看p1 “持有”的内容时,您可能执行了诸如cout << p1cout << p1[3] Either one of these will dereference p1 , treating it as a pointer-to-array-of-characters. 这些中的任何一个都将取消引用 p1 ,将其视为字符数组指针。

To see the actual value of p1 , try cout << (void*)p1 . 要查看p1的实际值,请尝试cout << (void*)p1 This will be the same as the actual value of str1 - a memory location which contains 'T', if you entered "Test". 这将与str1的实际值相同-如果您输入“ Test”,则该存储位置包含'T'。

Pointers hold address, nothing more. 指针保留地址,仅此而已。 Sometimes you dereference pointers to get the data, other times you pass the pointer around to code that will dereference it. 有时,您取消引用指针以获取数据,而有时将指针传递给将取消引用的代码。

For example : 例如 :

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");

You can emphasis the fact that p1 does not hold data other than the pointer by reorganizing your program like this : 通过这样重组程序,可以强调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");

Now to emphasis the fact that p1 and str1 are the same thing (the same address in memory), add this to the program : 现在要强调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");

What told you that p1 wasn't a pointer? 是什么告诉您p1不是指针?

Functions and operators like cout::<< and printf are designed to print strings (as well as other data types) so they will appropriately dereference pointer arguments for you: give it a pointer to a string and it will print the string at that address. cout::<<printf类的函数和运算符旨在打印字符串(以及其他数据类型),因此它们将为您适当地取消引用指针参数:为其提供指向字符串的指针,并将在该地址打印该字符串。 If you really want it to print the value of the pointer as an address, you have to cast it with (void *) . 如果您确实希望它将指针的值打印为地址,则必须使用(void *)

Do remember that, for array: 请记住,对于数组:

int array[N];

The usage of array would essentially mean &array[0] , and therefore, following are same: array的使用本质上是&array[0] ,因此,以下是相同的:

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

This way, when you do: 这样,当您执行以下操作时:

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

You can modify second line as: 您可以将第二行修改为:

pAddress = array;

And, just for completeness, following are same: 并且,仅出于完整性考虑,以下是相同的:

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

And so the following: 如下所示:

pAddress = array+5;
pAddress = &array[5];
printf("Address: %p\n", (void *)p1);

will print the address (from how to see address of a structure in printf ). 将打印地址(从如何在printf中查看结构的地址 )。

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

will print the string. 将打印字符串。

The first is the actual content of p1 , the second is what this content means in the context of your program: p1 is a pointer to char , which is the usual way in C to represent strings (ending with a 0 - '\\0' ). 第一个是p1的实际内容,第二个是该内容在程序上下文中的含义p1是指向char的指针,这是C语言中表示字符串的常用方式(以0- '\\0'结尾)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM