一、概述
计算30名同学的平均成绩,如何存储? 数组:有序集合;具有相同的数据类型(为了存储需要) 有序(便于使用/访问) 
二、一维数组:
(一)基本格式:
注意: 数组下标从0开始 int n = 10; a[n]; //错误定义
(二)C语言描述:
1.定义并输出1~10:
int a[10];
int i ;
for(i = 0;i < 10;i ++){
a[i] = i;
printf("%d ",a[i]);
}
printf("\n");
int j;
for(j = 9;j >= 0;j--){
a[j] = j;
printf("%d ",a[j]);
}
(三)一维数组初始化:
初始化:在定义的同时赋以初值 注意:只有在定义的同时才能初始化 ,数组名是常量,不可以赋值
int a[10] = {1,2,3,4,5,6,7,8,9,10};
for(int i = 0;i < 10;i++){
printf("%d ",a[i]);
}
printf("\n");
int b[10] = {1,2,3,4,5};
for(int j = 0;j < 10;j ++){
printf("%d ",b[j]);
}
printf("\n");
int c[] = {1,2,3,4,5,6,7,8,9,10};
for(int k = 0;k < 10;k++){
printf("%d ",c[k]);
}
printf("\n");
int d[10];
for(int n = 0;n < 10;n++){
printf("%d ",d[n]);
}
printf("\n");

(四)数组名:
数组名是常量 数组名是数组元素的首地址(指针)
int a[10] ;
printf("a = %p,&a[0] = %p",a,&a[0]);
数组名a的地址和第一个数组的地址一样 扩展: 数组中sizeof的使用: sizeof(数组名):计算的是数组的总大小 sizeof(数组元素):计算的是每个元素的大小
int a[10] ;
printf("%d ",sizeof(a));
printf("%d ",sizeof(a[0]));
printf("%d ",sizeof(a)/sizeof(a[0]));

(五)练习:
1.给定一个一维数组,求数组的最大值:
方法一:
int a[10] = {1,4,2,5,3,6,9,8,7,10};
int b[1];
for(int i = 0;i < 10;i ++){
if(a[i] > a[i + 1]){
b[0] = a[i];
}
}
printf("%d\n",b[0]);
方法二:
int a[10] = {1,4,2,5,3,6,9,8,7,10};
int max = a[0];
for(int i = 0;i < 10;i ++){
if(a[i] > a[i + 1]){
max = a[i];
}
}
printf("%d\n",max);
2.给定一个数组,实现数组的翻转:
int a[10] = {1,2,3,4,5,6,7,8,9,10};
for(int i = 0;i < 10;i ++){
printf("%d ",a[i]);
}
printf("\n");
printf("----------------------------\n");
for(int j = 9;j >= 0;j--){
printf("%d ",a[j]);
}
printf("\n");
int b[10];
for(int k = 0;k < 10;k ++){
b[k] = a[9-k];
printf("%d ",b[k]);
}
printf("\n");
int i = 0 ;
int j = sizeof(a) / sizeof(a[0])-1;
int temp;
while(i < j){
temp = a[i] ;
a[i] = a[j];
a[j] = temp;
i ++;
j --;
}
for(int n = 0;n < 10;n ++){
printf("%d ",a[n]);
}
printf("\n");

3.实现数组的排序:
int a[10] = {2,5,8,7,4,1,3,6,9,55};
for(int i = 0;i < 10;i ++){
printf("%d ",a[i]);
}
printf("\n");
printf("----------------------------\n");
int v = sizeof(a)/sizeof(a[0])-1;
int temp;
for(int n = 0;n < v-1;n ++){
for(int m = 0;m < v-1-n;m ++){
if(a[m] > a[m+1]){
temp = a[m];
a[m] = a[m+1];
a[m+1] = temp;
}
}
}
for(int k = 0;k < 10;k ++){
printf("%d ",a[k]);
}
4.求两数之和:
给定一个整数数组nums和一个目标值target,请在该数组中找出和为目标值的那两个整数,并返回下标;你可以假设每种输出只对应一个答案,但是不能重复利用数组中相同的元素
int target = 26;
int a[] = {2,7,11,15};
int n = sizeof(a) / sizeof(a[0]);
int i,j;
int result;
for(i = 0;i <= n;i++){
for(j = 1;j <= n;j++){
if(a[i] + a[j] == target){
result = 1;
break;
}
}
if(result == 1){
break;
}
}
if(result == 1){
printf("%d+%d=%d 元素下标为:%d %d ",a[i],a[j],target,i,j);
}
三、二维数组:
(一)基本格式:

