思考:了解二维数组在内存中是连续存放的有什么作用?
1、在说int arr[][4]; 这个例子的时候,我们说二维数组行可以省略,列不可以省略。为什么列不可以省略呢?
当列确定的时候,我们才能知道一行有多少个元素,才能知道第二行从哪里开始,否则的话,这个二维数组就不是确定的
2、只有当二维数组是连续存放的方式,当我拿到二维数组首元素地址的时候,就可以依次访问到这个数组的所有元素。
二维数组arr[3] [4]可以看作由三个一维数组组成,这三个一位数组的数组名分别为arr[0], arr[1], arr[2]
数组通过数组名 + [下标]访问其成员,由此我们可知arr[0], arr[1], arr[2]也是数组名。
该二维数组的数组名:arr
二维数组的第一行数组名:arr[0]
二维数组的第二行数组名:arr[1]
二维数组的第三行数组名:arr[2]
三、数组作为函数参数
冒泡排序思想
我们在写代码的时候,往往会将数组作为参数传给函数,比如:我们要**实现一个冒泡排序函数将一个整型数组排序。**那我们将这样使用函数:
冒泡排序的思想:两两相邻的元素进行比较,并且可能的话需要交换。
一趟解决一个数字的排序问题,第一趟最大值9出现到最右侧,第二趟8到右侧第二位
10个数字,需要进行9躺冒泡排序
n个数字,需要进行 n - 1躺
一趟冒泡排序内部:
第一趟:10个数字待排序,9对比较
第二趟:9个数字待排序,8对比较
第三趟:8个数字待排序,7对比较
……
第九趟:2个数字待排序,1对比较
代码实现:
#include<stdio.h> void print(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } void bubble_sort(int arr[], int sz) { int i = 0; int j = 0; for (i = 0; i < sz - 1; i++)//确定冒泡排序的趟数 { for (j = 0; j < sz - 1 - i; j++)//确定每一趟两两比较的次数 { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; int sz = sizeof(arr) / sizeof(arr[0]); printf("排序前:"); print(arr, sz); //冒泡排序,进行升序排列 bubble_sort(arr, sz); printf("排序后:"); print(arr, sz); return 0; }
冒泡排序法优化:当我们要排序的数组本身就是有序的时候,或者说数组排序的时候排好前几项就已经有序了,这时候按照上面的方法还要进行两两比较,效率就比较低,对此我们进行想要的优化。
#include<stdio.h> void print(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } void bubble_sort(int arr[], int sz) { int i = 0; int j = 0; for (i = 0; i < sz - 1; i++)//确定冒泡排序的趟数 { int flag = 1;//用于判断比较是否继续 for (j = 0; j < sz - 1 - i; j++)//确定每一趟两两比较的次数 { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; flag = 0; } } if (flag == 1) { break; } } } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; int sz = sizeof(arr) / sizeof(arr[0]); printf("排序前:"); print(arr, sz); //冒泡排序,进行升序排列 bubble_sort(arr, sz); printf("排序后:"); print(arr, sz); return 0; }
四、思考:数组名到底是什么?
我们经常会说数组名是首元素地址,那么这个说法对不对呢?这里我们可以验证一下。
可以看到两者一样,所以数组名是首元素地址。
但是要排除以下两种情况:
①sizeof(数组名)-- - 数组名表示整个数组-- - 计算的是整个数组的大小单位是字节
② &数组名-- - 数组名表示整个数组-- - 取出的是整个数组的地址
除上述两种情况以外,其余情况数组名均表示首元素地址!
数组地址和数组首元素地址有什么区别?
两者的地址值是一样的,但是含义和使用不同。
数组地址 + 1表示跳过整个数组,首元素地址 + 1表示跳到第二个元素。
& arr + 1 与 & arr 相差40个字节
arr + 1 与 arr相差4个字节
三维数组及多维数组
三维数组具有高、宽、深的概念,或者说行、列、层的概念,即数组嵌套数组达到三维及其以上。是最常见的多维数组,由于其可以用来描述三维空间中的位置或状态而被广泛使用。
三维数组就是维度为三的数组,可以认为表示对该数组存储的内容使用了三个独立参量去描述,但更多的是认为该数组的下标是由三个不同的参量组成的。三维数组又被认为是二维数组的数组,而二维数组也可以认为是一维数组的数组。
数组这一概念主要用在编写程序当中,和数学中的向量、矩阵等概念有一定的差别,主要表现在数组内的元素可以是任意的相同数据类型,包括向量和矩阵。
对数组的访问一般是通过下标进行的。在三维数组中,数组的下标是由三个数字构成的,通过这三个数字组成的下标对数组的内容进行访问。
多维数组 三维或者三维以上的数组。
定义方式:type name[size1][size2]…[sizeN];
例如,下面的声明创建了一个三维 4 . 3 . 2 整型数组:
int threedim[4][3][2];