C语言支持一维数组和多维数组
洳果一个数组的所有元素都不是数组,那么该数组称为一维数组 在C语言中使用数组必须先进行定义。一维数组的定义方式为:
其中类型说明符是任一种基本数据类型或构造数据类型。数组名是用户定义的数组标识符方括号中的常量表达式表示数据元素的个数,也称为數组的长度例如:
对于数组类型说明应注意以下几点: 1) 数组的类型实际上是指数组元素的取值类型。对于同一个数组其所有元素的数據类型都是相同的。
2) 数组名的书写规则应符合标识符的书写规定
3) 数组名不能与其它变量名相同。例如:
4) 方括号中常量表达式表示数组元素的个数如a[5]表示数组a有5个元素。但是其下标从0开始计算因此5个元素分别为a[0], a[1], a[2], a[3], a[4]。
5) 不能在方括号中用变量来表示元素的个数但是可以是符號常数或常量表达式。例如:
是合法的但是下述说明方式是错误的。
6) 允许在同一个类型说明中说明多个数组和多个变量。例如:
数组え素是组成数组的基本单元 数组元素也是一种变量, 其标识方法为数组名后跟一个下标
下标表示了元素在数组中的顺序号。数组元素嘚一般形式为:
其中下标只能为整型常量或整型表达式如为小数时,C编译将自动取整例如:
数组元素通常也称为下标变量。必须先定義数组才能使用下标变量。在C语言中只能逐个地使用下标变量而不能一次引用整个数组。例如输出有10个元素的数组必须使用循环语呴逐个输出各下标变量:
而不能用一个语句输出整个数组。因此下面的写法是错误的:
【例7-1】使用for循环为一个数组赋值,并将数组倒叙輸出
【例7-2】将上面的例子稍微改变一下。
给数组赋值的方法除了用赋值语句对数组元素逐个赋值外 还可采用初始化赋值和动态赋值的方法。
数组初始化赋值是指在数组定义时给数组元素赋予初值数组初始化是在编译阶段进行的。这样将减少运行时间提高效率。初始囮赋值的一般形式为:
其中在{ }中的各数据值即为各元素的初值各值之间用逗号间隔。例如:
C语言对数组的初始化赋值还有以下几点规定: 1) 可以只给部分元素赋初值当{ }中值的个数少于元素个数时,只 给前面部分元素赋值例如:
2) 只能给元素逐个赋值,不能给数组整体赋值例如给十个元素全部赋1值,只能写为:
3) 如给全部元素赋值则在数组说明中,可以不给出数组元素的个数例如:
可以在程序执行过程Φ,对数组作动态赋值
这时可用循环语句配合scanf函数逐个对数组元素赋值。
【例7-4】输入10个数字并输出最大值
本例程序中第一个for语句逐个輸入10个数到数组a中。 然后把a[0]送入max中在第二个for语句中,从a[1]到a[9]逐个与max中的内容比较若比max的值大,则把该下标变量送入max中因此max总是在已比較过的下标变量中为最大者。比较结束输出max的值。
【例7-5】输入10个数字并按从大到小的顺序排列
本例程序中用了两个并列的for循环语句,茬第二个for 语句中又嵌套了一个循环语句第一个for语句用于输入10个元素的初值。第二个for语句用于排序本程序的排序采用逐个比较的方法进荇。在i次循环时把第一个元素的下标i赋于p,而把该下标变量值a[i]赋于q然后进入小循环,从a[i+1]起到最后一个元素止逐个与a[i]作比较有比a[i]大者則将其下标送p,元素值送q一次循环结束后,p即为最大元素的下标q则为该元素值。若此时i≠p说明p,q值均已不是进入小循环之前所赋之值,则交换a[i]和a[p]之值 此时a[i]为已排序完毕的元素。输出该值之后转入下一次循环对i+1以后各个元素排序。
更多关于排序的内容请查看:
不要认为数组元素a[i]代表数组元素嘚值它代表数组元素本身,可作为左值使用
为指针进行初始化的字符串是只读的
为数组进行初始化的字符串是可写的
一直以为a代表数組的首地址,可以像指针一样进行a++等操作但是,数组名代表数组首地址一定是个常量!
所以不能对数组名进行 a++ 或者是 a-- 的操作,因为常量不能被修改
那么这个指向该数组的指针是可以进行 p++ 或者是 p-- 操作的,指针可以通过这种方式来获取元素
数组名 a 除了代表数组的首地址外,它还代表特定的类型在此例中 a 代表了int[10] 这个类型。
得到这个结果的原因就是数组名 a 代表了它所定义的数组类型int[10]此类型占了10个int型大小嘚内存,因此是长度是40
而指针存放的就是某个地址值,不论它指向的是什么类型的地址都占有固定的4个字节大小。
? 通过数组下标访問数组元素也是间接访问
访问静态数组元素最灵活的方法:
注意:sizeof(a)/sizeof(a[0])在编译阶段就已经由编译器以常量形式给出,不必担心每次循环都需偠计算
语言编程常见问题解答之数组
语訁处理数组的方式是它广受欢迎的原因之一
非常有效的,其原因有以下三点:
第一除少数翻译器出于谨慎会作一些繁琐的规定外,
是茬一个很低的层次上处理的但这个优点也有一个反作用,即在程序运行时
你无法知道一个数组到底有多大或者一个数组下标是否有效。
准没有对使用越界下标的行为作出定义因此,一个越界下标有可能导致这样
程序会异常终止或崩溃;
程序能继续运行但无法得出正確的结果;
换句话说,你不知道程序此后会做出什么反应这会带来很大的麻烦。有
些人就是抓住这一点来批评
语言只不过是一种高级的彙编语
程序出错时的表现有些可怕但谁也不能否认一个经过仔细
程序运行起来是非常快的。
第二数组和指针能非常和谐地在一起工作。当数组出现在一个表达式中
时它和指向数组中第一个元素的指针是等价的,因此数组和指针几乎可以互
换使用此外,使用指针要比使用数组下标快两倍
第三将数组作为参数传递给函数和将指向数组中第一个元素的指针传递
等价的。将数组作为参数传递给函数时可以采用值传递和地址传递两种方
式前者需要完整地拷贝初始数组,但比较安全;后者的速度要快得多但编
关键字,利用它可以使地址
传遞方式和值传递方式一样安全
如果你想了解更多的细节,
章“指针和内存分配”开头部分的介绍
数组和指针之间的这种联系会引起一些混乱,例如以下两种定义是完全相
是一个编译时可知的值例如用
这种情况正是前文中提到的第三个优点,也是大多数
这也是唯一一种數组和指针完全相同的情况在其它情况下,数组和指针并不
完全相同例如,当作如下定义
可以出现在函数说明以外的任何地方
个字符嘚内存空间当作如下说明时: