相关疑难解决方法(0)

当函数具有特定大小的数组参数时,为什么它被指针替换?

鉴于以下计划,

#include <iostream>

using namespace std;

void foo( char a[100] )
{
    cout << "foo() " << sizeof( a ) << endl;
}

int main()
{
    char bar[100] = { 0 };
    cout << "main() " << sizeof( bar ) << endl;
    foo( bar );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

main() 100
foo() 4
Run Code Online (Sandbox Code Playgroud)
  1. 为什么数组作为指向第一个元素的指针传递?
  2. 它是C的遗产吗?
  3. 标准说什么?
  4. 为什么C++的严格类型安全性下降了?

c++ arrays standards sizeof function-parameter

65
推荐指数
2
解决办法
3万
查看次数

可靠地确定数组中的元素数量

每个C程序员都可以使用这个众所周知的宏来确定数组中元素的数量:

#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a])
Run Code Online (Sandbox Code Playgroud)

这是一个典型的用例:

int numbers[] = {2, 3, 5, 7, 11, 13, 17, 19};
printf("%lu\n", NUM_ELEMS(numbers));          // 8, as expected
Run Code Online (Sandbox Code Playgroud)

但是,没有什么能阻止程序员意外地传递指针而不是数组:

int * pointer = numbers;
printf("%lu\n", NUM_ELEMS(pointer));
Run Code Online (Sandbox Code Playgroud)

在我的系统上,这打印2,因为显然,指针是整数的两倍.我想过如何防止程序员错误地传递指针,我找到了一个解决方案:

#define NUM_ELEMS(a) (assert((void*)&(a) == (void*)(a)), (sizeof(a)/sizeof 0[a]))
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为指向数组的指针与指向其第一个元素的指针具有相同的值.如果改为传递指针,指针将与指向自身的指针进行比较,这几乎总是假的.(唯一的例外是递归的void指针,也就是指向自身的void指针.我可以忍受它.)

意外地传递指针而不是数组现在在运行时触发错误:

Assertion `(void*)&(pointer) == (void*)(pointer)' failed.
Run Code Online (Sandbox Code Playgroud)

太好了!现在我有几个问题:

  1. 我的用法是assert逗号表达式的左操作数有效标准C吗?也就是说,标准是否允许我assert用作表达式?对不起,如果这是一个愚蠢的问题:)

  2. 可以在编译时以某种方式完成检查吗?

  3. 我的C编译器认为这int b[NUM_ELEMS(a)];是一个VLA.有没有办法说服他呢?

  4. 我是第一个想到这个吗?如果是这样,我可以期待在天堂等待多少处女?:)

c arrays assert pointers sizeof

16
推荐指数
2
解决办法
2463
查看次数

标签 统计

arrays ×2

sizeof ×2

assert ×1

c ×1

c++ ×1

function-parameter ×1

pointers ×1

standards ×1