指针的大小,C中指向指针的指针

Size of pointer, pointer to pointer in C

我怎样才能证明下面 C 程序的输出是正确的?

#include <stdio.h>

char *c[] = {"Mahesh", "Ganesh", "999", "333"};
char *a;
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;

int main(void) {
    printf("%d %d %d %d ",sizeof(a),sizeof(c),sizeof(cp),sizeof(cpp));
    return 0;
}

版画

4 16 16 4 

为什么?

Here is the ideone link如果你想fiddle用它。

a 是一个指针。 cpp 也是一个指向不同类型的指针(指向指针的指针)。 现在 c 是一个数组。你有 4 个元素,每个元素都是一个指针,所以你有 4 * 4 = 16(如果你在 x64 上 运行 它会有所不同)。 cp 也类似。尝试将类型更改为 int,您会看到不同之处。

a通常是一个指针,代表内存地址。在 32 位操作系统上,32 位(4 字节)无符号整数用于表示地址。因此,sizeof(a)4.

c是一个有4个元素的数组,每个元素都是一个指针,它的大小是4*4 = 16

cp也是一个数组,每个元素都是一个指针(第一个*,指向另一个指针(第二个*)。后面的指针指向一个内存中的字符串。因此它的基本元素大小应该代表一个指针的大小。然后sizeof(cp) = 4*4 = 16

cpp 是一个指针的指针的指针。它也代表 32 位内存地址。因此它的 sizeof 也是 4.

所以你得到 4 16 16 4 的原因是因为 'a' 本身只是一个指针,它只需要 4 个字节(因为指针持有 32 位地址,具体取决于你的体系结构)所以当你有一个 **pointer == 到 *pointer[] 时,你实际上创建了一个指针数组,并且因为你初始化了 4 个创建 4 个指针的东西,因此 4x4 = 16。对于 cpp 你可能会问 "well wouldn't it then be 16 as it was initalized?" 而答案是否定的,因为 *** 指针是它自己的独立变量并且仍然只是一个指针(指向指针的指针,或指向指针数组的指针),并且只需要 4 个字节的内存。

char *c[] = {"Mahesh", "Ganesh", "999", "333"};

c 是一个 char* 指针数组。初始值设定项的长度为 4 个元素,因此它的类型为 char *[4]。该类型的大小,因此 c,是 4 * sizeof (char*).

char *a;

achar*.

类型的指针
char **cp[] = {c+3, c+2, c+1, c};

cp 是一个 char** 指针数组。初始化器有 4 个元素,所以它的类型是 char **[4]。它的大小是 4 * sizeof (char**).

char ***cpp = cp;

cpp 是指向 charchar*** 的指针的指针。它的大小是 sizeof (char***).

您的代码使用 %d 打印尺寸值。这是不正确的——但它恰好适用于您的系统。可能 intsize_t 大小相同。要正确打印 size_t 值,请使用 %zu —— 或者,如果该值不是很大,您可以将其转换为 int 并使用 %d。 (%zu 格式是在 C99 中引入的;可能仍然有一些实现不支持它。)

您获得的特定尺寸:

sizeof a == 4
sizeof c == 16
sizeof cp == 16
sizeof cpp == 4

特定于您的系统。显然您的系统使用 4 字节指针。其他系统可能有不同大小的指针; 8 个字节很常见。几乎所有系统都对所有指针类型使用相同的大小,但这并不能保证;例如,char* 可能大于 char***。 (某些系统可能需要更多信息来指定内存中的字节位置而不是字位置。)

(您会注意到我省略了 sizeof 表达式上的括号。这是合法的,因为 sizeof 是一个运算符,而不是一个函数;它的操作数是一个表达式(可能或可能没有括号)或括号中的类型名称,例如 sizeof (char*).)