这个问题摆在了C大师面前:

在C语言中,可以按如下方式声明指针:

char (* p)[10];

…它基本上表示这个指针指向一个由10个字符组成的array.像这样声明一个指针的好处是,如果你试图将一个不同大小的数组指针分配给p,你会得到一个编译时错误.如果你试图将一个简单的字符指针的值分配给p,它也会给你一个编译时错误.我用gcc试过了,它似乎适用于ANSI、C89和C99.

在我看来,这样声明一个指针会非常有用--特别是在向函数传递指针时.通常,人们会这样编写这样一个函数的原型:

void foo(char * p, int plen);

如果需要特定大小的缓冲区,只需测试plen的值.但是,不能保证将p传递给您的人会在该缓冲区中真正为您提供plen有效的内存位置.你必须相信调用这个函数的人做了正确的事情.另一方面:

void foo(char (*p)[10]);

..会强制调用方为您提供指定大小的缓冲区.

这似乎非常有用,但我从未在我遇到的任何代码中看到过这样声明的指针.

我的问题是:人们为什么不这样声明指针呢?我没有看到明显的trap 吗?

推荐答案

我想补充一下AndreyT的答案(以防有人无意中发现这个页面,想了解更多关于这个话题的信息):

当我开始更多地使用这些声明时,我意识到在C语言中(显然不是在C++中)存在与之相关的主要障碍.很常见的情况是,您希望给调用者一个指向已写入缓冲区的常量指针.不幸的是,在C中声明这样的指针时,这是不可能的.换句话说,C标准(6.7.3-第8段)与以下内容不一致:


   int array[9];

   const int (* p2)[9] = &array;  /* Not legal unless array is const as well */

这种约束似乎不存在于C++中,使得这些类型的声明更有用.但在C语言中,每当需要指向固定大小缓冲区的常量指针时,就必须回到常规指针声明(除非缓冲区本身首先声明为常量).你可以在这个邮件线程中找到更多信息:link text

在我看来,这是一个严格的限制,这可能是人们通常不会在C中声明这样的指针的主要原因之一.另一个原因是,正如AndreyT指出的那样,大多数人甚至不知道可以声明这样的指针.

C++相关问答推荐

如何将一个integer与一个数组进行比较?

如何将匿名VLA分配给指针?

如何判断宏参数是否为C语言中的整型文字

初始变量重置后,char[]的赋值将消失

插座打开MacOS组件

Kdb:仅升级指定的列

从uint8_t*转换为char*可接受

防止C++中递归函数使用堆栈内存

如何读取文件并将内容保存在字符串中?(在C语言中,没有崩溃或核心转储错误)

S和查尔有什么不同[1]?

在vfork()之后,链接器如何在不 destruct 父内存的情况下解析execve()?

';\n&39;和';\r&39;中的';\n&39;之间有什么关系?

某些EAX值的不同调用方的CPUID结果不一致

GETS()在C++中重复它前面的行

计算SIZE_MAX元素的长数组的大小

在下面的C程序中,.Ap0是如何解释的?

STM32:代码的执行似乎取决于它在闪存中的位置

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

如何为avr atmega32微控制器构建C代码,通过光电二极管捕获光强度并通过串行通信传输数据

在C中定义函数指针?