第六章:数组
文章目录
第六章:数组
在C语言中,定义了一个数组后,就确定了它所容纳的具有相同数据类型元素的个数
6.1一维数组
数组是由若干个相同类型的变量在内存中有序存储的集合。
int a[10]
定义:
数据类型 数组名[常量表达式,即数组元素的个数]
数据类型:每个数组元素的数据类型
数组名:满足标识符的命名规则,不能与其他变量重名
常量表达式:表示元素的个数,即数组的长度。不能包含变量
访问数组元素时,下标的取值范围为 0 ≤ index < length,过大或过小都会越界,导致数组溢出,发生不可预测的情况。
- 一维数组在内存的存放、
- 存储单元的大小由数组的类型和数组的长度决定
- 数组名表示整个数组所占用的内存空间的首地址。同一数组中的所有元素, 按其下标的顺序占用若干连续的存储单元
一维数组的初始化
-
定义:初始化指在定义时指定初始值,编译时将初始值赋给数组元素
-
一般格式:
数据类型 数组名[常量表达式]={初值表};
-
几种方式
-
全部数组元素赋初值
int a[6]={1,2,3,4,5,6};
-
在对全部数组元素赋值时,由于数据的个数已经确定,因此可以不指定数组长度
int a[]={1,2,3,4,5};
-
部分数组元素赋初值
int a[6]={1,2,3,4}; # 其余数组元素值为0
-
数组定义后,若全部数组元素在使用前未赋值,则该数组元素的值不确定。若数组元素部分初始化,则未初始化部分元素值为0
int a[10],b[10]={1,2,3,4};
-
如果想使一个数组的全部元素值为0,可以写为:
int a[10]={0};
-
-
更高效的初始化方法
memset(a, 0, sizeof(a)); //将数组中的所有元素全部初始化为0
eg:
给数组赋值-1
int A[2];
memset(A, -1, sizeof(A);
用sizeof(a)来获得数组a 所占的内存字节数
需要包含头文件:#include <string.h>
一维数组的访问
- 数组中的每个元素只能逐个被引用,而不能一次引用全部数组元素
- 在c语言中引用数组元素时,其数组下标的数据类型允许是:整型常量或整型表达式
- 数组的引用方式:数组名[下标]
- 下标的取值范围:0<=下标<=数组长度-1
int a[5]={1,2,3};
for (i=0;i<5;i++)
printf("%d ",a[i]);
一维数组应用举例
- 查找
#include <stdio.h>
#include <math.h>
int main()
{
int a[] = {21, 13, 52, 0, -25, 11, 54, 41, 87, 9, 3, 98, 43, 65, 11};
int i, x, flag = 0, k;
scanf("%d", &x);
for (i = 0; i < 15; i++)
if (a[i] == x)
{
k = i;
flag = 1;
break;
}
if (flag==1)
printf("%d的下标是%d", x, k);
else
printf("not exist!");
system("pause");
return 0;
}
-
排序
- 交换排序:通过不断交换数组中数组元素的位置,直到数组排序完成为止。冒泡排序就是交换排序的典型示例。冒泡排序的基本思想就是:扫描整个数组,依次比较相邻的两个数,将小数放在前面,大数放在后面。
- 冒泡排序总共排序(n-1)轮,总共比较[(n-1)×n]/2次,第i轮比较(n-i)次。
- 选择排序:首先挑选最小的数,放在第一个数的位置,再从其余位置选最小的数,放在第二个位置,以此类推。
-
拓展:
-
指针数组
char*a[10];
-
结构体数组
struct stu boy[10];
-
6.2-二维数组(即矩阵)
定义:
数据类型 数组名[常量表达式1,即行的个数][常量表达式2,即列的个数];
eg:int b[3][5];
b组数据有3行5列,共15个数组元素
-
二维数组有两个下标。常量表达式1代表第一维的长度,常量表达式2是第2维的长度
-
定义一维数组后,则需要为其所有的元素分配内存单元,一维数组占用的内存字节数=数组 长度×每一元素占用的字节数,而且所占用的内存单元是连续的,并按照元素顺序依次排列
eg: int a[5]; 所占字节数为:4×5=20个字节,用sizeof(a)即可计算内存数
-
二维数组在概念上是二维的,但在内存中是连续存放的。换句话说,二维数组的各个元素是相互挨着的,彼此之间没有缝隙。在线性内存中存放二维数组有两种方式:
- 一种是按行排列, 即放完一行之后再放入第二行;
- 另一种是按列排列, 即放完一列之后再放入第二列。
-
在C语言中,二维数组是按行排列的。
二维数组初始化
-
一般格式:
数据类型 数组名[常量表达式1][常量表达式2]={初值表};
-
其他方式:
- 按行初始化:每一行的数据用括号括起来
全部元素赋值: int x[2][4]={{1,2,3,4},{5,6,7,8}}; 部分元素赋值: int y[3][5]={{1},{6,7},{}}; # 剩余用0补齐
- 按顺序初始化:所有数据在一个花括号内,按数组元素排列的顺序对各元素赋初值,但容易遗漏。
全部元素赋值: int x[2][4]={1,2,3,4,5,6,7,8}; 部分元素赋值: int y[3][5]={1,6,7}; # 剩余用0补齐
-
省略指定第一维的长度:
- 给二维数组的全部元素赋值时,可以不指定第一维的长度,但第二维的长度不能省略
int x[][4]={{1,2,3,4},{5,6,7,8}}; int x[][4]={1,2,3,4,5,6,7,8};
- 按行初始化时,也可以只对部分元素赋初值而省略第一维的长度
int a[][3]={{1},{},{9,11}};
二维数组的访问
-
数组元素的引用方式:数组名[下标1] [下标2]
-
下标取值范围:
0<=下标1<常量表达式1 0<=下标2<常量表达式2 eg: int m[2][3] m[0][0] m[0][1] m[0][2] m[1][0] m[1][1] m[1][2]
注意:定义的m[2] [3]数组中无m[2] [3]元素
-
三维数组:是由多个相同的二维数组构成的
int a[4][2][10];
6.3-字符数组
定义
-
用来存放字符数据的数组是字符数组。
-
C语言用字符数组存放字符串,字符数组中的各元素依次存放字符串的各字符
-
一维字符数组:存放一个字符串(每个数组元素存放一个字符)
-
二维字符数组:存放多个一维数组(字符串);二维数组的行数是字符串的个数
-
定义格式:
char 数组名[常量表达式]; char 数组名[常量表达式][常量表达式]; //声明的时候,方括号中一定是常量或常量表达式,使用的时候可以是变量。其中常量表达式:整数、字符、符号常量 。 也可以用整型数组存放字符型数据,但是浪费存储空间
字符数组的存储
字符数组的初始化
- 用单个字符对字符数组初始化
- 如果花括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误
- 如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度
- 如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即’\0’)
- 用字符串常量对字符数组初始化
(1)char str[6]={"CHINA"};
(2)char str[6]="CHINA"; //省略{}
(3)char str[ ]="CHINA"; // 省略长度值
(4)char c[12]={"HOW ARE YOU"};与char c[ ]={'H','O','W',' ','A','R','E',' ','Y','O','U','\0'}; 等价
(5)char *p=c; //用一个指针指向该数组,*(p+i) <=> a[i]
- 字符数组逐个字符初始化比整个字符串初始化要少一个“\0”;即__用字符串方式赋值比用逐个字符赋值要多占1个字节,用于存放字符串结束标志’\0’__
字符数组的输入输出
- 逐个字符输入:用%c按字符序列输入
- 整个字符串输入:用%s字符串 //不同于数值型数组
注意:scanf以空格、回车作为结束的
char str[]="i am abc" scanf("%s",str) -->i # 在第一个空格处结束
- 说明
- 数组名前不加&符号
- 输入字符串的长度要小于数组长度
- 只能输入不包括空格、\t和\n的字符串
- 若要输入空格,用gets函数
- 自动加’\0’
字符串处理函数:
包含在头文件 <string.h >中
-
字符串输出函数puts
-
格式: puts(字符数组)
-
功能:向显示器输出一个字符串(输出完,换行)
-
说明:字符数组必须以’\0’结束。可以包含转义字符。输出时’\0’转换成’\n’,即输出字符后换行。
#include<stdio.h> #include<string.h> int main() { char a[]={"china\ngood"}; char b[]={"zhong\0guo"}; puts(a); puts(b); puts("CHINA"); } 运行结果: china good zhong //将'\0'转换成'\n' CHINA
-
-
字符串输入函数gets
- 格式:gets(字符数组)
- 功能:从键盘输入一个以回车结束的字符串放入字符数组中,并自动加’\0’
- 说明:输入串长度要小于字符数组长度
#include<stdio.h> #include<string.h> int main() { char a1[10],a2[10]; gets(a1); scanf("%s",a2); printf("a1=%s\n",a1); printf("a2=%s\n",a2); } 输入: china china //在scanf中遇到空格字符串便结束了,而gets中,却将空格作为字符存放入字符数组中 china china 输出: a1=china china a2=china 输入: abcdeabcdeabcde abcdeabcdeabcde 输出: a1=abcdeabcde a2=abcdeabcdeabcde
-
字符串连接函数stract
- 格式:strcat(字符数组1,字符数组2)
- 功能:把字符数组2连到字符数组1后面
- 返值:返回字符数组1的首地址
- 说明:
- 字符数组1必须足够大
- 连接前,两串均以’\0’结束;连接后,串1的’\0’取消,新串最后加’\0’。
#include<stdio.h> #include<string.h> int main() { char str1[10]={"China is"}; char str2[]={"good"}; printf("%s\n",strcat(str1,str2)); } 输出: China is good
-
字符串拷贝函数strcpy
- 格式:strcpy(字符数组1,字符串2)
- 功能:把字符数组2,拷贝到字符数组1中去
- 返值:返回字符数组1的首地址
- 说明:
- 字符数组1必须足够大,至少大于字符串2
- 字符数组1必须是数组名形式(str1),字符串2可以是字符数组名或字符串常量
- 拷贝时’\0’一同拷贝
#include<stdio.h> #include<string.h> int main() { char str1[20],str2[]="Hello!"; strcpy(str1,str2); printf("%s\n",str1); printf("%d\n",strlen(str1)); printf("%d\n",sizeof(str1)); } Hello! 6 20 //总长度
-
字符串比较函数strcmp
- 格式: strcmp(字符串1,字符串2)
- 功能:比较两个字符串
- 比较规则:对两串从左向右逐个字符比较(ASCII码),直到遇到不同字符或’\0’为止
- 返回值:返回int型整数。其值是ASCII码的差值(根据编译器的不同,也有可能返回1,0,-1)
- 说明:字符比较必须用strcmp
若字符串1大于字符串2,返回正整数; 若字符串1等于字符串2,返回零; 若字符串1小于字符串2,返回负整数; #include<stdio.h> #include<string.h> int main() { char a[]={"china"},b[]={"henan"}; int x.y.z; x=strcmp(a,b); y=strcmp("china","beijing"); z=strcmp(a,"china"); printf("x=%d\ny=%d\nz=%d\n",x,y,z); return 0; } x=-1 //只比较了c与h的ASCII码值,在ASCII码表中,c的值小于h的值 y=1 // 在ASCII码表中,c的值大于b的值 z=0
-
字符串长度函数strlen
strlen是函数,要在运行的时候才能计算。参数必须是字符型指针。当数组名作为参数传入时,实际上数组就退化成指针了
- 格式: strlen(字符数组)
- 功能:返回字符串的长度。该字符串可能时自己定义的,也可能时内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。
- 返值:返回字符串实际长度,不包括‘\0’在内
#include<stdio.h> #include<string.h> int main() { char a[]="china"; printf("%d\n",strlen(a)); printf("%d\n",sizeof(a)); } 5 //china后面自带'\0',strlen返回的字符串长度不带'\0' 6
-
strlwr函数
-
格式:strlwr(字符串)
-
作用:将字符串中的大写字母换成小写字母
-
-
strupr函数
- 格式:strupr(字符串)
- 作用:将字符串中的小写字母换成大写字母
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!