算法笔记系列:2.5 数组
2.5.1 一维数组
-
定义格式:数据类型 数组名[数组大小];
-
例如 int a[10] 定义10个int型数据,分别为a[0]到a[9]
2.5.2 冒泡排序
冒泡排序的本质在于交换,通过与邻近元素交换,步长为1进行,每一次遍历都可以把最大的元素或者最小的元素放到最右边,然后排除最右边的元素,再剩余元素中重复该操作以完成排序
#include<stdio.h>
int main(){
int a[10]={3,1,4,5,2};
for (int i=1;i<=4;i++){ //一共运行n-1趟
for (int j=0;j<5-i;j++){ //每运行一次,都能把剩余元素中最大的放到最右边
if (a[j]>a[j+1]){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for (int i=0;i<5;i++){
printf("%d ",a[i]);
}
return 0;
}
输出:
1 2 3 4 5
2.5.3 二维数组
-
定义格式: 数据类型 数组名[第一维大小][第二维大小];
-
注意:如果数组过大(大到 1 0 6 10^6 106的级别),需要定义在main函数外部,否则会使程序异常退出,原因是函数内部申请的局部变量来自于系统栈,允许申请的空间较小,而函数外申请的全局变量来自静态存储区,空间较大
-
多维数组以此类推
2.5.4 memset——对数组中每一个元素赋相同的值
-
用memset是因为相比于fill函数,它执行速度更快
-
推荐只赋值0或-1,因为memset使用的是按字节赋值,即对每个字节赋同样的值,而0的二进制补码全为0,-1的二进制补码全为1,不容易弄错
-
格式:memset(数组名,值,sizeof(数组名))
2.5.5 字符数组
-
字符数组的输入输出
-
scanf输入,printf输出:注意%c和%s这两个格式,%c用于输入单个字符而%s用于输入字符串。%c能够识别空格和换行并将其输入,而%s通过空格和换行表示一个输入结束
-
getchar输入,putchar输出:用来输入和输出单个字符
-
gets输入,puts输出:gets用于输入一行字符串,识别换行符\n作为输入结束;puts 用来输出一行字符串,并紧跟一个换行
-
-
字符数组的存放方式
-
字符数组由若干个char类型的元素组成,在数组末尾都有一个空字符\0,gets和scanf会自动在字符串后加空字符,并占用一个字符位,而puts和printf通过识别\0作为字符串结尾来输出
-
\0的ASCII码为0,即NULL,占一个字符位,因此初始化字符数组一定要比实际输入的位数多至少1,int型数组就不需要
-
如果不用gets和scanf输入,一定要在字符串后面手动添加\0,否则输出会有乱码
-
2.5.6 string.h头文件
string.h内包含的常用函数
-
strlen():得到字符数组第一个\0前面的字符的个数
-
strcmp():返回两个字符串大小的比较结果,比较的原则是按字典序,即按照顺序从左到右逐个比较直到比出大小。
-
格式为 strcmp(字符数组1,字符数组2)
-
如果字符数组1<字符数组2,则返回一个负整数
-
如果字符数组1==字符数组2,则返回0
-
如果字符数组1>字符数组2,
-
-
strcpy():格式 strcpy(字符数组1,字符数组2) 注意是把字符数组2复制给字符数组1,这里复制会包括结束符\0,所以用puts和printf的时候碰到\0就结束了
# include<stdio.h> # include<string.h> int main(){ char str1[5]="abcd",str2[3]="12"; strcpy(str1,str2); puts(str1);//puts会自动换行 printf(str1); printf("\n"); for (int i=0;i<5;i++){ putchar(str1[i]);//挨个输出会发现复制即为按顺序覆盖,\0覆盖了c } return 0; } 输出: 12 12 12d
-
strcat():格式: strcat(字符数组1,字符数组2);
把字符数组2接到字符数组1后面
2.5.7 sscanf与sprintf
举例说明
-
sscanf(str,"%d",&n);
把字符串数组str中的内容以"%d"的格式写到n中(从左至右)
-
sprintf(str,"%d",n);
把n以"%d"的格式写到str字符数组中(从右至左)
-
sscanf还支持正则表达式,很多字符串的题目可以用到