1.数值名的理解
数组名属于地址,而且是数组首元素的地址
# include <stdio.h>int main (){int arr[ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };printf ( "&arr[0] = %p\n" , &arr[ 0 ]);printf ( "arr = %p\n" , arr);return 0 ;}
输出的结果:
由上图可知数组名就是数组首元素的地址
以下有特殊的两种情况:
• sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节
• &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)
2.使用指针访问数组
如下代码:
# include <stdio.h>int main (){int arr[ 10 ] = { 0 };// 输⼊int i = 0 ;int sz = sizeof (arr)/ sizeof (arr[ 0 ]);// 输⼊int * p = arr;for (i= 0 ; i<sz; i++){scanf ( "%d" , p+i);//scanf("%d", arr+i);// 也可以这样写}// 输出for (i= 0 ; i<sz; i++){printf ( "%d " , p[i]);}return 0 ;}
其中*(p+i) = p[i];
arr[i] = *(arr+i);
3.一维数组传参的本质
数组传参的时候本质上传递的是数组首元素的地址
void test ( int arr[]) // 参数写成数组形式,本质上还是指针{printf ( "%d\n" , sizeof (arr));}void test ( int * arr) // 参数写成指针形式{printf ( "%d\n" , sizeof (arr)); // 计算⼀个指针变量的⼤⼩}int main (){int arr[ 10 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };test(arr);return 0 ;}
总结:⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
4.冒泡排序
冒泡排序的核⼼思想就是:两两相邻的元素进⾏⽐较
如下代码就是冒泡排序:
// ⽅法 1void bubble_sort ( int arr[], int sz) // 参数接收数组元素个数{int i = 0 ;for (i= 0 ; i<sz -1 ; i++){int j = 0 ;for (j= 0 ; j<sz-i -1 ; j++){if (arr[j] > arr[j+ 1 ]){int tmp = arr[j];arr[j] = arr[j+ 1 ];arr[j+ 1 ] = tmp;}}}}int main (){int arr[] = { 3 , 1 , 7 , 5 , 8 , 9 , 0 , 2 , 4 , 6 };int sz = sizeof (arr)/ sizeof (arr[ 0 ]);bubble_sort(arr, sz);for (i= 0 ; i<sz; i++){printf ( "%d " , arr[i]);}return 0 ;}// ⽅法 2 - 优化void bubble_sort ( int arr[], int sz) // 参数接收数组元素个数{int i = 0 ;for (i= 0 ; i<sz -1 ; i++){int flag = 1 ; // 假设这⼀趟已经有序了int j = 0 ;for (j= 0 ; j<sz-i -1 ; j++){if (arr[j] > arr[j+ 1 ]){flag = 0 ; // 发⽣交换就说明,⽆序int tmp = arr[j];arr[j] = arr[j+ 1 ];arr[j+ 1 ] = tmp;}}if (flag == 1 ) // 这⼀趟没交换就说明已经有序,后续⽆序排序了break ;}}int main (){int arr[] = { 3 , 1 , 7 , 5 , 8 , 9 , 0 , 2 , 4 , 6 };int sz = sizeof (arr)/ sizeof (arr[ 0 ]);bubble_sort(arr, sz);for (i= 0 ; i<sz; i++){printf ( "%d " , arr[i]);}return 0 ;}
5.二级指针
指针变量作为变量,其变量的地址便储存在二级指针内
对于⼆级指针的运算有:
• *ppa 通过对ppa中的地址进⾏解引⽤,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 20 ;*ppa = &b; //等价于pa = &b
• **ppa 先通过 *ppa 找到 pa ,然后对 pa 进⾏解引⽤操作: *pa ,那找到的是 a .
**ppa = 30 ;// 等价于 *pa = 30;// 等价于 a = 30;
6.指针数组
指针数值是存放指针的数组,指针数组的每一个元素都是用来存放地址(指针)的。
如下图:
指针数组的每一个元素是地址,又可以指向一块区域。
7.指针数组模拟二维数组
如下面代码所示:
# include <stdio.h>int main (){int arr1[] = { 1 , 2 , 3 , 4 , 5 };int arr2[] = { 2 , 3 , 4 , 5 , 6 };int arr3[] = { 3 , 4 , 5 , 6 , 7 };// 数组名是数组⾸元素的地址,类型是 int* 的,就可以存放在 parr 数组中int * parr[ 3 ] = {arr1, arr2, arr3};int i = 0 ;int j = 0 ;for (i= 0 ; i< 3 ; i++){for (j= 0 ; j< 5 ; j++){printf ( "%d " , parr[i][j]);}printf ( "\n" );}return 0 ;}
可以通过下图更好的理解该代码:
上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的。