有一个问题要打印值的地址:
char word[] = "hi there"; //print address of string
int a = 1; // print address of 1
Run Code Online (Sandbox Code Playgroud)
我知道如何打印变量的地址,我认为值在变量地址内?那么值的地址实际上是变量地址?
这是一个棘手的问题,我是对的吗?
提前致谢
char word[]="hi there"; //print address of string
Run Code Online (Sandbox Code Playgroud)
word
是名为char数组的对象的名称.它有一个地址和大小.
在这个地址上,有第一个元素,一个带有值的char 'h'
.以下字母跟随下一个地址,直到最后一个'e'
.接下来是一个0字节的字符串终结符.因此,给定的字符加上0字节,数组的总大小为9:8.
+--+--+--+--+--+--+--+--+--+
|h |i | |t |h |e |r |e |# | <-- # means NUL byte.
+--+--+--+--+--+--+--+--+--+
+--+--+--+--+--+--+--+--+--+
|68|69|20|74|68|65|72|65|00|
+--+--+--+--+--+--+--+--+--+
Run Code Online (Sandbox Code Playgroud)
这里我们有一个专长:&word
并word
指向相同的地址,但它们代表的大小是不同的.&word
指向整个数组,因此sizeof(*(&word))
是9,而word
指向第一个字符,因此sizeof(*word)
是1.
据说" word
衰变到第一个元素的指针".
正如评论中所述,请注意这与案例略有不同
char * wordptr = "hi there";
Run Code Online (Sandbox Code Playgroud)
因为内存布局是相同的,但字符串位于只读内存中,而普通数据段包含指向该字符串的指针.所以&wordptr
,wordptr
和*wordptr
彼此完全不同:&wordptr
是char **
指向数据存储器,wordptr
是一个char *
指向RO内存(即,真正的字符串-准确的说,字符串的第一个字符),并*wordptr
仅仅是'h'
在开始.
OTOH,
int a = 1; // print address of 1
Run Code Online (Sandbox Code Playgroud)
a
是被调用对象的名称int
.它也有地址和大小.
它的大小依赖于实现,它的内存布局也是如此.让我们先拿一个最小字节的小端机器,让我们假设每个int有4个字节:
+--+--+--+--+
|01|00|00|00|
+--+--+--+--+
Run Code Online (Sandbox Code Playgroud)
您可以使用&word
和&a
取出它们的地址并打印出来:
printf("%p %p\n", &word, (void *)&a);
Run Code Online (Sandbox Code Playgroud)
((void *)
需要因为在某些实现中,指针的大小可能会有所不同,所以为了安全起见,我们需要转换指针类型.)
"地址1"这个词没有意义; 而你得到的地址的变量&a
保持值1,这只是"巧合":你可以设置a = 3
,地址保持不变,而存储在那里的值会发生变化.因此,确实更好地说"变量的地址正确地保持1".