栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

程序设计与C语言引论笔记——C语言数组的定义和初始化

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

程序设计与C语言引论笔记——C语言数组的定义和初始化

C语言数组的定义和初始化 一维数组

数组变量也是变量。数组定义的形式与简单变量类似,但需要增加有关元素个数的信息。在被定义变量名之后写一对方括号就是一个数组定义,指定元素个数的方式是在括号里写一个整型表达式。

int a[10]; 

//定义数组时没做初始化,
//如果是外部数组或局部静态数组,元素将自动初始化为 0,
//如果是自动数组,元素将不初始化,这些元素的值处在没有明确初始化的状态。

extern double a1[]; 
//在写数组变量的外部说明时不必写数组大小,只要在数组变量名后写一对方括号。
//这个说明通知本源文件的其他部分,有个数组a1在其他地方定义,它们的元素类型是双精度类型

数组元素个数必须能在编译时静态确定,根据这个规定,下面数组定义不合法:

 void f(int n) {  
     int b[n]; // 此时局部数组 b 的大小依赖于函数的参数值,这个值在编译时无法确定。
 }

全局数组和局部静态数组(用关键字 static)同样在程序开始执行前建立并初始化;

局部自动数组也是在程序执行进入相应函数时建立和初始化。

给数组指定初值也是在定义变量时通过附加描述给出元素初值:各元素值的表达式顺序在一对花括号里,表达式间用逗号分隔。例如:

int b[4] = {1, 1, 2, 3};  
//元素初值表达式必须是常量表达式,自动数组的初始化也只允许用常量表达式。
//初始化表示中元素的个数不超过数组元素的个数。

int b1[4] = {1, 2};  
//语言允许只给数组前一段元素指定初值,这时未指定值的元素将自动初始化为 0。
//因为 b1 的初值不够,b1[2]、b1[3]自动初始化为 0。
//(无论是外部数组还是自动数组)。

int b2[4] = {1, 2, 0, 0};//b1 和 b2 中各元素的值完全一样。

int fib1[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55};  
//为了编程方便,C 语言规定,在给出了所有元素初值的情况下,定义数组时可以不写大小。
//这时系统根据初始化表达式的个数自动确定数组大小。

int fib2[10] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55}; 
//数组 fib1 和 fib2 都是 10 个元素的整数数组,两种定义方式等价。
//前一写法能带来一点方便,因为这样能减少维护两部分描述之间一致性的麻烦,有利于程序修改。

应特别指出,这种为数组元素指定值的写法只能用在初始化时,语句里不能采用这种写法。

多维数组

C 语言里也能定义两维的和更多维的数组。

double a[3][2]; 
//在这里把两维数组看作一维数组的数组。
//也就是说,两维数组里的每个元素都是(成员类型相同,成员个数也相同的)一维数组。
//a 包含三个元素,每个元素各是一个双精度数组,其中包含了两个 double 元素。
//人们常说 a 是 3×2 的双精度数组。有时也说 a 是 3 行 2 列的数组,这是从矩阵概念那里借用的说法。

int a1[3][2][4];
//定义了一个三维数组.
//三维就不好说是二维数组的一维数组还是一维数组的二维数组了。
//准确地说,三维数组是一维数组的一维数组的一维数组。
//更多维的数组的定义也与此类似。

多维数组也可以在定义时直接初始化。

int a[3][2] = {{1, 2}, {3, 4}, {5, 6}};  
//内嵌各括号里的数据将用于初始化各个成员数组。
//这里要求各括号里表达式的个数都不超过成员数组长度,数据的组数不超过成员数组的个数。
//如果给出的表达式不够,相应成员数组 的其他成分也将被自动设置为 0。 

int b[3][2] = {1, 2, 3, 4, 5, 6}; 
//多维数组的初始化表示中也可以不写内嵌括号,采用平铺的写法。
//所列出的初始值按顺序,依次给各个成员数组的各成分置初值。
//如果初始值的个数不够,剩余成分也置 0。
//第二种形式写起来简单,但不如前一形式清晰。

int c[][2] = {{1, 2}, {3, 4}, {5, 6}};
int d[][2] = {1, 2, 3, 4, 5, 6};


