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

时间:2018-10-07 23:22:15

标签: c casting point

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

2 个答案:

答案 0 :(得分:5)

如果您询问将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并将其用作获取{{1} }。

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

这是无效的代码-C标准未定义其行为。具体而言,它违反了C 2018 6.5 7,即说只能通过具有正确类型的左值表达式访问对象,该左值表达式具有与实际对象兼容的类型或某些其他情况,在此均不适用。在int所指向的位置,有一个指向q的指针,但是您试图像访问int一样访问它,这是不允许的。

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

C对于这种情况有特殊的规则。您允许 通过通过char访问组成对象的字节来检查它们。因此,如果将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 *的字节。但是,通常,不应将一个间接级别的指针转换为另一种间接级别的指针。

答案 1 :(得分:1)

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

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

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

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

0x0020 -> 0x0010 (unprintable)

这几乎毫无用处。将此随机数据解释为以空终止的字符串可能会造成灾难性的后果。