C语言学习4——第六章:利用数组处理批量数据

总述

时隔3个多月,终于更新了这篇博客,这次终于来到了第六章——数组。这三个月因为放假本身没怎么学习,刚好这学期学校也有c语言课程,我就边自学后面,边把老师讲的当做复习,而且这两天花时间重新复习了前面五章,现在开始正式学习第六章。

注:本博客所有知识点均出自C程序设计(第五版)

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

C语言规定用方括号中的数字来表示下标。

6.1.1怎样定义一维数组

定义一维数组的一般形式为
类型说明符 数组名[常量表达式]

说明:
(1)数组名的命名规则和变量名相同,遵循标识符命名规则。
(2)在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。例如,a[10],表示a数组有10个元素。但有一点要注意,这个下标是从0开始。按上面的定义,不存在数组元素a[10]。
(3)常量表达式中可以包括常量和符号常量,如“int a[3+5];”是合法的。不能包括变量,如“int a[n];”是不合法的。

6.1.2怎样引用一维数组元素

在定义数组并对其中各元素赋值后,就可以引用数组中的元素。应注意:只能引用数组元素而不能一次整体调用整个数组全部元素的值。
引用数组元素的表示形式为:数组名[下标]
注:定义数组时用到的“数组名[常量表达式]”和引用数组元素时用的“数组名[下标]”形式相同,但含义不同。
【例6.1】对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。

#include                  //编译预处理指令
int main()                         //定义主函数
{                                  //函数开始
	int i, a[10];                  //定义整形i和包含十个元素的数组a
	for (i = 0; i <= 9; i++)       //for循环,i赋值0,当i小于等于9时,第i个数组元素等于i的值,然后i自加1
		a[i] = i;
	for (i = 9; i >= 0; i--)       //for循环,i赋值9,当i大于等于0时。输出第i个数组元素,然后i自减1
		printf("%d", a[i]);
	printf("\n");                  //输出换行符
	return 0;                      //函数值返回0
}                                  //函数结束

注:数组元素的下标从0开始,如果用int a[10]定义数组,则最大下标为9,不存在数组元素a[10]。

6.1.3一维数组的初始化

在定义数组的同时给各数组元素赋值,称为数组的初始化
(1)将数组中各元素的初值顺序放在一对花括号内,数据间用逗号隔开。
如:int a[10]={0,1,2,3,4,5,6,7,8,9};
(2)也可以只给数组中的一部分元素赋值,剩下未赋值的元素系统默认赋值0。
如:int a[10]={0,1,2,3,4};
(3)在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。
如:int a[5]={1,2,3,4,5};可以写成int a[ ]={1,2,3,4,5};

6.1.4一维数组程序举例

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

#include                             //编译预处理指令
int main()                                    //定义主函数
{                                             //函数开始
	int i;                                    //定义整形i
	int f[20] = { 1,1 };                      //定义数组f含20个元素,前两个元素赋值为1
	for (i = 2; i < 20; i++)                  //for循环,i赋值为2,当i小于20时,f[i]为前两个元素相加,然后i自加1
		f[i] = f[i - 2] + f[i - 1];
	for (i = 0; i < 20; i++)                  //这个for循环是整格式的,之前写过,不在赘述
	{
		if (i % 5 == 0)printf("\n");
		printf("%12d", f[i]);
	}
	printf("\n");                             //输出换行符
	return 0;                                 //函数值返回0
}                                             //函数结束

【例6.3】有10个地区的面积,要求对它们按由小到大的顺序排列。

#include                                               //编译预处理指令
int main()                                                      //定义主函数
{                                                               //函数开始
	int a[10];                                                  //定义整型数组包含十个元素
	int i, j, t;                                                //定义整形i,j,t
	printf("input 10 numbers:\n");                              //输出input 10 numbers:\n
	for (i = 0; i < 10; i++)                                    //for循环,使数组十个元素赋上输入的十个值
		scanf_s("%d", &a[i]);
	printf("\n");
	for (j = 0 ; j < 9; j++)                                    //for循环,执行起泡法比较,使元素按从小到大比较
		for(i=0;i<9-j;i++)
			if (a[i] > a[i + 1])
			{
				t = a[i]; a[i] = a[i + 1]; a[i + 1] = t;
			}
	printf("the sorted number:\n");                             //输出the sorted number:\n
	for (i = 0; i < 10; i++)                                    //for循环,输出十个数组
		printf("%d ", a[i]);
	printf("\n");
	return 0;                                                   //函数值返回0
}                                                               //函数结束

运行结果如下:

input 10 numbers:
34 67 90 43 124 87 65 99 132 26

