简体   繁体   English

这个指针做了什么?

[英]what does this pointer do?

char* p = "hello world";

programmers usually assigns the address of an variable to a pointer. 程序员通常将变量的地址分配给指针。 But in the above case, where is the pointer pointing to? 但在上面的例子中,指针指向哪里?

and what in the world is 以及世界上有什么

int x =42;
int* p= &x;
int ** r = &p;

It's pointing to an area in the program's read-only memory (usually in the program's machine code itself) containing the ASCII sequence hello world . 它指向程序的只读存储器中的一个区域(通常在程序的机器代码本身中),其中包含ASCII序列hello world Compare this to: 比较这个:

char p[] = "hello world";

Which creates an array of 12 char s on the stack, which is modifiable just like any other variable, and to: 这会在堆栈上创建一个包含12个char的数组,可以像任何其他变量一样进行修改,并且:

char *p = strdup("hello world");

Which creates an array of 12 char s on the heap, and sets p to be a pointer to this readable and writable space of heap memory. 这产生12个阵列char S于堆,并且将p是一个指针堆内存的此可读写的空间。

As for your (totally unrelated) second question: 至于你(完全不相关)的第二个问题:

int** r = &p;

Is simpler than it looks, though it's also bad. 比它看起来更简单,虽然它也很糟糕。 &p is the address of p. &p&p地址 So if we did: 所以如果我们这样做:

int x;
int *y = &x;

Then the pointer y points to the variable x , so assigning to *y changes x (and vice versa). 然后指针y 指向变量x ,因此分配给*y改变x (反之亦然)。 We can do this for arbitrarily complex types: 我们可以为任意复杂的类型执行此操作:

int *x;
int **y = &x;

Now y is still a pointer that points to x , but x is also a pointer. 现在y仍然是一个指向x的指针,但x也是一个指针。 So in your example, r is a pointer to a pointer to an int , and it's value is the address of p (a pointer to a char ). 所以在你的例子中, r是指向int的指针,它的值是p的地址(指向char的指针)。 However, it's a bad idea to do this because many platforms have alignment issues with casting from a char * type to a larger pointer type. 但是,执行此操作是一个坏主意,因为许多平台在从char *类型转换为更大的指针类型时存在对齐问题。

The string constant "hello world" must reside somewhere in the application and will be loaded into memory at runtime. 字符串常量“hello world”必须位于应用程序的某个位置,并在运行时加载到内存中。 Typically this is in the data section of the executable. 通常,这是在可执行文件的数据部分中。 The pointer p points to this address in memory. 指针p指向内存中的该地址。

The second example simply takes the address of p. 第二个例子只是取p的地址。 Given that p is on the stack it will be an address into the current stack. 假设p在堆栈上,它将成为当前堆栈的地址。

An illustration might be helpful. 插图可能会有所帮助。 Given the following declarations: 鉴于以下声明:

char *s = "hello world";
int   x = 45;
int  *p = &x;
int **r = &p;
char q[] = "hello world";

assume the following memory map (addresses and layout are completely arbitrary and aren't meant to represent any real-world architecture): 假设以下内存映射(地址和布局完全是任意的,并不代表任何真实的架构):

0x00  0x01  0x02  0x03 
    0x00008000:  'h'   'e'   'l'   'l'   
    0x00008004:  'o'   ' '   'w'   'o'
    0x00008008:  'r'   'l'   'd'   0x00  
    ...
s:  0x01000000:  0x00  0x00  0x80  0x00  
x:  0x01000004:  0x00  0x00  0x00  0x2D
p:  0x01000008:  0x01  0x00  0x00  0x04
r:  0x0100000C:  0x01  0x00  0x00  0x08
q:  0x01000010:  'h'   'e'   'l'   'l'
    0x01000014:  'o'   ' '   'w'   'o'
    0x01000018:  'r'   'l'   'd'   0x00

The string literal "hello world" is a 12-element array of char ( const char in C++) with static extent, meaning that memory is allocated for it when the program starts and remains allocated until the program terminates. 字符串文字“hello world”是一个12元素的char数组(C ++中的const char ),具有静态范围,这意味着在程序启动时为其分配内存并保持分配直到程序终止。 Exactly where the string literal lives in memory depends on the platform, but it's best to assume that memory is unwritable (ie, you can't change its contents with strcpy() or strcat() or sprintf() , etc.). 字符串文字在内存中的确切位置取决于平台,但最好假设内存是不可写的(即,您不能使用strcpy()strcat()sprintf()等更改其内容)。 The language standard explicitly states that attempting to modify a string literal results in undefined behavior. 语言标准明确指出,尝试修改字符串文字会导致未定义的行为。

The line 这条线

char *s = "hello world";

defines s as a pointer to char initializes it with the address of the literal (0x00008000 in this example). s定义为char的指针,使用文字的地址 (在本例中为0x00008000)初始化它。

The line 这条线

int x = 45;

defines x as an integer and initializes it with the value 45 (2D in hexadecimal notation). x定义为整数,并使用值45(以十六进制表示的2D)初始化它。

The line 这条线

int *p = &x;

defines p as a pointer to int and initializes it with the address of x (0x01000004). p定义为指向int的指针,并使用地址x (0x01000004)对其进行初始化。

The line 这条线

int **r = &p;

defines r as a pointer to a pointer to int and initializes it with the address of p (0x01000008). r定义为指向int的指针,并使用地址p (0x01000008)对其进行初始化。

Note that pointer types are distinct and not always compatible. 请注意,指针类型是不同的,并不总是兼容。 Even though s , p , and r all resolve to 32-bit address values in this particular hypothetical, they have different types and are not necessarily interchangable, even if they were all set to point to the same location. 即使spr都在这个特定的假设中解析为32位地址值,它们也有不同的类型 ,并且不一定是可互换的,即使它们都设置为指向同一位置。 Some platforms use different sizes and representations for different pointer types. 某些平台对不同的指针类型使用不同的大小和表示。

And finally, as an added bonus, we have the line 最后,作为额外的奖励,我们有了这条线

char q[] = "hello world";

which defines q as a 12-element array of char (size taken from the size of the string literal being used to initialize it) and initializes it with the contents of the string literal. 它将q定义为12个元素的char数组(大小取自用于初始化它的字符串文字的大小),并使用字符串文字的内容对其进行初始化。

The asterisk sign used when declaring a pointer only means that it is a pointer (it is part of its type compound specifier), and should not be confused with the dereference operator, also an asterisk. 声明指针时使用的星号符号表示它是一个指针(它是其类型复合说明符的一部分),不应与取消引用运算符混淆,也不应与星号混淆。

If you want to access the value it returns, you must precede it with a double asterisk. 如果要访问它返回的值,则必须在其前面加上双星号。

p points to the first character of a NUL-terminated string. p指向NUL终止字符串的第一个字符。 r points to a pointer ... that is to say that it points to a location which holds pointer, to an integer. r指向一个指针......也就是说它指向一个将指针保持为整数的位置。

p is a memory address stored with "hello world" , so the memory p'address has a address position... p是存储在"hello world"的内存地址,因此内存p'address具有地址位置...

int** r = &p;

so r is a reference to that address...kinda messed 所以r是对那个地址的引用......有点混乱

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

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