[英]Understanding pointer to pointer concept
我是C的初学者,我试图理解指针指针的概念。 我有以下示例
int main() {
char *names[]={"Peter", "Dan"};
printf("names = %p\n", names);
printf("(char *)names = %p\n", (char *)names);
printf("(char **)names = %p\n", (char **)names);
printf("*(char *)names = %p\n", *(char *)names);
printf("*(char **)names = %p\n", *(char **)names);
return 0;
}
Output:
names = 0x7fff167f7c00
(char *)names = 0x7fff167f7c00
(char **)names = 0x7fff167f7c00
*(char *)names = 0x58
*(char **)names = 0x400658
这里我的问题为什么*(char *)名称不会返回0x400658? 从上面的输出我可以看到(char *)名称的值是0x7fff167f7c00,现在,如果我取消引用它,它应该显示我0x400658对吗?
有人可以解释一下这是如何工作的吗?
初步问题后编辑:
我做了一些进一步的分析并找出了一些理论,但仍需要帮助才能理解。 在执行(char *)名称时,它认为它是指向char的指针因此*(char *)名称打印0x400658的地址的1字节,即0x58。 但在(char **)名称的情况下,它认为作为指针的指针,当解除引用时,它给出整个地址ie0x400658。 下面将帮助像我这样的新手更多地了解这一点
printf("notes =%p\n", notes);
printf("(char *)notes+1 =%p\n", ((char *)notes+1));
printf("(char **)notes+1 =%p\n", ((char **)notes+1));
Output:
notes =0x7fff75e4c260
(char *)notes+1 =0x7fff75e4c261
(char **)notes+1 =0x7fff75e4c268
以上是我的理论,但现在让我说我观察到的是正确的,但有时我会低于输出
*(char **)notes =0x4007ec
*(char *)notes =0xffffffec
考虑到我的理论是正确的,这应该是0xec? 为什么它附加了ffff? 我错过了什么吗?
以下是我的阅读方式:
// (char*) is an address (of char): 8 bytes
(char *) names = 0x7fff167f7c00 // actual address of names
// (char**) is an address (of char*): 8 bytes
(char **) names = 0x7fff167f7c00 // actual address of names.
// *(char*) is a char: 1 byte.
*(char *) names = 0x58 // first byte of the first value of names (ie address of "Peter").
// *(char **) is an address (of char): 8 bytes
*(char **)names = 0x400658 // first value of names (ie address of "Peter").
关于0xec
。
此代码: printf("*(char *)names = %p\\n", *(char *)names);
打印指针(因为%p
),给定的值是*(char *)
即char
。
发生的事情是给定的char(1个字节)在打印之前被转换为指针(8个字节)。
此转换旨在失败。 您不能拥有来自单个数据位的有效指针。
对于0x58
,因为char是88而88是8字节整数是0x00..0058
它被打印为0x58
。
Char是签名类型。 0xec
,因为char是-20,而作为4字节有符号整数的-20是0xffffffec
,符号字节填充所有新位。 这称为符号传播 。
所以你可以看到0xec
被转换为0x00000000ffffffec
。 为什么符号传播仅发生在前4个字节上可能有多种解释。 我看到的第一个是性能。
无论如何,char到指针的转换将取决于编译器,目标等......并且因为结果是无法使用的,所以它可以是任何东西。
names变量的类型是指向char的指针。 通过使用表达式*(char *)名称,您假设名称是指向char的指针并取消引用它,即*(char *)名称表达式的类型为char。
您通过将char **对象类型转换为char *对象来引入错误。 因此,你不能指望在两种情况下得到相同的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.