C中数组的const和typedef

Cya*_*yan 19 c arrays typedef const

在C中,typedef使用这种结构可以使用数组:

typedef int table_t[N];

这里,table_t现在定义为N的数组int.声明的任何变量table_t t;现在将表现为正常数组int.

这种构造的要点是在函数中用作参数类型,例如:

int doSomething(table_t t);

一个相对等效的函数原型可能是:

int doSomething(int* t);

第一个结构的优点是它强制执行N表的大小.在许多情况下,强制执行此属性更安全,而不是依赖程序员来正确地找出这种情况.

现在一切都很好,除了为了保证表的内容不会被修改,有必要使用const限定符.

以下陈述相对简单易懂:

int doSomething(const int* t);

现在,doSomething保证它不会修改作为指针传递的表的内容.现在,这几乎相同的建筑怎么样?:

int doSomething(const table_t t);

这是什么const?表的内容,或指向表的指针?如果它是指针const,是否有另一种方式(C90兼容)保留定义表大小的能力并告诉它的内容将是const?

请注意,有时还需要修改表的内容,因此该const属性不能嵌入到typedef定义中.

[ 编辑 ]感谢到目前为止收到的优秀答案.总结一下:

  • typedef强制执行大小N的初始假设是完全错误的.它基本上与普通指针的行为相同.
  • const属性的行为也与指针相同(与指针类型的typedef形成鲜明对比,如下面的@random所示)
  • 要强制执行一个大小(这不是最初的问题,但最终现在非常重要......),请参阅Jonathan的回答

Jen*_*edt 10

首先,你错了,函数原型

int doSomething(table_t t);
int doSomething(int* t);
Run Code Online (Sandbox Code Playgroud)

完全相同.对于函数参数,始终将第一个数组维重写为指针.因此无法保证接收到的阵列大小.

const- 数组的限定始终适用于数组的基类型,因此这两个声明

const table_t a;
int const a[N];
Run Code Online (Sandbox Code Playgroud)

是等价的,我们有函数参数

int doSomething(const table_t t);
int doSomething(int const* t);
Run Code Online (Sandbox Code Playgroud)


Ram*_*man 9

表的内容将是不变的.使用此代码轻松检查.

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,现在是正确的,尽管你没有解释它为什么会这样. (3认同)

Ran*_*832 5

数组类型和指针类型不是 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
}
Run Code Online (Sandbox Code Playgroud)

它的作用类似于const int *,但const pointer_t等效于int * const

(另外,免责声明,POSIX 不允许以 _t 结尾的用户定义名称,它们保留用于将来的扩展)