指针的大小,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;
a
是 char*
.
类型的指针
char **cp[] = {c+3, c+2, c+1, c};
cp
是一个 char**
指针数组。初始化器有 4 个元素,所以它的类型是 char **[4]
。它的大小是 4 * sizeof (char**)
.
char ***cpp = cp;
cpp
是指向 char
或 char***
的指针的指针。它的大小是 sizeof (char***)
.
您的代码使用 %d
打印尺寸值。这是不正确的——但它恰好适用于您的系统。可能 int
和 size_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*)
.)
我怎样才能证明下面 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;
a
是 char*
.
char **cp[] = {c+3, c+2, c+1, c};
cp
是一个 char**
指针数组。初始化器有 4 个元素,所以它的类型是 char **[4]
。它的大小是 4 * sizeof (char**)
.
char ***cpp = cp;
cpp
是指向 char
或 char***
的指针的指针。它的大小是 sizeof (char***)
.
您的代码使用 %d
打印尺寸值。这是不正确的——但它恰好适用于您的系统。可能 int
和 size_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*)
.)