C/C++教程

C程序设计语言-第六章 利用数组处理批量数据

本文主要是介绍C程序设计语言-第六章 利用数组处理批量数据,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

第六章 利用数组处理批量数据

  • 6.1 怎样定义和引用一维数组
    • 6.1.1 怎样定义一维数组
    • 6.1.2 怎样引用一维数组元素
    • 6.1.3 一维数组的初始化
    • 6.1.4 一维数组应用举例
  • 6.2 怎样定义和引用二维数组
    • 6.2.1 怎样定义二维数组
    • 6.2.2 怎样引用二维数组的元素
    • 6.2.3 二维数组的初始化
    • 6.2.4 二维数组程序举例
  • 6.3 字符数组
    • 6.3.1 怎样定义字符数组
    • 6.3.2 字符数组的初始化
    • 6.3.3 怎样引用字符数组中的元素
    • 6.3.4 字符串和字符串结束标志
    • 6.3.5 字符数组的输入输出
    • 6.3.6 使用字符串处理函数

6.1 怎样定义和引用一维数组

(1)数组是一组有序数据的集合。 数组中各数据的排列是有一定规律的,下标代表数据在数组中的序号。
(2)用一个数组名和小标来唯一地确定数组中的元素。
(3)数组中的每一个元素都属于同一个数据类型。不能把不同类型的数据放在同一个数组中。
由于计算机键盘只能输入有限的单个字符而无法表示上下标,C语言规定用方括号中的数字来表示下标。

6.1.1 怎样定义一维数组

定义一维数组的一般形式为
类型说明符 数组名[常量表达式]
如:int a[10]
它表示定义了一个整形数组,数组名为a,此数组包含10个整形元素。相当于定义了10个简单的整型变量。
在这里插入图片描述
说明:
(1)数组名的命名规则和变量名相同,遵循标识符命名规则。
(2)在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。请特别注意,数组元素的下标从0开始,如用“int a[10];”定义数组,则最大下标值为9,不存在数组元素a[10]。
(3) 常量表达式中可以包括常量和符号常量,不能包含变量。如“int a[3+5];”合法,但“int a[n];”就是不合法的。也就是说,C语言不允许对数组的大小做动态定义,即数组的大小不依赖于程序运行过程中变量的值。

6.1.2 怎样引用一维数组元素

引用数组元素的表示形式为
数组名[下标]
说明:
(1)只能引用数组元素而不能一次整体调用整个数组全部元素的值。
(2)数组元素与一个简单变量的地位和作用相似。
(3)“下标”可以是整型常量或整型表达式。
注意: 定义数组时用到的“数组名[常量表达式]” 和引用数组元素时用的“数组名[下标]”形式相同,但含义不同。如:

int a[10];
//前面有int,这是定义数组,指定数组包含10个元素
t=a[6];
//这里的a[6]表示引用a数组中序号为6的元素

举个例子【例6.1】对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。
编写代码

#include <iostream>
//对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。
int main() {
    int i,a[10],t;
    for(i=0;i<10;i++){                  //对数组元素a[0]~a[9]赋值
        a[i]=i;
    }
    for(i=9,t=0;i>=0;i--,t++){          //输出a[9]~a[0]共10个数组元素
        printf("a[%d]=%d\t",t,a[i]);
    }
    return 0;
}

运行结果
在这里插入图片描述
**程序分析:**第1个for循环使a[0]~a[9]的值为0~9,见下图。第2个for循环按a[9]~a[0]的顺序输出各元素的值。
在这里插入图片描述

6.1.3 一维数组的初始化

为了使程序简洁,常在定义数组的同时给各数组元素赋值,这称为数组的初始化。
(1) 在定义数组时对全部数组元素赋予初值。如:

int a[10]={0,1,2,3,4,5,6,7,8,9};

将数组中各元素的初值顺序放在一对花括号内,数据间用逗号分隔。花括号内的数据就称为“初始化列表”。
(2) 可以只给数组中的一部分元素赋值。如:

int a[10]={0,1,2,3,4};

定义a数组有10个元素,但花括号内只提供5个初值,这表示只给前面5个元素赋初值,系统自动给后5个元素赋初值为0。
(3) 给数组中全部元素赋初值为0。可以写成:

int a[10]={0,0,0,0,0,0,0,0,0,0};
//或
int a[10]={0};		//未赋值的部分元素自动设定0

(4) 在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。如:

