void foo(int myArray[10]);这样的函数仍可接收整数指针int *,但是长度[10]可以对阅读代码的人们可当作文档,传达着这相函数预期一个长度为10个整数的数组的信息.
void bar(int myArray[static 10]);
1.编译器在优化代码时能够用到这些信息[2]
2.当编译一个带有上述声明的bar时,如果传递下面三种实参[3]进去, 编译器能够警告调用者:
a. 传递NULLbar(NULL);warning: null passed to a callee which requires a non-null argument [-Wnonnull] bar(NULL); ^ ~~~~
int a[9]; bar(a);warning: array argument is too small; contains 9 elements, callee requires at least 10 [-Warray-bounds] bar(a); ^ ~
int b[11]; bar(b);
[no output]
[1]. 也可以在括号中使用const关键字. 这会让指向myArray的指针变成指针常量.[2].不确实编译器是否真的会优化代码, 因为寄希望于程序员们都留心编译警告信息是十分不靠谱的.[3].使用的编译器:Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn).
"C99扩展了声明形式参数的语句. 一个用于修饰数组的限制符列表允许出现在数组声明者的最上层[]括号中.数组限制符(类型限制符)const, volatile和restrict将数组和指针类型等同对待.也就是说,这样的参数声明:T A[qualifier-list e]与以下声明等价:T *qualifier-list e例子:给出这些C99中的声明:
extern int f(int x[const 10]); extern int g(const y[10]);
那么在f函数中参数x会被看成是int * const类型(这是一个指向整型的指针常量), 而在g函数中参数y被看成它有const int *类型(也就是一个指向整型常量的指针).译注:指向整型的指针常量,是指针的值无法改变,它指向一个可变的整型变量,也即无法改变p的值,但是*p的值是可以改的. 而后面的常量指针,是指向一个整型常量的指针,也就是p可以改变,但是*p是无法改变的.在C99中,数组限制符static也允许出现在数组的括号之中.它对C的实现(编译器)是一个优化提示,断言实际的数组参数不能是NULL并且在进入函数体时要有所声明的类型和长度.如果没有这个限制符,NULL指针就可以当作实参作为数组传进来,就会使编译器很难知道它是安全的,比如,当在进入函数时要预取一个输入数组参数的内容时.另外,对于原型(不能是函数定义)中的C99形式数组参数声明,其长度可以用星号(*)替代,这意味着实参将会是一个可变长数组.在原型声明中作为数组大小的任何非常量表达式与星号是等价.函数定义时必须提供一个非常量的表达式作为数组大小."
void foo(int a[], int len);