(二)遍历二维数组:
int a[3][4];
int num = 0;
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 4;j ++){
a[i][j] = num;
num ++;
}
}
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 4;j ++){
printf("%d ",a[i][j]);
}
printf("\n");
}

(三)二维数组初始化:
int a[3][4] = {
{0,1,2,3},
{4,5,6,7},
{8,9,10,11},
};
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 4;j ++){
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("------------------------------\n");
int b[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 4;j ++){
printf("%d ",b[i][j]);
}
printf("\n");
}
printf("------------------------------\n");
int c[3][4] = {
{1},
{5},
{9},
};
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 4;j ++){
printf("%d ",c[i][j]);
}
printf("\n");
}
注意:
如果对二维数组全部赋初值,第一个[ ]可以省略,但第二个必须写
int a[][4] = {
{0,1,2,3},
{4,5,6,7},
{8,9,10,11},
};
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 4;j ++){
printf("%d ",a[i][j]);
}
printf("\n");
}
(四)练习:
1.实现二维数组行列交换:
int a[2][3] = {
{1,2,3},
{4,5,6},
};
printf("原数组:\n");
for(int i = 0;i < 2;i ++){
for(int j = 0;j < 3;j ++){
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("遍历倒置,不改变原数组:\n");
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 2;j ++){
printf("%d ",a[j][i]);
}
printf("\n");
}
printf("借助辅助数组,改变原数组:\n");
int b[3][2];
for(int i = 0;i < 2;i ++){
for(int j = 0;j <3;j ++){
b[j][i] = a[i][j];
}
}
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 2;j ++){
printf("%d ",b[i][j]);
}
printf("\n");
}

