繁体   English   中英

理解指针指针的概念

[英]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.

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