C语言的创造者们一定都热衷于让关键字的数目尽可能的少.今天将向你展示另一个可使用C99中static关键字地方.
也许你已经看到过在数组的参数声明中包括数组的长度:
void foo(int myArray[10]);
这样的函数仍可接收整数指针int *,但是长度[10]可以对阅读代码的人们可当作文档,传达着这相函数预期一个长度为10个整数的数组的信息.
除此之外,你还可以在括号之中加上static关键字[1]:
void bar(int myArray[static 10]);
这会告诉编译器:函数会假定传进来的实参至少有10个元素.(值得注意的是这就会把NULL排除在外!)
这样做有二个目的:
1.编译器在优化代码时能够用到这些信息[2]
2.当编译一个带有上述声明的bar时,如果传递下面三种实参[3]进去,编译器能够警告调用者:
a. 传递NULL
bar(NULL);
warning: null passed to a callee which requires a non-null argument [-Wnonnull]
bar(NULL);
^ ~~~~
b. 传递一个(比10)更小的数组
int a[9];
bar(a);
warning: array argument is too small; contains 9 elements, callee requires at least 10 [-Warray-bounds]
bar(a);
^ ~
c. 传递一个(比10)更大的数组
这在当你确信函数能接收的数组的长度时很有用, 因为它既可以为阅读代码的人提供文档信息,又能让编译器帮忙捕获错误.
[1]. 也可以在括号中使用const关键字. 这会让指向myArray的指针变成指针常量.
[2].不确实编译器是否真的会优化代码, 因为寄希望于程序员们都留心编译警告信息是十分不靠谱的.
[3].使用的编译器:Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn).
看过这篇文章,但去查了C语言的参考手册<C A Reference Manual>,发现C99中在函数参数声明时,的确允许在数组的括号中加上限制符. 以下译自<C A Reference Manual> Chap 9, 9.3 FORMAL PARAMETER DECLARATION, P296
"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形式数组参数声明,其长度可以用星号(*)替代,这意味着实参将会是一个可变长数组.在原型声明中作为数组大小的任何非常量表达式与星号是等价.函数定义时必须提供一个非常量的表达式作为数组大小."
其实这里面提到的目的都是让编译器在编译时帮忙探测更多的错误.但是貌似大多数编译并不支持对函数声明数组参数的修饰,比如以上的例子在gcc中就完全没有效果,gcc不会给出任何提示.上面的建议只有static的修饰有实用意义,那就是帮忙排除NULL实参.其他的都仅有学术研究价值.
其实,在实际使用过程中,对于数组的参数,都必须同时给出另外一个参数来传达数组的长度,就像这样:
void foo(int a[], int len);
这是提倡的,也是大量普遍使用的方式.
分享到:
相关推荐
labview中的数组索引详细讲解,写的挺详细的,应该能解决你关于这个问题的困惑
在labview中可以索引数组
该文件由带有 MUX、DeMUX、Vector Concatenate 和简单 MATLAB 函数的数组索引组成。 它将给出从多项式中提取系数并从数组向量中提取元素的基本思想。
C语言中的数组索引必须保证位于合法的范围内! 示例代码如下: enum {TABLESIZE = 100}; int *table = NULL; int insert_in_table(int pos, int value) { if(!table) { table = (int *)malloc(sizeof(int) *TABLE...
C语言实现的词索引表程序:IndexBook。C语言实现按照索引插入并查找元素。严蔚敏建立词索引表:严蔚敏数据结构C语言实现,串操作应用举例中的词索引表例子,由于作者没给出完整源码,自己写了一个比较完整的。
day05_11_常见问题_数组索引越界异常
数组是一组连续可索引的具有相同内在数据类型的元素所成的集合,在未指定为变体变量情况下。 2、上界、下界和下标 上界:数组某一维可用的最大下标。用Ubound 函数表示。 下界:数组某一维的最小下标。默认最小下标...
LabVIEW清华题库练习3-1 创建一个自动索引的数组.vi
//索引实际上就是序数,一个整型数字 alert(ary1[0]); alert(ary1[1]); alert(ary1[2]); alert(ary1[3]); /* 关联数组,指以非序数类型为下标来存取的数组 python中称为字典 */...
给定一个数组,可以想象通过向各个方向填充原始数组而形成的虚拟数组。 此虚拟数组的有效下标范围包括所有负整数和正整数,而不考虑原始数组的大小。 这个函数实现了这个想法。 可以通过多种方式进行填充。 实现了...
c#数组索引器集合典型程序示例,简单易学。
本文探讨了Matlab中矩阵数组的相关内容,包括创建矩阵数组、矩阵数组运算、矩阵数组索引、矩阵数组函数和矩阵数组应用。Matlab中的矩阵数组是一个强大的工具,可用于解决各种数学和工程问题。 在实际应用中,矩阵...
c语言 c语言编程题之数组操作寻找数组的中心索引
新手,框架熟悉人员
php图片加文本或水印,可用于生成图片证书....
numpy的delete是可以删除数组...axis = None:表示把数组按一维数组平铺在进行索引删除 返回:一个新的子数组 x = array([[1,2,3], [4,5,6], [7,8,9]]) 1.删除第i行和多行操作 x = numpy.delete(x,i, axis = 0) 删除
C# 索引器 索引 数组 C# 索引器 索引 数组 C# 索引器 索引 数组 C# 索引器 索引 数组 C# 索引器 索引 数组 C# 索引器 索引 数组
● 复制数组:使用System.arraycopy()方法或Arrays.copyOf()方法将一个数组复制到另一个数组中。 ● 排序数组:使用Arrays.sort()方法对数组进行排序。 ● 搜索数组:使用Arrays.binarySearch()方法在一个已排序的...
初学者labview索引数组中的相同元素
分享一个实现缩略图和加水印的php类,设置图片的参数,进行图片的缩放,然后给图片增加水印。