什么是数组?
数组是一组有序数据的集合;数组中各数据的排列是有一定规律的,下标代表数据在数组中的序号。
数组中的每一个元素都属于同一个数据类型;不能把不同类型的数据放在同一个数组中。
C语言规定用方括号中的数字来表示下标,如s[5]。
怎样定义和引用一维数组
一维数组是数组中最简单的,它的元素只需要用数组名加一个下标,就能唯一地确定。
怎样定义一维数组
定义一维数组地一般形式为:
类型说明符 数组名[ 常量表达式 ] ;
例如: int a[10];
数组名的命名规则和变量名相同,遵循标识符命名规则。
方括号中的常量表达式用来表示元素的个数,即数组长度。如:指定a[10],表示a数组有10个元素,下标从0开始,所以a[10]中不存在数组元素a[10]。
常量表达式中可以包括常量和符号常量,如“int a[3+5];”是合法的,而“int a[n];”是不合法的。
C语言不允许对数组的大小作为动态定义,即数组的大小不依赖于程序运行过程中变量的值。
int n;
scanf("%d",&n); //企图在程序中临时输入数组的大小
int a[n];
怎样引用一维数组
只能引用数组元素而不能一次整体调用整个数组全部元素的值。
引用数组元素的表示形式为:
数组名 [ 下标 ]
例如:a[0]就是数组a中序号为0的元素,它和一个简单变量的地位和作用相似。
#include <stdio.h>
int main(){
int i,a[10];
for(i=0;i<=9;i++) //对数组元素a[0]~a[9]赋值
a[i]=i;
for(i=9;i>=0;i--) //输出a[9]~a[0]共10个数组元素
printf("%d",a[i]);
printf("\n");
return 0;
}
一维数组的初始化
在定义数组的同时给各数组元素赋值,这称为数组的初始化。
在定义数组时对全部数组元素赋予初值;如:int a[10]={0,1,2,3,4,5,6,7,8,9}; 元素的初值顺序放在一对花括号内,数据间用逗号分隔,花括号内的数据就称为“初始化列表”。
可以只给数组中的一部分元素赋初值;如: int a[10]={0,1,2,3,4}; 表示只给前面5个元素赋初值,系统自动给后5个元素赋初值0。
如果想使一个数组中全部元素值为0,可以写成:int a[10]={0,0,0,0,0,0,0,0,0,0};或 int a[10]={0};(未赋值的部分元素自动设定为0).
在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。如:int a[5]={1,2,3,4,5};可以写成 int a[]={1,2,3,4,5}; 如果数组长度与提供初值的个数不相同,则方括号中的数组长度不能省略;例如:像定义数组长度为10,就不能省略数组长度的定义,而必须写成 int a[10]={1,2,3,4,5}; 只初始化前5个元素,后5个元素为0.
如果是字符型数组,则初始化为“\0”,如果是指针数组,则初始化为NULL,即空指针。
一维数组程序举例
#include<stdio.h>
int main(){ //纳契数列
int i;
int f[20]={1,1}; //对前面两个元素f[0]和f[1]赋初值1
for(i=2;i<20;i++)
f[i]=f[i-2]+f[i-1]; //先后求出f[2]~f[19]的值
for(i=0;i<20;i++){
if(i%5==0) printf("\n"); //控制每输出5个数后换行
printf("%12d ",f[i]); //输出一个数
}
printf("\n");
return 0;
}
#include<stdio.h>
int main(){
int a[10];
int i,j,t;
printf("input 10 number: \n");
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("\n");
for(j=0;j<9;j++) //进行九次循环,实现9趟比较
for(i=0;i<9-j;i++) //在每趟中进行9-j次比较
if(a[i]>a[i+1]) //相邻两个数比较
{t=a[i];a[i]=a[i+1];a[i+1]=t;}
printf("the sorted number : \n");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
怎样定义和引用二维数组
二维数组常称为矩阵;把二维数组写成行(row)和列(column)的排列形式,有助于形象化地理解二维数组的逻辑结构。
怎样定义二维数组
二维数组定义的一般形式:
类型说明符 数组名[ 常量表达式a ] [ 常量表达式b ];
常量表达式a控制行,常量表达式b控制列;例如:float a[3][4]; 定义a为3行4列的数组。
二维数组中元素排列的顺序是按行存放的,即在内存中先顺序存放第1行的元素,接着在存放第2行的元素;而在内存中,各元素是连续存放的,不是二维的,是线性的。
C语言还允许使用多维数组,例如:float a[2][3][4]; 定义三维数组a,它有2页3行4列。
怎样引用二维数组元素
二维数组元素的表示形式为:
数组名 [下标][下标]
如:a[2][3]表示a数组中序号为2的行中序号为3的列的元素;下标应是整形表达式,如:a[2-1][2*2-1] ,不要写成a[2,3] ,a[2-1,2*2-1]的形式。
数组元素可以出现在表达式中,也可以被赋值:
b[1][2]=a[2][3]/2
在引用数组元素时,下标值应在已定义的数组大小的范围内。严格区分在定义数组时用的a[3][4]和引用元素时的额a[3][4]的区别:
前者用a[3][4]来定义数组的维数和各维的大小,后者a[3][4]中的3和4是数组元素的下标值,a[3][4]代表行序号为3、列序号为4的元素(行序号和列序号均从0起算)。
二维数组的初始化
可以用“初始化列表”对二维数组初始化:
分行给二维数组赋值:
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
即按行赋初值。
可以将所有数据写成在一个花括号内,按数组元素在内存中的排列顺序对各元素赋初值:
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
可以对部分元素赋初值:
int a[3][4]={{1},{5},{9}};
//即: 1 0 0 0
// 5 0 0 0
// 9 0 0 0
//也可以对各行中的某一元素赋初值:
int a[3][4]={{1},{0,6},{0,0,11}};
//即: 1 0 0 0
// 0 6 0 0
// 0 0 11 0
//也可以只对某几行元素赋初值:
int a[3][4]={{1},{5,6}};
//即: 1 0 0 0
// 5 6 0 0
// 0 0 0 0
//第三行不赋初值
//也可以对第2行不赋初值:
int a[3][4]={{1},{},{9}};
如果对全部元素都赋初值,则定义数组时对第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};
//系统会根据总个数和第2维的长度算出第1维的长度。
二维数组程序举例
#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(i=0;i<=1;i++) //处理a数组中的一行中各元素
{
for(j=0;j<=2;j++) //处理a数组中某一列中各元素
{
printf("%5d",a[i][j]); //输出a数组的一个元素
b[j][i]=a[i][j]; //将a数组元素的值赋给b数组相应元素
}
printf("\n");
}
printf("array b:\n"); //输出b数组各元素
for(i=0;i<=2;i++) //处理b数组中一行中各元素
{
for(j=0;j<=1;j++) //处理b数组中一列中各元素
printf("%5d",b[i][j]); //输出b数组的一个元素
printf("\n");
}
return 0;
}
#include<stdio.h>
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];//先认为a[0][0]最大
for(i=0;i<=2;i++)
for(j=0;j<=3;j++)
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;
}
字符数组
C语言中没有字符串类型,也没有字符串变量,字符串是存放在字符型数组中的。
怎样定义字符数组
用来存放字符数据的数组是字符数组,定义字符数组的方法与定义数值型数组的方法类似:
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';
//以上定义了c为字符数组,包含10个元素。
字符数组的初始化
对字符数组初始化,最容易理解的方式是用“初始化列表”,把各个字符一次赋给数组中各元素,如:
char c[10]={'I',' ','a','m',' ','h','a','p','p','y'};
如果花括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误;初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(‘\0’).
怎样引用字符数组中的元素
可以引用字符数组中的一个元素,得到一个字符。
输出已知的字符串:
#include<stdio.h>
int main(){
char c[15]={'I',' ','a','m',' ','a',' ','s','t','u','d','e','n','t','.'};
int i;
for(i=0;i<15;i++)
printf("%c",c[i]);
printf("\n");
return 0;
}
输出一个菱形:
#include<stdio.h>
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;
}
字符串和字符串结束标志
在C语言中,是将字符串作为字符数组来处理的;为了测定字符串的实际长度,C语言规定了一个“字符串结束标志“,以字符“\0”作为结束标志。在遇到字符”\0“时,表示字符串结束,把它前面的字符组成一个字符。
C系统在用字符数组存储字符串常量时会自动加一个"\0"作为结束符。
在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度;在一个字符数组中先后存放多个不同长度的字符串,则应使数组长度大于最长的字符串的长度。
在向内存中存储时,系统自动在最后一个字符”\n“的后面加一个”\0“,作为字符串结束标志,在执行printf函数时,每输出一个字符检查一次,看一下字符是否为”\0“,遇”\0“就停止输出。
补充一种对字符数组初始化的方法,即用字符串常量来使字符数组初始化,如:
char c[]={"I am happy"};
//也可以省略花括号,直接写成:
char c[]="I am happy";
字符数组的输入输出
字符数组的输入输出有两种:
逐个字符输入输出,用格式符”%c“输入或输出一个字符;
将整个字符串一次输入或输出,用”%s“格式符,意思是对字符串的输入输出。
例如:
char c[]={"China"};
printf("%s\n",c);
说明:
输出的字符串不包括结束符‘\0’。
用”%s“格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名
如果数组长度大于字符串的实际长度,也只输出到遇'\0'结束,只输出字符串的有效字符。
如果一个字符数组中包含一个以'\0',则遇第一个'\0'时输出就结束。
可以用scanf函数输入一个字符串,scanf函数中的输入项要是已定义的字符数组名,输入的字符串应短于一定义的字符数组长度;如果利用一个scanf函数输入多个字符串,则应在输入时以空格分隔;scanf函数中的输入输出项如果是字符数组名,不要再加地址符&,因为在C语言中数组名代表该数组第一个元素的地址(或数组的起始地址)。
输出字符串的方法:
printf("%s",c);
实际上是:按字符数组名c找到其数组第一个元素的地址,然后逐个输出其中的字符,直到遇'\0'为止。
使用字符串处理函数
puts函数---输出字符串的函数
一般形式为:
puts(字符数组)
其作用是将一个字符串(以'\0'结束的字符序列)输出到终端;用puts函数输出的字符串可以包含转义字符:
char str[]={"China\nBeijing"};
printf(str);
在用puts输出时将字符串结束标志'\0'转换成'\n',即输出完字符串后换行。
gets函数---输入字符串的函数
其一般形式为:
gets(字符数组)
其作用是:从终端输入一个字符串到字符数组,并且得到一个函数值,该函数值是字符数组的起始地址;如:
gets(str); //str是已定义的字符数组
//如果从键盘输入:Computer 将输入的字符串送给字符数组str,返回的函数值是字符数组str的第一个元素地址。
一般利用gets函数的目的是向字符数组输入一个字符串,而不大关心其函数值。
用puts和gets函数只能输出或输入一个字符串,不能写成:
puts(str1,str2);
//或
gets(str1,str2);
strcat函数---字符串连接函数
其一般形式为:
strcat(字符数组1,字符数组2);
其作用是把两个字符数组中的字符串连接起来,把字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值——字符数组 1的地址,如:
char str1[30]={"People's Republic of"};
char str2[]={"China"};
printf("%s",strcat(str1,str2));
说明:
字符数组1必须足够大,以便容纳连接后的新字符串。
连接前两个字符串的后面都有'\0',连接时将字符串后面的'\0'取消,只在新字符串最后保留'\0'。
strcpy和strncpy函数---字符串复制函数
其一般形式为:
strcpy(字符数组1,字符串2);
其作用是将字符串2复制到字符数组1中去,如:
char str1[10],str2[]='China';
strcpy(str1,str2);
字符数组1必须定义得足够大,以便容纳被复制的字符串2;字符数组1的长度不应小于字符串2的长度。
”字符数组1“必须写成数组名形式(str1),”字符串2“可以是字符数组名,也可以是一个字符串常量,如:
strcpy(str1,"China"); //作用与前面相同
复制时将str2中的字符串和其后的'\0'一起复制到字符数组1中,取代字符数组1中的前6个字符,最后4个字符并不一定是'\0',而是str1中原有的最后4个字节内容。
不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组;字符数组名是一个地址常量,它不能改变值,正如数值型数组名不能被赋值一样;只能用strcpy函数将一个字符串复制
到另一个字符数组中去,用赋值语句只能将一个字符赋给一个字符型变量或字符数组元素。如:
char a[5],c1,c2;
c1='A';c2='B';
a[0]='C';a[1]='h';a[2]='i';a[3]='n';a[4]='a';
可以用strncp函数将字符串2中前面n个字符复制到字符数组1中去,如:
strncp(str1,str2,2);
作用是:将str2中最前面2个字符复制到str1中,取代str1中原有的最前面2字符;但复制的字符个数n不应多于str1中原有的字符串(不包括'\0')。
strcmp函数---字符串比较函数
其一般形式为:
strcmp(字符串1,字符串2);
其作用是:比较字符串1和字符串2;如:
strcmp(str1,str2);
strcmp("China","Korea");
strcmp(str1,"Beijing");
字符串的比较规则:将两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到'\0'为止;
如全部字符相同,则认为两个字符串相等;
若出现不相同的字符,则以第1对不相同的字符的比较结果为准。
说明:
如果参加比较的两个字符串都由英文字母组成,则有一个简单的规律:在英文字典中位置在后面的为”大“,但应注意小写字母比大写字母”大“。
如果字符串1与字符串2相同,则函数值为0;
如果字符串1>字符串2,则函数值为一个正整数;
如果字符串1<字符串2,则函数值为一个负整数。
对两个字符串比较,只能用:
if(strcmp(str1,str2)>0)
printf("yes");
strlen函数---测字符串长度的函数
一般形式为:
strlen(字符数组);
它是测试字符串长度的函数,函数的值为字符串中的实际长度(不包括'\0'在内),如:
char str[10]="China";
printf("%d",strlen(str));
也可以直接测试字符串常量的长度,如:
strlen("China");
strlwr函数---转换为小写的函数
其一般形式为:
strlwr(字符串);
其作用是将字符串中大写字母换成小写字母。
strupr函数---转换为大写的函数
其一般形式为:
strupr(字符串);
函数的作用是将字符串中小写字母换成大写字母。
在使用字符串处理函数时,应当在程序文件的开头用 #include <string.h> 把string.h文件包含到本文件中。
字符数组应用举例
输入一行字符,统计其中有多少个单词,单词之间用空格隔开:
#include <string.h>
#include<stdio.h>
int main()
{
char string[81];
int i,num=0,word=0;
char c;
gets(string); //输入一个字符串给字符数组string
for(i=0;(c=string[i])!='\0';i++) //只要字符不是'\0'就继续执行循环
if(c==' ') word=0; //如果是空格字符,使word置0
else if(word==0) //如果不是空格字符且word原值为0
{
word=1; //使word置1
num++ //num累加1,表示增加一个单词
}
printf("There are %d words in this line.\n",num); //输出单词数
return 0;
}
注意:
赋值表达式”c=string[i]“两侧的括号不可缺少,如果写成”c=string[i]!='\0'“,由于关系运算符”!=“的优先级高于赋值运算符”=“,就会先执行关系运算:”string[i]!='\0'“,这样字符变量c得到的值是关系运算符的结果(”真“(1)或”假(0)“),而不是字符。
有三个字符串,要求找出其中”最大“者:
#include <string.h>
#include<stdio.h>
int main()
{
char str[3][20]; //定义二维字符数组
char string[20]; //定义一维字符数组,作为交换字符串时的临时字符数组
int i;
for(i=0;i<3;i++)
gets(str[i]); //读入3个字符串,分别给str[0],str[1],str[2]
if(strcmp(str[0],str[1])>0) //若str[0]大于str[1]
strcpy(string,str[0]); //把str[0]的字符串赋给字符数组string
else //若str[0]小于等于str[1]
strcpy(string,str[1]); //把str[1]的字符串赋给字符数组string
if(strcmp(str[2],string)>0) //若str[2]大于string
strcpy(string,str[2]); //把str[2]的字符串赋给字符数组string
printf("\nthe largeat is : \n%s\n",string); //输出string
return 0;
}
以上就是这两天的学习内容,关于数组的更多内容各位小伙伴还可以在网上找到噢