数组部分综述
- 引入:
- 数组概念:
- 一、一维数组
- 1.1一维数组的创建:
- 1.2一维数组的初始化:
- 1.2.1初始化概念:
- 1.2.2完全初始化:
- 1.2.3不完全初始化:
- 1.3字符数组的初始化:
- 1.3.1用字符初始化:
- 1.3.2用字符串初始化:
- 1.3.3字符数组用字符初始化和字符串初始化的差别:
- 1.4一维数组的使用(下标引用)
- 一维数组在内存中的存储:
- 二、二维数组
- 2.1二维数组的创建:
- 2.2二维数组的初始化
- 2.3二维数组的使用
- 2.4二维数组在内存中的存储形式
- 三、数组作为函数参数
- 冒泡排序(将降序的arr数组排为升序):
- C语言实现:
- 注意:
引入:
数组概念:
一类相同类型(整数型/小数型/字母型)元素的集合
一、一维数组
1.1一维数组的创建:
数组元素类型 数组名 [常量表达式]
- 方括号内必须是常量
- C99语法支持变长数组(方括号内可以是变量),大部分情况下不建议使用。
1.2一维数组的初始化:
1.2.1初始化概念:
创建的同时并给与相应的值。
1.2.2完全初始化:
- int arr[10]={1,2,3,4,5,6,7,8,9,10};
- int arr[]={1,2,3,4,5};等价于int arr[5]={1,2,3,4,5};
1.2.3不完全初始化:
- int arr[10]={1,2,3,4,5};
1.3字符数组的初始化:
1.3.1用字符初始化:
char ch[5]={‘a’,‘b’,‘c’}; 实际存储:‘a’,‘b’,‘c’,‘\0’,‘\0’
char ch2[]={‘a’,‘b’,‘c’}; 实际存储就是’a’,‘b’,‘c’
1.3.2用字符串初始化:
char ch3[5]=“abc”; 用字符串存储于字符数组:实际存储‘a’,‘b’,‘c’,‘\0’,‘\0’
char ch4[]=“bit”; 实际存储:‘a’,‘b’,‘c’,'\0‘仅有4个元素
##
1.3.3字符数组用字符初始化和字符串初始化的差别:
- 直观差别
用字符串初始化数组中个数有4个(除了a,b,c还有字符串结束标志’\0’)
用字符初始化的只有三个元素,没有结尾’\0’
- 解析:
打印结果:
arr2打印乱码原因:
- 在内存中,arr1用字符串初始字符数组开拓4个空间,打印遇到了字符串结束标志’\0’结束。
- 在内存中,arr2用字符初始字符数组只开拓3个空间,打印a,b,c过程中没有遇到字符串结束标志。因此会打印字符c后内存中未知的存储内容,直到读到字符串结束标志。
因此求两字符数组的长度时,也会存在差异:
字符数组arr2的长度是随机值
1.4一维数组的使用(下标引用)
下标引用操作符:[ ]
注意:
- 数组下标从0开始
- sizeof(数组名)计算的是整个数组的大小,单位字节
总结:
1:数组用下标访问
2:数组的大小可以计算得到
一维数组在内存中的存储:
%p是打印地址格式控制(以16进制打印地址)
数组元素位置相邻的相差4(字节)
因此
- 一维数组在内存中连续存放
- 随数组下标增长,地址增长
- 找到数组的首地址就可以找到整个数组
又因为数组名即为首元素地址
p++:指向数组中下一元素(在内存中跳过一个该指针变量所指向的元素类型所占的字节数)
二、二维数组
2.1二维数组的创建:
有行有列
第一个方括号内的数字代表行数,第二个数字代表列数。因此创建的这个数组为3行4列。
2.2二维数组的初始化
- int arr[3] [4]={1,2,3,4,5,6,7,8,9,10,11,12};
- 不完全初始化:int arr[3] [4]={1,2,3,4,5,6,7};后边会自动补0
- 可以看作多个一维数组 :int arr[3] [4]={{1,2},{3,4},{5,6}}每个一维数组不够时补0
注意:
行可以省略
但是列不能省略,因为列决定每行元素的个数(使没行元素个数是确定的)
2.3二维数组的使用
和一维数组相同,都是通过数组的下标来访问数组中的元素:行号从0开始,列号也从0开始
2.4二维数组在内存中的存储形式
可以观察到,换行时元素在内存中的字节数仍然相差为4.因此——————》
二维数组在内存中本质上也是连续的,每一行内部是连续的,换行时也是连续的(行与行之间也是连续的)。
只要拿到二维数组中的首元素arr[0[[0]的地址就能找到该二维数组数组所有的元素!
- 第一行的元素可以看作arr[0]+0,1,2,3
- 第二行的元素可以看作arr[1]+0,1,2,3
- 第三行的元素可以看作arr[2]+0,1,2,3
三、数组作为函数参数
冒泡排序(将降序的arr数组排为升序):
arr [ ]={9,8,7,6,5,4,3,2,1,0};
使用自定义函数bubble_sort
冒泡排序地思想:
相邻两个元素进行比较,并且可能地话需要交换!
9来到最后时候(排了一趟)
10个数字,冒泡排序需要进行9趟(9趟后,剩下的一个已经在应该的位置)
如果是n个数字,需要进行n-1趟
第一趟:10个数字待排序,9对比较
第二趟:9个数字的待排序,8对比较
第三趟:8个数字待排序,7对比较
C语言实现:
…
void bubble_sort(int arr[],int sz)
{
//1 确定趟数(sz-1趟)
int i = 0;
for (i = 0; i < sz - 1; i++)
{
//一趟冒泡排序的过程
int j = 0;
/*/
一趟中需要进行比较的对数
i=0,进行第一趟比较,比较的对数为9
i=1,进行第二趟比较,比较的对数为8
*/
for (j = 0; j < sz-1-i; j++)
{
if (arr[j] > arr[j + 1])//前大于后的话就进行交换
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };
//计算数组中元素的个数
int sz = sizeof(arr) / sizeof(arr[0]);
//冒泡排序
bubble_sort(arr, sz);
return 0;
}
注意:
数组传参的时候,传递的本质上传递的是首元素的地址(数组名是数组首元素的地址),形参arr本质上是指针。
x86平台(32位平台)
x64(64位机器)
》但是有2个例外:
(1)sizeof(数组名):这时的数组名表示的整个数组,计算的是整个数组的大小,单位是字节
(2)&数组名:这时数组名表示整个数组,取出的是整个数组的地址
打印结果:
(2)和(3)是相同的
(1)取出的是整个数组的地址,那整个数组的地址和数组首元素的地址一样?
的确一样:打印出的值一样的,意义不一样
如何显示出&arr和&arr[0](arr)的意义不同:
对&arr+1和&arr[0]+1进行比较
&arr+1比&arr大了40(16进制的28)
&arr[0]+1比&arr大了4