根据架构或编译器,'指针'的大小始终相同(4 / 8B /其他)。
int** b = &pointer;
int***c = &b;
sizeof(b)和sizeof(c)是相同的,因此我们可以以相同的方式取消引用它们。 如果指针指向指针的另一个指针或指针,我们只需要用两颗星声明它就不应该这样。
答案 0 :(得分:2)
考虑你的例子:
int* a = &integer
int** b = &a;
int*** c = &b;
他们都是不同类型。它们都是指针但它们指向指针的不同类型。
第一个是指向整数的指针。
第二个是指向整数指针的指针。
第三个是指向指向整数指针的指针的指针。
在查看指针指向的位置(解除引用)时,这很重要。
如果我这样做:
*b; // what is that?
我从中得到一个整数吗?没有!我把自己放进去了:
int** b = &a;
我得到a
这是一个指向整数的指针,不一个int
,它是指向int <的指针/ em>的。
如果我想要int
,我必须再次取消引用:
**b; // now I located the integer
所以*b
是int*
而**b
是原int
。
答案 1 :(得分:1)
不重要。指针算法完全取决于它指向的内容。例如,int(*p)[2]
和int *p
两者都不同。 int **p
和int ***p
的方式不同。您可能会认为,即使sizeof (int*)
和sizeof(int**)
相同 - ,丢失多个间接信息 也不符合逻辑。有正确的指针算法很有帮助。 (如果它们的大小相同,它将是相同的但指针算术将没有问题,但它将以其他方式存在问题 - 请参阅问题的第二段)。
请注意,这些对我们来说非常有帮助 - 想想一个系统,您将负责编写正确的代码来解除引用变量正确的次数。你必须记住它指向的地方?它是变量的地址还是指向指针的指针。这将简单地使C编程只是写下底层汇编语言 - 我们将不得不处理原始地址。然后想想,要记住需要解除引用的次数,您需要维护一些元数据以及该变量 - 正是编译器通过保留类型信息int*
或int**
来存储的内容。
答案 2 :(得分:1)
在第2行和第3行中,两个变量指针指向某个地址
右。 b
的地址为(指向)a
,c
的地址为b
。
我认为你要问的是,因为b
有类型&#34;指向某事物的指针&#34;并且c
的类型为&#34;指向指向某事物的指针&#34;,然后b
和c
将具有非常相似的表示,并将使用非常相似的代码。这是真的......但是。
C中的指针算法不仅仅是生成的机器语言。我们并不关心b
是指向某事物&#34;的指针,因为我们需要知道如果我们取消引用它将导致的值的类型< / em>的。实际上,b
指向int
的指针,然后是*b
(即&#34; b
的内容,指的是b
当我们取消引用*c
)是指向int的指针时,我们得到。另一方面,b
是指向int的指针。因此c
和void **
不是相同的类型。
如果你真的真的想要,在实践中你可以使用你的信念,即使用int integer = 5;
int *a = &integer;
void **b, **c; // "generic pointer to pointer"
b = (void **)&a;
c = (void **)&b;
printf("the int: %d\n", integer);
printf("via pointer: %d\n", *a);
printf("via 2-level pointer: %d\n", **(int **)b);
printf("via 3-level pointer: %d\n", ***(int ***)c);
作为&#34;泛型,指针的所有指针都具有基本相同的类型指向指针的指针&#34;类型。但是你必须使用一堆额外的,明确的演员阵容:
{{1}}
但是这段代码更难写,更难阅读,更难以思考。它也不是严格的便携式或符合标准。
(你可能会问,&#34;实际上,在什么样的机器上它不起作用?&#34;,我承认我不能说出一个;它可以在我们目前认为实用的任何机器上正常工作但是代码仍然难以编写,更难以阅读,也更难以思考。)