目录
一.一维数组
一般形式:数据类型 数组名[数组长度]
eg: int x[5]
补充说明:1.一个类型中可以同时说明多个数组和变量,中间用逗号隔开
2.数组长度必须是正整数型常量或常量表达式
3.数组元素的表现形式:数组名[下标];
下标需不超过数组长度n-1.超出则称数组下标越界
4.数组元素初始化:一般形式: 数据类型 数组名[数组长度]={元素初始值列表};
eg: int score[5]={85,86,78,90,75}
若先定义数组,在对元素单独初始化,则可以是变量常量表达式或者从键盘外输入的值
eg:
int i, a[10];
for( i=0;i<10;i++ ) /*输入数组中的10个数*/
scanf("%d", &a[i]);
例5.3键盘输入5整数,从小到大排序输出
除了输入循环,大排序元素交换循环,还有位置变量排序循环顺序交换
eg:
#include <stdio.h>
#define N 5
int main()
{
int i,j,t,a[N],imax,position;
for(i=0;i<N;i++)
scanf("%d", &a[i]);
for(i=0;i<N-1;i++)//外层循环
{
imax=a[i];
position=i;
for(j=i+1;j<N;j++)//内层循环
if (a[j]>imax)
{
imax=a[j];
position=j;
}
if(position!=i)
{
t=a[i];
a[i]=a[position];
a[position]=t;
}
}
printf("排序的结果:");
for(i=0;i<N;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
二.二维数组
一般形式: 数据类型 数组名 [一维长度] [二维长度]
eg: int x[3][4]
补充说明:1.一维表示,行数,二维表示列数
2. 数组元素表示: 数组名[下标1][下标2]
3.行、列下标均从0开始
4.二维数组同一维数组一样,不能一次性引用整个数组。而只能逐个引用。一般用双重循环逐个输入或输出。外层循环的循环控制变量的值与行下标相对应,内层循环的循环控制变量与列下标相对应。eg:
#include stdio.h>
int main()
{
int x[2][3];
int i,j;
for(i=0;i2;i++) /*二维数组的输入,外层循环控制行*/
for(j=0;j3;j++) /*内外层循环控制列*/
scanf("%d", &x[i][j]);
for(i=0;i2;i++) /*二维数组的输出*/
{
for(j=0;j3;j++)
printf("%d ", x[i][j]);
printf("\n"); /*输出一行元素后换行*/
}
return 0;
}
5.行序优先。先存储第0行的所有元素,才存储第一行的元素
6.二维数组初始化赋值
(1):分行赋初值:一般形式:数据类型 数组名[行长度][列长度]={{第一行元素的值},...最后一行元素的值}
eg:
int x[2][3]={{1,2,3},{4,5,6}};
即:x[0][0]=1,x[0][1],x[0][2],x[1][0],x[1][1],x[1][2]
补充:1.行长度可以省略,但是列宽度不能省略。
2.每行赋值可以采用部分赋值法
(2):所有初值写在一对大括号里:一般形式: 数据类型 数组名[行长度][列长度]={初始值列表}
eg:
int x[0][0],={1,2,3,4,5,6};
(顺序赋值,按顺序赋值)
补充:1.所有初始值,用逗号分分隔
2.行长度可以省略,但是列宽度不能省略。
行长度由大括号里数值数量和列宽度决定
(3):先定义,后对每一元素单独初始化eg:
int score[2][3]
score[0][1]=85
score[1][2]=86
...
三.字符数组
1.字符数组的定义:
一般形式: char 字符数组名[字符串长度]
eg:
char s[5];
补充说明:1.字符数组的初始化方式和数值型数组的方式一样
2.定义的同时进行初始化/也可以先定义再初始化
完全赋值的情况: char s[5]={'a','b','c','d','e'};
定义时省略数组长度的情况:char s[ ]={'a','b','c','d'};
部分赋值:char s[5]={'a','b'};没赋 的当0处理
2.字符数组表示字符串
(1)字符串表示:
字符数组中某元素的值为‘\0’,则可以称这个字符数字为字符串。用字符数组表示字符串
(2)字符串的初始化(利用双引号来初始化):
" char s[8]={"hello"};“ 字符串常量”Hello“含有6个字符,除了看得见的,结束的地方还有一个默认的”\0“结束标志。相当于 s[0]='h',s[1]='e',s[2]='l',s[3]='l',s[4]='0',s[5]='\0',s[6],s[7]没有赋值,取默认值ascii码0,也是'\0',虽然567都是0,但是取的方式不一样
“char s[8]="hello";”大括号省略不写
“char s[ ]="hello";"数组长度省略不写,还是6
(3)字符串输出:
一般方法:printf函数和puts函数(需使用stdio.h头文件)
printf函数的使用 :
调用要求:输出字符串采用%s 或%c两种格式符
使用%c:
eg:
char s[]="hello";
int i;
for(i=;s[i]!='\0';i++)
printf("%c",s[]);
使用%s:
eg :char s[]="hello";
printf("%s",s); //或者
printf("%s","hello");
区别:%c,字符需要利用循环逐个输出,'\0'为循环截止条件每次输出一个字符
%s ,对应输出项是字符数组名字或字符串常量,进行字符串的整体输出,不需要使用循环
puts函数的使用 :
调用格式:puts(字符数组名或字符串常量);
函数功能:输出字符串直到‘\0’并将'\0'转化成‘\n’输出,
函数参数(只有一个):表示要输出的字符串内容eg:
char str[]="hello";
puts(str); //或者
puts("hello");
补充说明:字符数组需有字符串结束标志:‘\0’
若没有,如,char str[]={'h','e','l','l','o'};是错误的代码
由于没有结束标志,printf和puts函数在输出完hello后,继续访问内存直到遇到‘\0’,会导致不确定的字符输出
(4)字符串的输入
一般方法:使用scanf函数和gets函数(使用时需将头文件stdio.h包含进来)
scanf函数的使用
输入字符串需使用格式控制字符%s,对应输出项是字符数组名
特点(遇到空格停止)格式:
char name[20];
scanf("%s",name);
printf("%s",name);
补充说明:
1,运行至scanf时,若输入niubi,则这5个字符会被存到str[0]~str[4],并且'\0'被存到str[9]中
2,使用scanf输入字符串如遇到空格则输入操作停止,因此无法使用scanf输入一个包含空格的字符串
eg:上述程序段如输入 niubia wokao
则保存到str数组里的只有niubia 而没有wokao,没能完整保存
3,利用scanf函数可以连续输入多个字符串,字符串间用空格或者回车符分隔
eg: char jinstr[10],maostr[10];
scanf("%s%s",jinstr,maostr);
此时如果输入niubia wokao 则,jinstr中存放niubia,maostr中存放wokao
gets函数的使用
格式: gets(字符数组或者字符串常量)
函数功能:从键盘读入一整行字符包含空格,遇到换行符‘\n’停止,'\n'转换为字符串结束标志、
函数参数(只有一个):用来存储输入的字符串内容(字符串数组的数组名)
eg:
char name[100];
gets(name);
puts(name);
此时,输入niubia wokao回车,niubia wokao会被整体保存在name里,并在puts输出
补充说明:
1.gets函数由于没有指定输入字符的大小来限制缓冲区的大小,如果输入的字符数大于定义的数组长度,会发生内存越界,堆栈溢出,炸裂后果。
fgets函数的使用
因此,C中常使用fgets函数来替代gets函数,其简单示例如下eg:
#include
#include
int main()
{
char s[100];
printf(“输入字符串:\n”);
fgets(s,100,stdin);
s[strlen(s)-1]='\0'; //去掉回车符
printf("%s\n",s);
retern 0;
}
补充说明:
(1):fgets函数包含三个参数,字符串数组名,字符串最大长度,输入来源
stdin表示键盘(在stdio中定义的)
(2):fgets函数将输入结束的回车符也当做字符串的一部分,用strlen检测,和gets函数对比字符串长度,结果不一样,fgets函数多一位回车符'\n',因此,需利用
s[strlen(s)-1]='\0';把回车符去掉
(3):fgets函数比gets函数安全,gets函数没有输入函数的限制。fgets会指定长度,如果超出长度的限制会自动根据定义的长度限制进行截断。
3.字符串处理函数:
使用时需要将头文件string.h包含到文件中
(1)strlen函数的使用:
strlen即测试字符串长度函数
函数功能:求字符串实际字符个数,不包括字符串结束标志'\0'在内。
函数参数(只有一个):字符数组名或者字符串常量eg:
#include
#include
int main()
{
char str[]="hello";
printf("%d\n",strlen(str));
return 0;
}
(2)strcmp函数的使用
strcmp即字符串比较函数
函数功能:两个字符串比较大小。如果字符串1与字符串2完全相等,strcmp函数返回0;如果字符串1大于字符串2,则函数返回一个正整数;如果字符串1小于字符串2;则返回一个负整数
函数参数(两个):两个参数均为字符数组名或字符串常量
补充说明:字符串比较规则:
对两个字符串,从左至右逐个字符比较其ASCII码值大小,直到遇到不相等的字符或‘\0’为止。如果全部字符都相等,则两个字符串相等;如果出现不相等的字符,则以第一个不相等的字符的比较结果为准。
eg:
#include <stdio.h>
#include <string.h>
int main( )
{
char str1[100],str2[100];
int k;
fgets(str1,100,stdin);
fgets(str2,100,stdin);
k=strcmp(str1,str2);
if(k==0)
printf("str1与str2相等");
else if(k>0)
printf("str1比str2大");
else
printf("str1比str2小");
printf("\n");
return 0;
}
(3)strcpy函数的使用
strcpy即字符串复制函数
函数功能:将字符串2复制到字符数组1中。包含串中的结束符'\0'。定义时,字符数组1的长度必须大于字符串2的实际长度。
函数参数(两个参数):第一个为字符数组名,第二个为字符串常量或字符数组名
eg:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[10],str2="hello!";
strcpy(str1,str2);
puts(str1);
return 0;
}
结果为显示hello!
补充说明:
1.strcpy的第一个参数str1在定义时一定要足够大,以容纳str2的字符串和结束符'\0',否则将造成数组越界操作,产生异常
2.不能用str1=str2;来复制字符串,必须使用strcpy函数进行。因为 str1,str2是数组名,代表字符数组的起始地址(地址概念将在后文指针章节介绍)。
C语言把数组名定义为地址常量,不能给常量赋值。
(4)strcat函数的使用
strcat即字符串连接函数
函数功能:将两个字符串连接起来成为一个新串。连接时将第一个串的结束符删除,将第二个字符串连同结束符连接到第一个串的后边,形成一个新的字符串,储存在字符数组1中。
函数参数(两个参数):第一个为字符数组名,第二个为字符串常量或者字符数组名。eg:
#include <stdio.h>
#include <string>
int main()
{
char str1[30]="The C program",str2[ ]="language";
strcat(str1,str2);
puts(str1);
return 0;
}
结果为:The C program language.
补充说明:字符数组1的长度应该足以容纳新串的全部内容
(5)strlwr函数的使用
strlwr即字母大小写转换函数
函数功能:将字符串总所有的大写字母都转换成小写字母,其他字符不变。
函数参数(只有一个):为已赋值的字符数组名或者字符串常量
(6)strupr函数的使用
strupr即字母小大写转换函数
函数功能:将字符串里所有小写字母转换成大写字母,其他字符不变
函数参数(只有一个):为已赋值的字符数组名或字符串常量eg:
#include <stdio.h>
#include <string.h>
int main()
{
char str[]="The **C##Program**Language!";
printf("%s",strupr(str));
printf("%s",strlwr(str));
return 0;
}
结果为:
THE**C##PROGRAM**LANGUAGE!
the**c##program**language!
补充说明:strlwr和strupr两个函数都不是标准C的库函数