OP描述了一个函数func()
,其签名如下。
void func(size_t n, const int (*arr)[n])
OP想要调用它通过传递不同的数组
#define SZ(a) (sizeof(a)/sizeof(a[0]))
int array1[3];
func(SZ(array1), &array1); // problem
const int array2[3] = {1, 2, 3};
func(SZ(array2), &array2);
如何将const正确应用于作为参数传递的数组指针?使用C11,使用_Generic进行必要的转换。只有当输入是可接受的非const类型时,才会发生转换,从而保持类型安全性。这就是“如何”做到这一点。OP可能认为它很“臃肿”,因为它类似于
this。这种方法简化了宏/函数调用,只需要一个参数。
void func(size_t n, const int (*arr)[n]) {
printf("sz:%zu (*arr)[0]:%d\n", n, (*arr)[0]);
}
#define funcCC(x) func(sizeof(*x)/sizeof((*x)[0]), \
_Generic(x, \
const int(*)[sizeof(*x)/sizeof((*x)[0])] : x, \
int(*)[sizeof(*x)/sizeof((*x)[0])] : (const int(*)[sizeof(*x)/sizeof((*x)[0])])x \
))
int main(void) {
#define SZ(a) (sizeof(a)/sizeof(a[0]))
int array1[3];
array1[0] = 42;
const int array2[4] = {1, 2, 3, 4};
func(SZ(array2), &array2);
funcCC(&array1);
funcCC(&array2);
return 0;
}
输出
sz:4 (*arr)[0]:1
sz:3 (*arr)[0]:42
sz:4 (*arr)[0]:1
或者代码可以使用
#define funcCC2(x) func(sizeof(x)/sizeof((x)[0]), \
_Generic(&x, \
const int(*)[sizeof(x)/sizeof((x)[0])] : &x, \
int(*)[sizeof(x)/sizeof((x)[0])] : (const int(*)[sizeof(x)/sizeof((x)[0])])&x \
))
funcCC2(array1);
funcCC2(array2);
int ia[3]
,应该使用int *arr
来传递数组本身。或者,为了对称性,可以像传递数组一样声明参数:int arr[]
,并使用形式参数的隐式转换。 - too honest for this siteint *param
,参数int param[n]
并没有增加类型安全性的保障。 - Lundin*
。明白了。 - too honest for this site