数组
一、总结内容(个人对本单元的整体理解):
数组就是一个解题的工具,要储存若干字符、数、字符串 时,运用数组不失为一种好方法。因为看了很多一题多解的解法,数组就是方便平行存储读取(输入输出某数组)、排序(省去了挨个定义变量的工作)、标记(在实际情况是两种情况(男女 ,真假等),用bool型定义占用内存小)。一维数组是一个大类里的若干情况,二维数组是多个平行的大类里的一维数组(类似于m*n表格 或是 m*n的矩阵 或是 一维数组套着一维数组)。感觉数组就是为了让解题定义的未知量表示更简便,综合前面的顺序分支循环的方法来解题。
二、 干什么用的(应用举例)
1.易错点
数组的定义方式和初始化
数据类型 数组名[常量表达式];
int a[6];
int a[4+6];
|*不合法
int n=10;
int a[n];*|
//区别于
int n=5,a[10];
a[n]=20;
注:数组定义时的方括号中只能是常量或常量表达式,引用数组元素可以使常量,变量或表达式。
int a[3] = {1,2,3};
int a[]={1,2,3,4,5,6}
int a[6]={0} // 等价于 int a[6]={0,0,0,0,0,0}
注:只能给数组整体赋0,不能给数组整体赋非零值,非零值只能逐个输入。
易混:
数组不赋初值时(即 整个数组未初始化 或 通过键盘只给部分元素赋值),其值随机。
&&
对数值型数组中的一部分元素列举初值,未赋值的部分是0。
int a[4]={3,2,1}//等价于a[0]=3;a[1] =2;a[2]=1;a[3]=0;
注:不能用变量定义数组维数,但可以用常变量;
数组元素的个数确定,数组的所有元素类型相同;
数组在编译时分配连续的内存,单独写a是指a[0],数组名a表示内存首地址,a是地址常量(单独写a的地址也是a[0]的地址)。
内存字节数=数组元素个数*sizeof(元素数据类型)。
二维数组
二维数组的行序优先,二维数组赋值时也是按行赋值
EX1:
b[1][2]=a[1][2]/2;(可)
int a[][3]={1,2,3,4,5,6};(可)
int a[2][3]={{1,2,3},{1,2,3}}//二维数组是按行赋值
EX2:
int a[2][3]={{1,2},{4}}//等价于{{1,2,0},{4,0,0}}
a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
---|---|---|---|---|---|
1 | 2 | 0 | 4 | 0 | 0 |
int a[2][3]={{},{4}}//等价于{{0,0,0},{4,0,0}}
a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
---|---|---|---|---|---|
0 | 0 | 0 | 4 | 0 | 0 |
int a[2][3]={1,2,3,4,5,6}//等价于{{1,2,3},{4,5,6}}
a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 |
int a[2][3]={1,2,3}//等价于{{1,2,3},{0,0,0}}
a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
---|---|---|---|---|---|
1 | 2 | 3 | 0 | 0 | 0 |
字符数组
EX1:
char ch[]={‘h’,‘e’,‘l’,‘l’,‘o’}//等价于char ch[]={“hello”}等价于char ch[]="hello"等价于 char ch[]={‘h’,‘e’,‘l’,‘l’,‘o’,’/0’}
char ch[5]={"12"}//等价于char ch[5]={'1','2','\0','\0','\0'}
char ch[]={'c','c',}//长度为3
char str[20];
str=“hello world”;
2.重难点
冒泡排序(相邻两个数的比较)
n个数升序
for(int j=1;j<n;j++)//一共会走n-1遍,相邻比较的数从一开始的n个到最终的2个
for(i=0;i<n-j;i++)//走第j遍时要选出第j个小数
if(a[j]>a[j]+1)
swap(a[j],a[j+1]);
▶只要相邻的两个数是逆序,两个元素就会互换。
▶在过程中,每一趟结束之后都可以认为是把冒泡的那个数单独拿出来了,其他元素的相对位置不变
大致过程如图
3.重难点:
选择排序(第j个数和后面所有数的比较)(打擂台就是只走第一趟选最大maxx)
n个数升序
for (int j=1;j<n;j++)//一共会走n-1遍,第j个数和后面的所有数进行大小比较
for(int i=j+1;i<=n;i++)//第j个
if(a[j]<a[i])
swap(a[j],a[i]);
▶要挑第i大的数时,只要后面的数比a[i]大,两个元素就会互换
▶在过程中,每一趟结束后可以认为是比较的所有数中第j大的那个数和原排列中第j个数互换了位置。
大致过程如图
打擂台(有n组人,每组m个人,选出总冠军即n行m列)
maxx=a[0][0];
for(int i=0;i<=n;i++)//第i组
for(int j=0;j<=m;j++)//第i组第j个人
if(a[i][j]>maxx) maxx=a[i][j],row=i,colum=j;//最大的数,行标,列标
cout<<"总冠军"<<maxx<<endl;
4.与矩阵转置换行换列有关的题关注i,j(行标列标)
5.字符数组
注:字符数组的一个元素只能放一个字符,不能用字符语句整体赋值
检测到’\0’才结束,即’\0’也在字符数组中,定义时必须留出’\0’的位置
EX1:输入输出
for(int i=1;i<=n;i++)
str[i]=cin.get();//相似于cin>>str[i]
(输入时要求字符串的长度小于数组的长度)
cout<<str[i];
EX2:字符串整体输入
char s[100]
cin.getline(s,80)//键盘输入一行字符
头文件cstring或string.h
字符数组按字典序比较大小
strcat(str1,str2) str1必须足够大
strcpy(str1,str2) 把2复制到1中 ,而不能用str2=str1
strcmp(str1,str2) 字符串的比较不能用"== ",必须用strcmp
6.重点:
string
注:
①必须包含头文件string
②可以用=赋值,==比较,+串联;
字符串的输入方法
cin.get() | cin>>str | gets(str) | cin.getline(str,100) |
---|---|---|---|
不会自动加’\0’ | 自动加’\0’ | 自动加’\0’ | 自动加’\0’ |
要用到循环 | 输入时以回车或空格结束 | 输入时以回车结束 |
三.这段时间的感悟
思路真的很重要,因为看了别的参考书的缘故,我现在就觉得简直是智力知识的双重碾压,相比于人家书上简单的设个变量、定义个数组、技巧性的转化一下、思路条理清晰,我自己的想的那种模拟过程的思路简直就是可以用”蠢笨”二字形容,再比如昨天写综合的那个不吉利日期的题,我定义了三个函数,写了那么多行,最后发现还是出错了,坚信肯定有比我这思路更更简单的方法,而我自己长篇大论写到最后越绕越迷糊••••••
我觉得我出现了眼高手低的问题(看一遍,知道大体什么思路就翻页了,等到真正要用的时候,脑子里只对以前看过的那个思路有个大体的感觉,动手具体写出来的时候要思考好一会儿),昨天晚上看书就变成了,看完之后自己再写一遍。
这段时间最大的感悟就是心静才有思路,心静才能学下去。最近的一个周状态不好,有些急,生活上又碰到了很多糟心事,本来定的每天写oj上题的计划也被打乱,周六在电阅从中午12点待到晚上8点,心情很不好,各种急躁,没想法没思路,真的是在含着泪写着题,到周日才全部做完。
以前熬大夜写oj题的时候,有人就和我说当成一种习惯就好,我不听,生活上碰到的好多不好的事再加上心情急躁知识不入脑子,不如意的感觉凑到一起,对C++有点疲了,心态有些崩••••••
准备不去管那些不好的事情,调整学习计划,晚自习看书,白天写题,把数分高代c+的复习安排好,努力调整心态,做自己,毕竟快到期末考试了,毕竟我还有个小目标,毕竟生活还要过下去•••••