the sorted number:
26 34 43 65 67 87 90 99 124 132

可以看到,在写出例6.3时,使用了一种比较的方法,起泡法,其基本思路是每次将相邻两个数比较,将小的调到前面。除此之外,排序的算法有多种,常用的还有选择法,希尔法,后续遇到了再介绍。

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

二维数组常称为矩阵

6.2.1怎样定义二维数组

二维数组定义的一般形式为:类型说明符 数组名[常量表达式][常量表达式]

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

二维数组元素的表示形式为:数组名[下标][下标]
注:要区分定义数组时用的a[3][4]和引用元素时的a[3][4]的区别,前者的3和4来定义数组的维数和各维的大小,后者的3和4是数组元素的下标值,代表行序号为3,列序号为4的元素。

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}}
其他没赋值的元素自动为0。

6.2.4二维数组程序举例

【例6.4】将一个二维数组行和列的元素互换,存到另一个二维数组中。

#include                             //编译预处理指令
int main()                                    //定义主函数
{                                             //函数开始
	int a[2][3] = { {1,2,3},{4,5,6} };        //定义二维数组a有2行3列并赋值
	int b[3][2], i, j;                        //定义二维数组b有3行2列,定义整形i,j
	printf("array a:\n");                    
	for (i = 0; i <= 1; i++)                  //for循环,处理a数组中的一行各元素
	{
		for (j = 0; j <= 2; j++)              //for循环,处理a数组中每一行各列的元素
		{
			printf("%5d", a[i][j]);           //输出a数组的一个元素
			b[j][i] = a[i][j];                //将a数组元素的值赋给b数组相应元素
		}
		printf("\n");
	}
	printf("array b:\n");
	for (i = 0; i <= 2; i++)                  //for循环,处理b数组中一行中各元素
	{
		for (j = 0; j <= 1; j++)              //for循环,处理b数组中每一行各列的元素
			printf("%5d", b[i][j]);           //输出b数组的一个元素
		printf("\n");
	}
	return 0;                                 //函数值返回0
}                                             //函数结束

【例6.5】有一个3*4的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。

#include                                             //编译预处理指令
int main()                                                    //定义主函数
{                                                             //函数开始
	int i, j, row = 0, colum = 0, max;                        
	int a[3][4] = { {1,2,3,4},{9,8,7,6},{-10,10,-5,2} };
	max = a[0][0];
	for(i=0;i<=2;i++)                                         //for循环,a数组行
		for(j=0;j<=3;j++)                                     //for循环,a数组列
			if (a[i][j] > max)                                
			{
				max = a[i][j];                               //如果某元素大于max,就取代max的原值
				row = i;                                    
				colum = j;
			}
	printf("max=%d\nrow=%d\ncolum=%d\n", max, row, colum);
	return 0;
}

6.3字符数组

c语言中没有字符串类型,也没有字符串变量,字符串是存放在字符型数组中的。

6.3.1怎样定义字符数组

char c[10];
c[0]=‘i’

6.3.2字符数组的初始化

char c[10]={‘i’,‘’,‘a’,‘m’,‘’,‘h’,‘a’,‘p’,‘p’,‘y’};
也可以定义和初始化二维字符数组。
(这两小节类比一维和二维数组,就不多赘述)

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

可以引用字符数组中的一个元素,得到一个字符。
【例6.6】输出一个已知的字符串

#include                                                                          //编译预处理指令
int main()                                                                                 //定义主函数
{                                                                                          //函数开始
	char c[15] = { 'I',' ','a','m',' ','a',' ','s','t','u','d','e','n','t','.' };          //字符数组初始化
	int i;                                                                                 //定义整型i
	for (i = 0; i < 15; i++)                                                               //for循环挨个输出数组
		printf("%c", c[i]);
	printf("\n");                                                                          //输出换行符
	return 0;                                                                              //函数值返回0
}                                                                                          //函数结束

这个例子是用循环结构逐个输出字符数组。
【例6.7】同样也是循环结构输出,只不过用的二维数组,属于加深印象,就不在展示。

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

为了测定字符串的实际长度,c语言规定了一个“字符串结束标志”,以字符‘\0’作为结束标志。如果字符数组中存有若干字符,前面九个字符都不是空字符(‘\0’),而第十个字符是‘\0’,则认为数组中有一个字符串,其有效字符为9个。
注:c系统在用字符数组存储字符串常量时会自动加一个‘\0’作为结束符。

6.3.5字符数组的输入和输出

两种方式:
(1)逐个字符输入输出。用格式符“%c”输入或输出一个字符。
(2)将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串(string)的输入输出。
例:

char c[ ]={“china”};                  
printf(“%s\n”,c);

注:
(1)输出的字符中不包括结束符’\0’。
(2)用“%s”格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素。
不能写成这种形式:printf(“%s”,c[0]);
(3)如果数组长度大于字符串的实际长度,也只输出到遇到‘\0’时输出就结束。
(4)如果一个字符数组中包括一个以上‘\0’,则遇到第一个‘\0’时输出就结束。
(5)可以用scanf函数输入一个字符串。&1:scanf函数中的输入项如果是字符数组名,不要再加地址符&,因为在c语言中数组名代表该数组第一个元素的地址。

6.3.6使用字符串处理函数

1.puts函数——输出字符串函数
一般形式为 puts(字符数组)
2.gets函数——输入字符串的函数
一般形式为 gets(字符数组)
注:用puts和gets函数只能输出或输入一个字符串,不能写成puts(str1,str2)或gets(str1,str2)
3.strcat函数——字符串连接函数
一般形式为 stract(字符数组1,字符数组2)
说明:
(1)字符数组1必须足够大,以便容纳连接后的新字符串。
(2)连接前2个字符串的后面都有‘\0’,连接时将字符串1后面的‘\0’取消,只在新串最后保留‘\0’。

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

5.strcmp函数——字符串比较函数
一般形式为 strcmp(字符串1,字符串2)
说明:
(1)如全部字符相同,则认为两个字符串相等。
(2)若出现不相同的字符,则以第一对不相同的字符的比较结果为准
结果说明:
(1)如果字符串1与字符串2相同,则函数值为0。
(2)如果字符串1>字符串2,则函数值为一个正整数。
(3)如果字符串1<字符串2,则函数值为一个负整数。

一般比较形式为:

if(strcmp(str1,str2)>0)
     printf(“yes”);

6.strlen函数——测字符串长度的函数
一般形式为strlen(字符数组)
7.strlwr函数——转换为小写的函数
一般形式为strlwr(字符串)
8.strupr函数——转换为大写的函数
一般形式为strupr(字符串)

注:在使用字符串处理函数时,应当在程序文件的开头用

#include

6.3.7字符数组应用举例

【例6.8】输入一行字符,统计其中有多少个单词,单词之间用空格隔开。

#include                                             //编译预处理指令
#include                                            //调用字符串函数库
int main()                                                    //定义主函数
{                                                             //函数开始
	char string[81];                                          //定义字符数组
	int i, num = 0, word = 0;                                 //定义整型并赋值
	char c;                                                   //定义字符
	gets_s(string);                                           //输入字符赋给string数组
	for (i = 0; (c = string[i]) != '\0'; i++)                 //for循环,直到检测到‘\0’结束
		if (c == ' ')                                         //如果c等于空格,word等于0
			word = 0;
		else if (word == 0)                                   //当word等于0时,word等于1.num加1
		{
			word = 1;
			num++;
		}
	printf("there are %d words in this line.\n", num);        //输出结果
	return 0;                                                 //函数值返回0
}                                                             //函数结束

结果为:

I am a student.
there are 4 words in this line.

注:因为visual studio 2019认为gets()是不安全的,所以要用gets_s()。
【例6.9】有三个字符串,要求找出其中“最大”者。

#include                                            //编译预处理指令
#include                                           //调用字符串函数库
int main()                                                   //定义主函数
{                                                            //函数开始
	char str[3][20];                                         //定义二维字符数组
	char string[20];                                         //定义一维字符数组
	int i;                                                   //定义整型i
	for (i = 0; i < 3; i++)                                  //for循环,输入三个字符串赋给str数组
		gets_s(str[i]);
	if (strcmp(str[0], str[1]) > 0)                          //比较,将大的字符串赋给string,下面也是重复此过程
		strcpy_s(string, str[0]);
	else
		strcpy_s(string, str[1]);
	if (strcmp(str[2], string) > 0)
		strcpy_s(string, str[2]);
	printf("\nthe largest string is:\n%s\n", string);         //输出结果
	return 0;                                                 //函数值返回0
}                                                             //函数结束

结果为:

holland
china
america

the largest string is:
holland

后记

终于把第六章啃完了,起笔时是三月,现在已经到了四月,一个月终于学完了数组,离指针又近了一步,加油啊。因为后面几章内容较多,篇幅较长,遍新开一篇专门写习题,这篇只总结知识点,并且只是大致总结,细节方面还是要看书学习,这只是作为一个辅佐。

聿辞
2021年4月3日

你可能感兴趣的:(c语言学习记录,c语言)