2.求二维数组中最大元素的值,并输出行列号:
int a[3][4] = {
{5,1,3,7},
{2,4,6,8},
{9,10,11,12},
};
printf("原数组:\n");
for(int i = 0;i < 3;i ++){
for(int j = 0;j < 4;j ++){
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("-------------------\n");
printf("最大值:");
int max = a[0][0];
int i,j;
for(i = 0;i < 3;i ++){
for(j = 0;j < 4; j ++){
if(max < a[i][j]){
max = a[i][j];
}
}
}
printf("%d\n",max);
printf("最大值行列号:%d %d",i,j);

3.二维数组总结:
二维数组的数组名和一维数组一样,都是常量,只能初始化,不能赋值 二维数组使用sezeof()计算的依旧是总大小,sizeof(a)/sizeof(int)或sizeof(a)/sizeof(a[0][0])依旧是数组个数(二维数组可以视为一维数组)
求得二维数组的行数:sizeof(a)/sizeof(a[0]) 求得二维数组的列数:sizeof(a[0])/sizeof(a[0][0]) 求得二维数组行列总数:sizeof(a)/sizeof(a[0][0])
四、字符数组:
(一)基本格式:
注意 注意 注意:C语言中,没有字符串类型,字符串存储在字符数组中 字符串以\0或0结尾(\0的ASCII码是0)结尾,而字符数组没有
(二)字符串与字符数组的定义:
char a[10] = {'h','e','l','l','o','\0'};
for(int i = 0;i < 10;i ++){
printf("%c",a[i]);
}
printf("\n");
char b[10] = {'h','e','l','l','o'};
for(int i = 0;i < 10;i ++){
printf("%c",b[i]);
}
(三)字符数组的初始化:
注: 字符数组和字符串输出:不需要循环,%s即可:printf("%s",数组名);
char a[10] = {'h','e','l','l','o','\0'};
for(int i = 0;i < 10;i ++){
printf("%c",a[i]);
}
printf("\n");
char b[10] = {'h','e','l','l','o','\0'};
printf("%s\n",b);
char c[10] = "hello";
printf("%s\n",c);
char d[] = "hello";
printf("d的大小:%d\n",sizeof(d));

当需要计算字符串或字符数组大小时,切记不要指定大小,写为:a[] = "hello" \0后面不要加其他数字,防止计算机理解为其他的ASCII码,产生其他的转义字符 注意: char a[] = {‘h’,‘a’,‘o’};和char a[] = {“hao”};不一样:前者为字符数组(3字符) 后者为字符串(4字符) char a[10] = {“0123456789”};不正确,\0占有一个字符位
(四)字符数组的输出格式:
%c:使用循环逐个输出,和一维数组一样 %s:直接一次性输出,不需要循环 输出字符串不包括\0 使用%s时,printf()的输出是数组名 当有多个\0时,遇到第一个\0便结束
(五)字符数组的输入:
1.scanf()【不允许空格 不做越界检查】:
scanf()时,数组名就是首地址名,故不需要寻址,即不需要& ,写上&不算错,有waring
char str[10];
printf("请输入字符串:");
scanf("%s",str);
printf("%s",str);
scanf输入时不能有空格,输入先放入缓冲区,缓冲区以空格作为分隔,仅用于scanf 不推荐使用scanf():不做越界检查,不安全
char str[2];
printf("请输入字符串:");
scanf("%s",str);
printf("%s",str);

2.gets(数组名)【允许空格 不做越界检查】:
char str[2];
printf("请输入字符串:");
gets(str);
printf("%s",str);
 scanf()和gets()只有遇见换行符或者文件结尾符才会停止接收输入
3.fgets【允许空格 越界检查】:
3.1.基本格式:
char *fgets(char *s,int size,FILE *stream); char *s:指针,也可以理解为数组名 size:接收的字符数 FILE *stream - stdin
功能:从stream中读取字符,保存到s中,直到出现换行或者读到文件结尾或者size-1(\0)为止,最后自动加“\0”作为结束符
注:fgets自动加入换行 不需要手动添加\n
3.2.C语言实现:
char str[10];
printf("请输入字符串:");
fgets(str,10,stdin);
printf("%s",str);

(六)字符数组的输出:
1.puts():
1.1.一般格式:
int puts(const char *s);
功能:向屏幕输出字符串,并且自动换行
1.2.C语言实现:
char str[10];
printf("请输入字符串:");
fgets(str,10,stdin);
puts(str);
2.fputs():
2.1.一般格式:
int fputs(const char *str,FIFE *stream); *stream - stdout
功能:向屏幕输出字符串,并且结尾不加"\0",不加换行
2.2.C语言实现:
char str[10];
printf("请输入字符串:");
fgets(str,10,stdin);
fputs(str,stdout);
(七)其他字符数组函数:
1.strlen():
1.1.一般格式:
size_t strlen(const char *s);
功能:计算指定字符串的长度,不包含\0
1.2.C语言实现:
char str[] = "hello";
printf("%d",strlen(str));
注:strlen计算的是长度,不会因为结束符而结束:char a[] = “\0hello”,计算结果为7 但当有指定大小时,输出指定大小:char a[10] ;计算结果为10
2.strcpy():
2.1.一般格式:
char *strcpy(char *dest,char *src); char *dest - 目标数组 char *src - 原数组
功能:将src拷贝到dest中,\0也拷贝,拷贝遇到\0结束
2.2.C语言实现:
char str[] = "hello";
char dest[10];
strcpy(dest,str);
printf("%s",dest);
3.strncpy():
3.1.一般格式:
char *strcpy(char *dest,char *src,size_t n); size_t n - src的前n个字符
功能:将src的前n个字符拷贝到dest中,\0也拷贝,拷贝遇到\0结束但拷贝\0
3.2.C语言实现:
char str[] = "hello";
char dest[10];
strncpy(dest,str,2);
dest[2] = '\0';
printf("%s",dest);
4.strcmp():
4.1.一般格式:
int strcmp(const char *s1,const char *s2);
功能:比较s1和s2的大小,比较的是ASCII码,依次比较,若相等才会比较下一个
4.2.C语言实现:
char s1[] = "hello";
char s2[] = "hello world";
int result = strcmp(s1,s2);
if(result > 0){
printf("s1 > s2");
}else if(result < 0){
printf("s1 < s2");
}else{
printf("s1 = s2");
}
Pt:strncmp(s1,s2,n),比较前n个字符大小
5.strcat():
5.1.一般格式:
char strcat(char *dest,char *src);
功能:将src的字符串连接到dest,\0也会追加过去
5.2.C语言实现:
char s1[] = "hello";
char s2[] = " world";
printf("%s",strcat(s1,s2));
Pt:strncat(dest,src,n),将src的前n个追加
五、练习:
输入一行字符串,统计单词词组的个数:
char a[] = "hello world hello china";
int num = 0;
int word = 0;
for(int i = 0;a[i] != '\0';i ++){
if(a[i] == ' '){
word = 0;
}else if(word == 0){
word = 1;
num ++;
}
}
printf("%d",num);

|