int a[5]={1,2,3,4,5};
//可以写成
int a[ ]={1,2,3,4,5};

但是,如果数组长度与提供初值的个数不相同,则方括号中的数组长度不能省略。
说明: 如果在定义数值型数组时,指定了数组的长度并对之初始化,凡未被“初始化列表”指定初始化的数组元素,系统会自动把它们初始化为0(如果是字符型数组,则初始化为’\0’,如果是指针型数组,则初始化为NULL,即空指针)。

6.1.4 一维数组应用举例

【例6.2】用数组来处理求Fibonacci数列问题。
编写代码

#include <stdio.h>
//用数组来处理求Fibonacci数列问题。即,兔子繁殖问题
int main() {
    int i;
    int f[20]={1,1};			//对最前面两个元素f[0]和f[1]赋初值1
    for(i=2;i<20;i++){
        f[i]=f[i-1]+f[i-2];		//先后求出f[2]~f[19]的值
    }
    for(i=0;i<20;i++){
        printf("%d\t",f[i]);	//输出一个数
        if((i+1)%5==0) printf("\n");	//控制每输出5个数后换行
    }
    return 0;
}

运行结果
在这里插入图片描述
【例6.3】有10个地区的面积,要求对它们按由小到大的顺序排列。
算法用:起泡排序法
在这里插入图片描述
编写代码

#include <stdio.h>
//有10个地区的面积,要求对它们按由小到大的顺序排列。
int main() {
    int s[10];
    int i,j,t;
    printf("please enter 10 numbers:\n");
    for (int i = 0; i < 10; i++) {
        scanf("%d",&s[i]);
    }
    for(j=0;j<(10-1);j++){                          //进行9次循环,实现9趟比较
        for (int i = 0; i < ((10-1)-j); i++) {      //在每一趟比较中,实现9-j次比较
            if(s[i]>s[i+1]){                        //相邻两个数进行比较
                t=s[i];
                s[i]=s[i+1];
                s[i+1]=t;
            }
        }
    }
    printf("the sorted numbers:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d\t",s[i]);
    }
    return 0;
}

运行结果
在这里插入图片描述

6.2 怎样定义和引用二维数组

二维数组常称为矩阵 (matrix)。把二维数组写成行(row)和列(column)的排列形式,可以有助于形象化地理解二维数组的逻辑结构。

6.2.1 怎样定义二维数组

二维数组的一般形式
类型说明符 数组名 [常量表达式] [常量表达式] ;
例如:

float a[3][4], b[5][10];					//定义a为3×4(3行4列)的数组,b为5×10(5行10列)的数组

二维数组可被看作一种特殊的一维数组: 它的元素又是一个一维数组。 例如,

float a[3][4];

可以把a看作一个一维数组,它有3个元素:a[0], a[1], a[2],每个元素又是一个包含4个元素的一维数组:

a[0] —— a[0][0] a[0][1] a[0][2] a[0][3]
a[1] —— a[1][0] a[1][1] a[1][2] a[1][3] 
a[2] —— a[2][0] a[2][1] a[2][2] a[2][3]

C语言中,二维数组中元素排列的顺序是按行存放的,即在内存中先顺序存放第1行的元素,接着在存放第2行的元素···
注意: 用矩阵形式表示二维数组,是逻辑上的概念,而在内存中,各元素是连续存放的,不是二维的,是线性的。
C语言还允许使用多维数组。多维数组元素在内存中的排列顺序为: 第1维的下标变化最慢,最右边的下标变化最快。

6.2.2 怎样引用二维数组的元素

二维数组元素的表示形式为
数组名 [下标] [ 下标]
说明:(1)“下标”可以是整型常量或整型表达式。
(2)数组元素可以出现在表达式中,也可以被赋值,如:b[1][2]=a[2][3]/2;
注意:在引用数组元素时,下标值应在已定义的数组大小的范围内。

6.2.3 二维数组的初始化

可以用“初始化列表”对二维数组初始化。
(1)分行给二维数组赋初值。(最清楚直观)

int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

(2)可以将所有数据写在一个花括号内,按数组元素在内存中的排列顺序对各元素赋初值。

int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

(3)可以对部分元素赋初值。

int a[3][4]={{1},{5},{9}};			//(1)
int a[3][4]={{1},{0,6},{0,0,11}};	//(2)
int a[3][4]={{1},{5,6}};			//(3)			
int a[3][4]={{1},{},{9}};			//(4)

在这里插入图片描述
(4)如果对全部元素都赋初值(即提供全部初始数据),则定义数组时对第1维的长度可以不指定,但第2维的长度不能省。

int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
//等价于
int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};

在定义时也可以只对部分元素赋初值而省略第1维的长度,但应分行赋初值。

int a[][4]={{0,0,3},{},{0,10}};

6.2.4 二维数组程序举例

【例6.4】将一个二维数组行和列的元素互换,存到另一个二维数组中。例如:
在这里插入图片描述
编写程序

#include <stdio.h>
//将一个二维数组行和列的元素互换,存到另一个二维数组中。

int main(){
    int a[2][3]={{1,2,3},{4,5,6}};
    int b[3][2],i,j;
    printf("array a:\n");
    for (int i = 0; i < 2; i++) {           //处理a数组中的一行中各元素
        for (int j = 0; j < 3; j++) {       //处理a数组中某一列中各元素
            printf("%d\t",a[i][j]); //输出a数组的一个元素
            b[j][i]=a[i][j];                //将a数组元素的值赋给b数组相应元素
        }
        printf("\n");
    }
    printf("array b:\n");           //输出b数组各元素
    for(j=0;j<3;j++){                       //处理b数组中一行中各元素
        for(i=0;i<2;i++){                   //处理b数组中一列中各元素
            printf("%d\t",b[j][i]); //输出b数组的一个元素
        }
        printf("\n");
    }
    return 0;
}

运行结果
在这里插入图片描述

6.3 字符数组

6.3.1 怎样定义字符数组

用来存放字符数据的数组是字符数组。在字符数组中的一个元素内存放一个字符。
定义字符数据的数组和定义数值型数组的方法类似。例如:

char c[10];
c[0]='I'; c[1]=' ';c[2]='a';c[3]='m';c[4]=' '; c[5]='h'; c[6]='a'; c[7]='p'; c[8]='p'; c[9]='y'; 

由于字符型数据是以整数形式(ASCII代码)存放的,因此也可以用整型数组来存放字符数据。如:

int c[10];
c[0]='a'; 	//合法,但浪费存储空间

6.3.2 字符数组的初始化

对字符数组初始化,最容易理解的方式是用“初始化列表”,把各个字符依次赋给数组中各元素。

char c[10]={′I′,′ ′ ,′a′,′m′,′ ′,′h′,′a′,′p′,′p′,′y′};		//把10个字符依次赋给c[0]~c[9]这10个元素

如果在定义字符数组时不进行初始化,则数组中各元素的值是不可预料的。
如果花括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误。
如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即′\0′)。

char c[20]={′c′,′ ′,′p′,′r′,′o′,′g′,′r′,′a′,′m′};

如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度

char c[]={′I′,′ ′,′a′,′m′,′ ′,′h′,′a′,′p′,′p′,′y′};		//数组c的长度自动定为10

也可以定义和初始化一个二维字符数组。

char diamond[5][5]={{′ ′,′ ′,′*′},{′ ′,′*′,′ ′,′*′},{′*′,′ ′,′ ′,′ ′,′*′},{′ ′,′*′,′ ′,′*′},{′ ′,′ ′,′*′}};

6.3.3 怎样引用字符数组中的元素

【例 6.5】输出一个已知的字符串。
编写程序

#include <iostream>
//输出一个已知的字符串。
int main() {
    char c[15]={'I',' ','a','m',' ','a',' ','s','t','u','d','e','n','t','.'};
    int i;
    printf("array c:\n");
    for(i=0;i<15;i++){
        printf("%c",c[i]);
    }
    printf("\n");
    return 0;
}

运行结果
在这里插入图片描述
【例 6.6】输出一个菱形图。
编写程序

#include <iostream>
//输出一个菱形图。
int main() {
    char diamond[][5]={{' ',' ','*'},{' ','*',' ','*'},{'*',' ',' ',' ','*'},
                       {' ','*',' ','*'},{' ',' ','*'}};
    int i,j;
    for(i=0;i<5;i++){
        for(j=0;j<5;j++){
            printf("%c",diamond[i][j]);
        }
        printf("\n");
    }
    return 0;
}

运行结果
在这里插入图片描述

6.3.4 字符串和字符串结束标志

在C语言中,是将字符串作为字符数组来处理的。
在实际工作中,人们关心的往往是字符串的有效长度而不是字符数组的长度。
为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符′\0′作为结束标志。
″C program″ 字符串是存放在一维数组中的,占10个字节,字符占9个字节,最后一个字节′\0′是由系统自动加上的。
注意:
(1)C系统在用字符数组存储字符串常量时会自动加一个′\0′作为结束符。
(2)在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度。
(3)如果在一个字符数组中先后存放多个不同长度的字符串,则应使数组长度大于最长的字符串的长度。

6.3.5 字符数组的输入输出

字符数组的输入输出可以有两种方法。
(1)逐个字符输入输出。用格式符“%c”输入或输出一个字符。
(2)将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串(string)的输入输出。
说明:
(1) 输出的字符中不包括结束符′\0′。
(2) 用“%s”格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名。
(3) 如果数组长度大于字符串的实际长度,也只输出到遇′\0′结束。
(4) 如果一个字符数组中包含一个以上′\0′,则遇第一个′\0′时输出就结束。
(5)可以用scanf函数输入一个字符串。

6.3.6 使用字符串处理函数

1.puts函数——输出字符串的函数
其一般形式为:puts(字符数组)
作用:将一个字符串(以′\0′结束的字符序列)输出到终端。
用puts函数输出的字符串中可以包含转义字符。
在用puts输出时将字符串结束标志′\0′转换成′\n′,即输出完字符串后换行。

2. gets函数——输入字符串的函数
其一般形式为:gets(字符数组)
作用:从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址。
注意: 用puts和gets函数只能输出或输入一个字符串。

3. strcat函数——字符串连接函数
其一般形式为:strcat(字符数组1,字符数组2)
作用:把两个字符数组中的字符串连接起来,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值——字符数组1的地址。
字符数组1必须足够大,以便容纳连接后的新字符串。
连接前两个字符串的后面都有′\0′,连接时将字符串1后面的′\0′取消,只在新串最后保留′\0′。

4. strcpy和strncpy函数——字符串复制函数
其一般形式为:strcpy(字符数组1,字符串2)
作用:将字符串2复制到字符数组1中去。
说明:
1.字符数组1必须定义得足够大,以便容纳被复制的字符串2。字符数组1的长度不应小于字符串2的长度。
2. “字符数组1”必须写成数组名形式,“字符串2”可以是字符数组名,也可以是一个字符串常量。
3.若在复制前未对字符数组1初始化或赋值,则其各字节中的内容无法预知,复制时将字符串2和其后的′\0′一起复制到字符数组1中,取代字符数组1中前面的字符,未被取代的字符保持原有内容。
4.不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组。字符数组名是一个地址常量,它不能改变值,正如数值型数组名不能被赋值一样。
5. 可以用strncpy函数将字符串2中前面n个字符复制到字符数组1中去。
将str2中最前面2个字符复制到str1中,取代str1中原有的最前面2个字符。但复制的字符个数n不应多于str1中原有的字符(不包括′\0′)。

5. strcmp函数——字符串比较函数
其一般形式为:strcmp(字符串1,字符串2)
作用:比较字符串1和字符串2。
字符串比较的规则是: 将两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到′\0′为止。
(1) 如全部字符相同,则认为两个字符串相等;
(2) 若出现不相同的字符,则以第1对不相同的字符的比较结果为准。
比较的结果由函数值带回。
(1) 如果字符串1与字符串2相同,则函数值为0。
(2) 如果字符串1>字符串2,则函数值为一个正整数。
(3) 如果字符串1<字符串2,则函数值为一个负整数。

6. strlen函数——测字符串长度的函数
其一般形式为:strlen(字符数组)
作用:测试字符串长度的函数。函数的值为字符串中的实际长度(不包括′\0′在内)。

7. strlwr函数——转换为小写的函数
作用:将字符串中大写字母换成小写字母。
其一般形式为:strlwr(字符串)

8. strupr函数——转换为大写的函数
其一般形式为:strupr(字符串)
作用:将字符串中小写字母换成大写字母。
注意:
以上介绍了常用的8种字符串处理函数,它们属于库函数。库函数并非C语言本身的组成部分,而是C语言编译系统为方便用户使用而提供的公共函数。不同的编译系统提供的函数数量和数名、函数功能都不尽相同,使用时要小心,必要时查一下库函数手册。
在使用字符串处理函数时,应当在程序文件的开头用#include <string.h>把string.h文件包含到本文件中。

这篇关于C程序设计语言-第六章 利用数组处理批量数据的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!