2.5.1 一维数组
1、
scanf("%d%d",&a,&b);
scanf("%d %d",&a,&b);
两个相同
2、字符数组
char a[10];
scanf("%s",a);
printf("%s",a);
3、数组初始化。
初始化1:逗号隔开,大括号括住。后面未被赋初值的元素将会由不同编译器内部
实现的不同而被赋以不同的初值(可能是很大的随机数),而一般情况默认初值为0。
初始化2:如果想要给整个数组都赋初值0,只需要把第一个元素赋为0,或者只用一个大
括号来表示。
int a[10]={0};
int a[10]={};
2.5.2 冒泡排序-跳过
2.5.3 二维数组
1.需要注意的是,对定义为int a[size1 ][size2]的二维数组,
其第-维的下标取值只能是0~(size1-1),其第二维的下标取值只能是0~ (size2- 1)。
2.二维数组初始化
int a[5][6] = {{3, 1, 2},{8,4},{},{1, 2, 3, 4, 5}};
输出结果:
312000
840000
000000
123450
000000
3.特别提醒:如果数组大小较大(大概10^6级别),则需要将其定义在主函数外面,否则会使程序异常退出,
原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部
申请的全局变量来自静态存储区,允许申请的空间较大。例如下面的代码就把
10^6大小的数组定义在了主函数外面。
#include <stdio.h>
int a[1000000] ;
int main() {
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/bdfd5429cb52d5975e3b04d89c33f059.png)
2.5.4 memeset——对数组中每一个元素赋相同的值
如果需要对数组中每一个元素赋以相同的值,例如对数组初始化为0或是其他的一些数,就可能要使用相关的函数。
一般来说,给数组中每一个元素赋相同的值有两种方法: memset函数和fill函数,其中fill 函数在第6章STL的algorithm头文件中介绍,这里先介绍memset
函数。
memset函数的格式为:
memset (数组名,值,sizeof (数组名));
不过也要记住,使用memset需要在程序开头添加"string.h"头文件,且只建议初学者使用
memset赋0或-1。 这是因为memset使用的是按字节赋值,即对每个字节赋同样的值,这样
组成int型的4个字节就会被赋成相同的值。而由于0的二进制补码为全0,-1的二进制补码
为全1,不容易弄错。如果要对数组赋其他数字(例如1), 那么请使用fill函数(但mermset
的执行速度快)。
例子:
int a[5]={1,2,3,4,5} ;
memset(a,0, sizeof(a)) ;
memset (a,-1,sizeof(a));
2.5.5 字符数组
1.1 字符数组的初始化1
char str[15] ={'G','o', 'o','d',', 's','t','o','r', 'y','!'};
for(int i= 0;i< 11; i++) {
printf ("%c",str[i]) ;
1.2 字符数组的初始化2
除此之外,字符数组也可以通过直接赋值字符串来初始化(仅限于初始化,程序其他位
置不允许这样直接赋值整个字符串),示例如下:
#include <stdio.h>
int main() {
char str[15] = "Good Story!";
for(int i= 0; : i<11; i++) {
printf("%c", str[i]) ;
2.字符数组的输入输出
字符数组就是char数组,当维度是一维时可以当作“字符串”。
当维度是二维时可以当作字符串数组,即若干字符串。字符数组的输入除了使用scanf外,还可以用getchar或者gets;其输出除了使用printf外,还可以用putchar或者puts。
(1) scanf输入,printf 输出
scanf对字符类型有%c和%s两种格式(printf 同理,下同), 其中%c用来输入单个字符,
%s用来输入一个字符串并存在字符数组里。%c格式能够识别空格跟换行并将其输入,而%s
通过空格或换行来识别一个字符串的结束。示例如下:
str[10];
scanf ("%s",str) ;
printf ("%s",str) ;
输入下面这个字符串:
TAT TAT TAT
输出结果:
TAT
(2) getchar 输入,putchar 输出
getchar和putchar 分别用来输入和输出单个字符
char str[5] [5];
for(int i= 0; i<3; i++) {
for(int j =0;j<3; j++) {
str[i][j] = getchar() ;
getchar(); / /这句是为了把输入中每行末尾的换行符吸收掉
}
for(int i= 0; 1<3; i++) {
for(intj =0;j < 3; j++) {
putchar(str[i][j]) ;
putchar('\n') ;
}
(3) gets 输入,puts 输出
gets用来输入一行字符串(注意: gets识别换行符\n作为输入结束,因此scanf完一个整
数后,如果要使用gets,需要先用getchar接收整数后的换行符),并将其存放于一维数组 (或
二维数组的一维)中;
puts用来输出一行字符串,即将-维数组(或二维数组的一维) 在界面上输出,并紧跟一个换行。示例如下:
char str 1[20] ;
char str 2[5][10] ;
gets(str 1) ;
for(int i=0; i<3; i++) {
gets(str 2[i]) ;
}
puts(str 1) ;
for(int i= 0;i < 3; i++) {
puts(str 2[i]);
}
3.字符数组的存放方式
字符数组是由若干个char类型的元素组成,因此字符数组的每一位都是一个char
字符。
除此之外,在一维字符数组(或是二维字符数组的第二维)的末尾都有一个空字符\0,
以表示存放的字符串的结尾。
空字符\0在使用gets 或scanf输入字符串时会自动添加在输入
的字符串后面,并占用一个字符位,而puts与printf就是通过识别\0作为字符串的结尾来输出。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4f139777624e0200e9bf6ec6c97f70f2.png)
特别提醒1:结束符\0的ASCII码为0,即空字符NULL,占用一个字符位,因此开"字符数组"
的时候千万要记得字符数组的长度一定要比实际存储字符串的长度至少多1。
注意: int型数组的末尾不需要加\0, 只有char型数组需要。还需要注意\0跟空格不是同一个东西,空格的ASCII码是32, 切勿混淆。
特别提醒2:如果不是使用scanf函数的%s格式或gets函数输入字符串,(例如使用getchar),
请一定要在输入的每个字符串后加入“\0”, 否则printf和puts输出字符串会因无法识别字符
串末尾而输出一大堆乱码,如:
char str[15] ;
for(int i=0; i < 3; i++) {
str[i] = getchar() ;
puts(str) ;
return 0;
输入字符串:
T^T
输出结果会是类似下面这样的(T^T 后面全是乱码):
T^T腫?w?@
2.5.6 string.h头文件
1. strlen
strlen函数可以得到字符数组中第一个\0前的字符的个数,其格式如下:
strlen (字符数组);
char str[10];
gets (str);
int len=strlen (str);
printf ("%d\n",len);
2. strcmpO
strcmp函数返回两个字符串大小的比较结果,比较原则是按字典序,其格式如下:
strcmp (字符数组1,字符数组2)
所谓字典序就是字符串在字典中的顺序,因此如果有两个字符数组str1和str2,且满足
str 1[0...k-1]== str 2[0...k-1]、str 1[k]<str2[k],那么就说str1的字典序小于str2。例如“a”
的字典序小于“b”“aaa”的字典序小于“aab”。strcmp 的返回结果如下:
①如果字符数组1 <字符数组2,则返回一个负整数(不同编译器处理不同,不一定是-1)。
②如果字符数组1==字符数组2,则返回0。
③如果字符数组1>字符数组2,则返回一个正整数(不同编译器处理不同,不一定是+1)。
char str1[50], str2[50] ;
gets (str1) ;
gets (str2) ;
int cmp = strcmp(str1, str2) ;
if (cmp < 0) printf ("str1 < str2\n") ;
else if (cmp > 0) printf ("str1 > str2\n") ;
else printf ("str1 == str2\n") ;
3. strcpyO
strcpy函数可以把一个字符串复制给另一个字符串,其格式如下:
strcpy (字符数组1,字符数组2)
注意:是把字符数组2复制给字符数组1,这里的“复制”包括了结束符\0。
示例如下:
char strl [50],str2[50] ;
gets(str1) ;
gets(str2) ;
strcpy(str1, str2) ;
puts (str1) ;
4. strcat
strcat()可以把一个字符串接到另一个字符串后面,其格式如下:
strcat (字符数组1,字符数组2)
注意:是把字符数组2接到字符数组1后面,示例如下:
char strl [50],str2[50];
gets(str1) ;
gets(str2) ;
strcat(str1,str2) ;
puts(str1) ;
2.5.7 sscanf与sprintf
sscanf与sprintf是处理字符串问题的利器,很有必要学会它们
(sscanf可以理解为string + scanf, sprintf则可以理解为string + printf, 均在stdio.h头文件下)。
先来回顾一下scanf与printf, 如果想要从屏幕输入int型变量n并将int型变量n输出到屏幕的,则写
法是下面这样的:
scanf ("&d",&n) ;
printf ("%d",n) ;
事实上,上面的写法其实可以表示成下面的样子,其中screen表示屏幕:
scanf (screen, "&d",&n) ;
printf (screen, "8d", n) ;
可以发现,scanf的输入其实是把screen的内容以"%d"的格式传输到n中(即从左至右),
而printf的输出则是把n以"%d"的格式传输到screen上(即从右至左)。
sscanf与sprintf与上面的格式是相同的,
只不过把screen换成了字符数组(假设定义了一个char数组str[100]),如下所示:
sscanf(str, "%d",&n) ;
sprintf (str, "%d",n) ;
!!!!
sscanf 的作用是把字符数组str 中的内容以"%d"的格式写到n中,从左至右
char str[100] = "123" ;
sscanf(str, "%d", &n) ;
printf ("%d\n",n);
输出结果:
123
sprintf写法的作用是把n以"%d"的格式写到str字符数组中,从右至左
int n= 233;
char str[100] ;
sprintf (str, "%d",n);
printf ("%s\n"str);
输出结果:
233
应用是可以使用复杂的格式输入输出。
使用sscanf将字符数组str中的内容按"%d:%lf,%s"的格式写到int型变量n、double 型变量db、char 型数组str2中。
int n;
double db;
char str[100] = "2048:3.14,hello", str2[100] ;
sscanf (str, "%d:%lf, %s",&n,&db,str2);
printf("n =%d,db =%.2f,str2= %s\n", n, db, str2) ;
输出结果:
n= 2048, db =3.14, str2 = hello
使用sprintf 将int型变量n、double 型变量db、char 型数组str 2按"%d:%.2f,%s"的格式写到字符数组str中。
int n= 12;
double db = 3.1415;
char str[100], str2[100] = "good";
sprintf (str, "%d:%.2f,%s", n, db, str2) ;
printf("str = %s\n", str) ;
输出结果:
str = 12:3.14, good
最后指出,sscanf 还支持正则表达式,如果配合正则表达式来进行字符串的处理,那么
很多字符串的题目都将迎刃而解。不过正则表达式不是本书想要讨论的内容,因此不作深入
探讨,有兴趣的读者可以自己去了解。
数组倒序输出
1.先排序
2.后逆序输出