将 char** 转换为 char* - 它会改变它指向的内容吗?

Casting char** to char* - Does it change what it points to?

如果我有一个指向 char* 数组的指针,换句话说,一个名为 p1 的 char**,如果我执行 (char*)p1 会得到什么?我猜会有一些精度损失。我会丢失什么信息,p1 现在指向什么?谢谢!

如果您询问过将 int ** 转换为 int *,答案会有所不同。让我们先考虑一下,因为我怀疑它更能代表你想问的问题,而且 char * 的情况更复杂,因为它涉及到一个特殊的目的。

假设您有几个 intint a, b, c, d;。您可以创建一个指向它们的指针数组:int *p[] = { &a, &b, &c, &d };。您还可以创建指向这些指针之一的指针:int **q = &p[1];。现在 q 指向 p[1],其中包含 b.

的地址

当你写 *q 时,编译器知道 q 指向一个指向 int 的指针,所以它知道 *q 指向一个 int .如果你写 **q,编译器知道 *q 指向一个 int,将从内存中获取 *q 并将其用作获取 [=14= 的地址].

如果将 q 转换为 int * 并尝试使用它,会发生什么情况,如 printf("%d\n", * (int *) q);?当您将 q 转换为 int * 时,您(错误地)告诉编译器将其视为指向 int 的指针。然后,* (int *) q 告诉编译器转到该地址并获得 int.

这是无效代码 — C 标准未定义其行为。具体来说,它违反了 C 2018 6.5 7,其中规定对象只能由具有正确类型的左值表达式访问——要么是与实际对象的类型兼容的类型,要么是某些其他情况,none 其中在这里申请。在 q 指向的地方,有一个指向 int 的指针,但您试图像访问 int 一样访问它,这是不允许的。

现在让我们考虑 char **char * 的情况。和以前一样,您可能需要一些 char **q 并将其转换为 char *。现在,您要告诉编译器转到 q 点的位置,那里有指向 char 的指针,并像那里有 char 一样访问该内存位置。

C 对这种情况有特殊的规定。您 允许通过 char * 访问组成对象的字节来检查它们。因此,如果将 char ** 转换为 char * 并使用它,如 * (char *) q 中那样,结果将是构成指针的第一个(最低地址)字节。您甚至可以使用如下代码查看其余字节:

char *t = (char *) q;
printf("%d\n", t[0]);
printf("%d\n", t[1]);
printf("%d\n", t[2]);
printf("%d\n", t[3]);

此代码将向您显示构成指向 char 指针的前四个字节的十进制值,该指针位于 q.

指定的位置

总而言之,将 char ** 转换为 char * 将允许您检查表示 char * 的字节。但是,一般来说,您不应将一个间接级别的指针转换为另一间接级别的指针。

当我将指针视为内存地址而不是一些抽象的高级事物时,我发现指针更有意义。

所以一个char**是一个内存地址,它指向一个字符。

0x0020 -> 0x0010 -> 0x0041 'A'

投射时,您改变了数据的解释,而不是实际数据。所以 char* 是

0x0020 -> 0x0010 (unprintable)

这几乎肯定没有用。将此随机数据解释为空终止字符串可能是灾难性的。