一维数组采用连续顺序存储元素的方式实现。多维数组的内部表示也完全一样,同样是依次连续存放数组元素,即其中的各成员数组),而这些成员数组也按同样方式存放它们的元素。

一行(一个成员数组)的元素连续存放,这种形式又被称为按行存放,或者行优先存放。

字符数组

字符数组就是以字符作为元素的数组。由于人们常用 C 语言写与处理字符序列或文本的程序,而字符序列理所当然地应该存放在字符数组中,所以C为处理字符数组提供了特别支持。

对于程序中写出的字符串字面量,系统将用字符数组的形式对其进行存储他们:分配连续的若干个存储单元,顺序存入字符串中的各个字符,每个字符占据一个字节。在存储了字符串常量的所有字符之后,还要另外存一个空字符 '’作为字符串的结束标志。

例如下面的字符串虽然只有7个字符,其内部却要占据8个字节的存储。

用这种方式表示字符串是为了处理方便。字符串数据与基本类型的数据不同,不同的字符串可能有不同长度。这种情况下,程序怎么才能从字符串的内部表示确定字符串结束的位置呢?

有了字符串末尾的空字符,处理字符串的程序就可以顺序检查,遇到空字符就知道遇到了字符串结束。虽然空字符不是字符串内容的一部分, 但却是字符串表示中不可缺少的部分。

标准库的字符串处理函数都是基于这种表示定义的, 我们自己写字符串处理程序时也应该遵守这种规则。

下面的问题是:能在自己定义的字符数组里存放字符串吗?回答是肯定的,根据字符串存储形式的规定,只要在数组里顺序存入所需字符,随后存一个空字符,这个字符数组里的数据就有了字符串的表现形式,这个数组也就可以当作字符串使用了。在这种情况下,人们也说这个数组里存了一个字符串。例如有下面定义:

char a[5] = {'i', 's', 'n', 'o', 't'}, //数组a里存的不是字符串,因为缺少表示串结束的空字符
。
 b[5] = {'g', 'o', 'o', 'd'}, 
//数组 b是字符串,尽管提供的初始化表达式个数不够,
//但按C语言规定,数组剩余位置自动置为 0(字符值的 0 就是空字符),正好当作字符串结束标志。

 c[5] = {'f', 'i', 'n', 'e', ''}, 
//c 初始化时已在有效字符后加了一个空字符,所以它也存了一个字符串。

 d[5] = {'o', 'k', ''}; 
//数组 d 最后两个字符未给,同数组b一样,将自动设为空字符,对d作为字符串没有影响。
 e[5] = {'o', 'k', '', '?', '?'};
// 作为字符数组,e 的 5 个元素分别有了值,意义很清楚。
//如果将e 中数据当作字符串看待和处理,遇到空字符就认为串已结束,后面的东西对串处理已经没意义了。
//所以,如果 e 被作为字符串处理时,那就是一个只包含两个字符的串。

为了方便使用,C 语言为字符数组提供了特殊的初始化形式:允许以字符串形式为字符数组的一系列元素指定初值。这种初始化形式应看成一般形式的简写,例如可以写:

char a1[20] = "Peking University";
//a1 的前 18 个字符指定了值,不但有明确写出的 17 个字符,还有一个作为字符串结束的空字符。
//随后部分自动用空字符填充  

char a3[] = "Peking University"; 
//这定义了一个 18 个元素的数组,其中依次存放各字符,最后元素存入一个空字符。

如a [3],用字符串做字符数组初始化时也允许不直接给出数组元素个数。这时的数组大小规定为初始化字符串的字符数加 1,因为需要在数组最后存一个空字符。

字符数组可以用在各种需要字符串的地方。例如,如果程序里许多输出语句都用同样输出格式,一种可能方法就是定义一个公用的格式描述数组。例如下面例子:

 char outform1[] = "Two reals: %f, %fn";    printf(outform1, x, y);  

这样可以减少重复定义。对输入格式也可以采用同样技术。

参考书籍

《从问题到程序——程序设计与C语言引论》裘宗燕著,北京大学出版社,1999.4

《从问题到程序——程序设计与C语言引论》2003,2004年修订

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/384888.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号