IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 程序设计与C语言引论笔记——C语言数组的定义和初始化 -> 正文阅读

[C++知识库]程序设计与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为处理字符数组提供了特别支持。

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

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

image-20211029130022771

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

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

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

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

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', '\0'}, 
//c 初始化时已在有效字符后加了一个空字符,所以它也存了一个字符串。

 d[5] = {'o', 'k', '\0'}; 
//数组 d 最后两个字符未给,同数组b一样,将自动设为空字符,对d作为字符串没有影响。
 e[5] = {'o', 'k', '\0', '?', '?'};
// 作为字符数组,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, %f\n";  /* 程序中可以使用这个格式描述 */  printf(outform1, x, y);  

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

参考书籍

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

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

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-30 12:23:34  更:2021-10-30 12:23:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:22:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码