C中数组的const和typedef
在C语言中,可以使用以下结构C中数组的const和typedef,c,arrays,constants,typedef,C,Arrays,Constants,Typedef,在C语言中,可以使用以下结构typedef数组: typedef int table_t[N]; 这里,表t现在定义为Nint的数组。声明的任何变量,如表\t现在将作为int的普通数组 这种构造的要点是用作函数中的参数类型,例如: int剂量测定法(表t); 相对等效的功能原型可能是: int剂量测量(int*t); 第一个构造的优点是它强制执行N作为表的大小。在许多情况下,强制执行此属性比依赖程序员正确地找出此条件更安全 现在一切都好了,只是为了保证表的内容不会被修改,有必要使用cons
typedef
数组:
typedef int table_t[N];
这里,表t
现在定义为Nint
的数组。声明的任何变量,如表\t
现在将作为int
的普通数组
这种构造的要点是用作函数中的参数类型,例如:
int剂量测定法(表t);
相对等效的功能原型可能是:
int剂量测量(int*t);
第一个构造的优点是它强制执行N
作为表的大小。在许多情况下,强制执行此属性比依赖程序员正确地找出此条件更安全
现在一切都好了,只是为了保证表的内容不会被修改,有必要使用const
限定符
以下陈述相对容易理解:
int剂量测量(常数int*t);
现在,doSomething
保证它不会修改作为指针传递的表的内容。
那么,这个几乎相等的结构呢
int剂量测量(常数表);
这里的const
是什么?表的内容,还是指向表的指针?
如果指针是常量,是否有另一种方法(C90兼容)来保留定义表的大小并告诉其内容是常量的能力
请注意,有时还需要修改表的内容,因此不能将const
属性嵌入到typedef定义中
[编辑]感谢迄今为止收到的优秀答案。
总结如下:
- 最初假设的大小为N是完全错误的。它的行为基本上与普通指针相同
属性的行为也将与指针相同(与指针类型的typedef形成鲜明对比,如下@random所示)const
- 要强制实施尺寸(这不是最初的问题,但现在非常重要…),请参阅
#include<stdio.h>
typedef int table_t[3];
void doSomething(const table_t t)
{
t++; //No error, it's a non-const pointer.
t[1]=3; //Error, it's a pointer to const.
}
int main()
{
table_t t={1,2,3};
printf("%d %d %d %ld",t[0],t[1],t[2],sizeof(t));
t[1]=5;
doSomething(t);
return 0;
}
#包括
typedef int table_t[3];
无效剂量测定(常数表)
{
t++;//没有错误,它是一个非常量指针。
t[1]=3;//错误,它是指向常量的指针。
}
int main()
{
表t={1,2,3};
printf(“%d%d%d%ld”,t[0],t[1],t[2],sizeof(t));
t[1]=5;
剂量测定法(t);
返回0;
}
首先,您弄错了,函数原型
int doSomething(table_t t);
int doSomething(int* t);
它们完全相等。对于函数参数,第一个数组维度始终重写为指针。因此,无法保证接收到的阵列的大小
const
-对数组的限定始终应用于数组的基类型,因此这两个声明
const table_t a;
int const a[N];
是等价的,对于函数参数
int doSomething(const table_t t);
int doSomething(int const* t);
标准6.7.6.3规定: 作为“类型数组”的参数声明应调整为“类型的限定指针” 这意味着当您将函数参数声明为
const int
数组类型时,它将衰减为指向const int
(数组中的第一个元素)的指针。在这种情况下相当于const int*
还请注意,由于上述规则,指定的数组大小不会增加额外的类型安全性!这是C语言的一大缺陷,但事实就是如此
尽管如此,最好像以前一样使用固定宽度声明数组,因为静态分析器或智能编译器可能会生成关于不同类型的诊断
第一个构造的优点是它将N强制为表的大小
我不知道你在这里是什么意思。在什么情况下它会“强制”它?如果将函数声明为
int doSomething(table_t t);
将不强制执行数组大小。我想强制执行尺寸,你得走另一条路
int doSomething(table_t *t); // equivalent to 'int (*t)[N]'
这里的常数是什么
至于常数
。。。当const
应用于数组类型时,它会一直“下拉”到数组元素。这意味着const table\u t
是常量int
s的数组,即它相当于const int[N]
类型。这样做的最终结果是数组变得不可修改。在函数参数声明上下文中,const table\u t
将转换为const int*
但是,请注意一个在本例中并不明显的特殊细节:数组类型本身保持非常量限定。是单个元素变成了const
。事实上,在C中不可能对数组类型本身进行常量限定。任何这样做的尝试都会使常量限定“筛选”到单个元素
这种特性导致了数组常量正确性方面相当令人不快的结果。例如,此代码不会在C中编译
table_t t;
const table_t *pt = &t;
尽管从const正确性的角度来看它看起来很天真,并且将针对任何非数组对象类型进行编译。C++语言更新了它的正确性规则来解决这个问题,而C继续坚持它的旧方法。
数组类型和指针类型不是100%等价的,即使在这样的上下文中,你最终得到函数函数的指针类型。您的错误在于假设
const
如果是指针类型,其行为方式也会相同
要扩展ARBY的示例,请执行以下操作:
typedef int table_t[3];
typedef int *pointer_t;
void doSomething(const table_t t)
{
t++; //No error, it's a non-const pointer.
t[1]=3; //Error, it's a pointer to const.
}
void doSomethingElse(const pointer_t t)
{
t++; //Error, it's a const pointer.
t[1]=3; //No error, it's pointer to plain int
}
它的作用类似于int*const
,但const pointer\u t
却相当于int*const
(另外,免责声明,POSIX不允许使用以_t结尾的用户定义名称,它们是为将来的扩展保留的。)