目录数组名的理解使用指针访问数组为什么指针能访问数组一维数组传参的本质冒泡排序升序二级指针指针数组指针数组模拟二维数组数组名的理解数组名是数组首元素地址例外数组名只在以下两个情况下代表整个数组1. 数组名整个数组的地址2. sizeof(数组名)计算的是整个数组的大小指针类型决定了指针的差异使用指针访问数组arr[i] 编译器会自动转化成指针方式读取所以这里的[ ]只是一个操作符为什么指针能访问数组1.数组在内存中是连续存放的2.指针的运算很方便可以很方便的遍历数组一维数组传参的本质实参传递的是首元素的地址因为在主函数里面调用子函数时用f(arr);形参可以写成数组形式但本质上都是指针的形式只能在主函数里算出数组的元素个数再传到子函数里冒泡排序升序思路10个元素要进行9趟的比较n个就比较n-1次第一个元素不变其他元素和他进行比较利用嵌套循环因为每比较完一趟就少一个数字参与比较所以内循环要变化就是 j n - 1 - i 趟#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h void scan(int* arr, int sz) { for (int i 0; i sz; i) { scanf(%d, arri); } } void bubble_sort(int* arr, int sz) { for (int i 0; i sz - 1; i) { // i表示趟数 for (int j 0; j sz - 1 - i;j) { //j表示内部的比较每一趟少i次的比较 if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } } } void print(int* arr, int sz) { for (int i 0; i sz; i) { printf(%d , *(arri)); } } int main() { int arr[10] { 0 }; int sz sizeof(arr) / sizeof(arr[0]); scan(arr, sz); bubble_sort(arr, sz); print(arr, sz); return 0; }优化利用flag#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h void scan(int* arr, int sz) { for (int i 0; i sz; i) { scanf(%d, arri); } } void bubble_sort(int* arr, int sz) { for (int i 0; i sz - 1; i) { int flag 1; //假设已经满足顺序 for (int j 0; j sz - 1 - i;j) { if (arr[j] arr[j 1]) { flag 0; int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } if (flag 1) { break; } } } void print(int* arr, int sz) { for (int i 0; i sz; i) { printf(%d , *(arri)); } } int main() { int arr[10] { 0 }; int sz sizeof(arr) / sizeof(arr[0]); scan(arr, sz); bubble_sort(arr, sz); print(arr, sz); return 0; }二级指针int main(){ int a 10; int * p a; //一级指针 int ** ppa pa; //二级指针 }ppa指向的pa的类型是int *二级指针用来存放一级指针变量的地址**ppa *pa pa二级指针和二维数组没有对应关系指针数组存放指针的数组数组中的每个元素是指针类型#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h int main() { int a 1; int b 2; int c 3; int* arr[3] { a,b,c }; for (int i 0; i 3; i) { printf(%d , *(arr[i])); } return 0; }指针数组模拟二维数组#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h int main() { int arr1[5] { 1,2,3,4,5 }; int arr2[5] { 6,7,8,9,0 }; int arr3[5] { 4,5,6,7,8 }; int* arr[3] {arr1,arr2,arr3 }; for (int i 0; i 3; i) { for (int j 0; i 5; j) { printf(%d , arr[i][j]); } } return 0; }字符指针变量写法一char ch w;char * pa pc;*pc b;printf(%c\n,*pc);写法二常量字符串会放在只读数据区const char *p abcdef; //这里的赋值是将字符串中的首字符的地址赋值给pchar *p arr;数组指针指针数组是 int * arr[5]字符指针char* pc整型指针int * pa数组指针数组指针指向数组的指针存放数组的地址总结1.指针 2.是一个指向数组的指针int arr[5] { 1,2,3,4,5 };int *p arr; //这里的p是整型指针变量指向数组首元素的地址int (*p) [5] arr; //这里的p是数组指针p存放的是数组的地址//p的类型是int (*) [5] 等号右边arr的类型也是这个int arr[5];int (*p)[5] arr;二维数组传参的本质int arr[3][5] { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};二维数组的数组名也表示首地址首地址是二维数组的第一行第一行是一维数组二维数组传参本质上是传递了第一行这个一维数组的地址所以二维数组 传的形参用数组指针表示指向这个二维数组的首地址写一个打印二维数组的函数#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h //写一个打印二维数组的函数 void Print(int(*arr)[5], int r, int c) { for (int i 0; i r; i) { for (int j 0; j c; j) { printf(%d , (*(*(arr i))j)); //printf(%d , (*(arr i))[j]); } printf(\n); } } int main() { int arr[3][5] { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} }; Print(arr, 3, 5); return 0; }思路要怎么才能取出二维数组中的每个元素1. 取出二维数组中第i行第j列的元素2. 要找到第i行第j列的地址3. 得找到第i行的首地址4. 那得先找到第i行的这个行地址知道这些然后再进行倒退我们知道数组名arr是二维数组的首地址4. 那么第i行的这个行地址就是arri它指向的是一整行二维数组中每个一维数组的地址如图3. 再找到第i行的首地址用*(arri)表示它指向的是 i 行第 0 个元素的地址但它只知道这一个 格子只指向这第一个元素2. 想让它指向下一个元素的地址用*(arri)j 表示第 i 行第 j 个元素的地址1. 最后取出第i行第j列的元素的值*(*(arr i))j
指针和数组相联系
目录数组名的理解使用指针访问数组为什么指针能访问数组一维数组传参的本质冒泡排序升序二级指针指针数组指针数组模拟二维数组数组名的理解数组名是数组首元素地址例外数组名只在以下两个情况下代表整个数组1. 数组名整个数组的地址2. sizeof(数组名)计算的是整个数组的大小指针类型决定了指针的差异使用指针访问数组arr[i] 编译器会自动转化成指针方式读取所以这里的[ ]只是一个操作符为什么指针能访问数组1.数组在内存中是连续存放的2.指针的运算很方便可以很方便的遍历数组一维数组传参的本质实参传递的是首元素的地址因为在主函数里面调用子函数时用f(arr);形参可以写成数组形式但本质上都是指针的形式只能在主函数里算出数组的元素个数再传到子函数里冒泡排序升序思路10个元素要进行9趟的比较n个就比较n-1次第一个元素不变其他元素和他进行比较利用嵌套循环因为每比较完一趟就少一个数字参与比较所以内循环要变化就是 j n - 1 - i 趟#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h void scan(int* arr, int sz) { for (int i 0; i sz; i) { scanf(%d, arri); } } void bubble_sort(int* arr, int sz) { for (int i 0; i sz - 1; i) { // i表示趟数 for (int j 0; j sz - 1 - i;j) { //j表示内部的比较每一趟少i次的比较 if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } } } void print(int* arr, int sz) { for (int i 0; i sz; i) { printf(%d , *(arri)); } } int main() { int arr[10] { 0 }; int sz sizeof(arr) / sizeof(arr[0]); scan(arr, sz); bubble_sort(arr, sz); print(arr, sz); return 0; }优化利用flag#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h void scan(int* arr, int sz) { for (int i 0; i sz; i) { scanf(%d, arri); } } void bubble_sort(int* arr, int sz) { for (int i 0; i sz - 1; i) { int flag 1; //假设已经满足顺序 for (int j 0; j sz - 1 - i;j) { if (arr[j] arr[j 1]) { flag 0; int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } if (flag 1) { break; } } } void print(int* arr, int sz) { for (int i 0; i sz; i) { printf(%d , *(arri)); } } int main() { int arr[10] { 0 }; int sz sizeof(arr) / sizeof(arr[0]); scan(arr, sz); bubble_sort(arr, sz); print(arr, sz); return 0; }二级指针int main(){ int a 10; int * p a; //一级指针 int ** ppa pa; //二级指针 }ppa指向的pa的类型是int *二级指针用来存放一级指针变量的地址**ppa *pa pa二级指针和二维数组没有对应关系指针数组存放指针的数组数组中的每个元素是指针类型#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h int main() { int a 1; int b 2; int c 3; int* arr[3] { a,b,c }; for (int i 0; i 3; i) { printf(%d , *(arr[i])); } return 0; }指针数组模拟二维数组#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h int main() { int arr1[5] { 1,2,3,4,5 }; int arr2[5] { 6,7,8,9,0 }; int arr3[5] { 4,5,6,7,8 }; int* arr[3] {arr1,arr2,arr3 }; for (int i 0; i 3; i) { for (int j 0; i 5; j) { printf(%d , arr[i][j]); } } return 0; }字符指针变量写法一char ch w;char * pa pc;*pc b;printf(%c\n,*pc);写法二常量字符串会放在只读数据区const char *p abcdef; //这里的赋值是将字符串中的首字符的地址赋值给pchar *p arr;数组指针指针数组是 int * arr[5]字符指针char* pc整型指针int * pa数组指针数组指针指向数组的指针存放数组的地址总结1.指针 2.是一个指向数组的指针int arr[5] { 1,2,3,4,5 };int *p arr; //这里的p是整型指针变量指向数组首元素的地址int (*p) [5] arr; //这里的p是数组指针p存放的是数组的地址//p的类型是int (*) [5] 等号右边arr的类型也是这个int arr[5];int (*p)[5] arr;二维数组传参的本质int arr[3][5] { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};二维数组的数组名也表示首地址首地址是二维数组的第一行第一行是一维数组二维数组传参本质上是传递了第一行这个一维数组的地址所以二维数组 传的形参用数组指针表示指向这个二维数组的首地址写一个打印二维数组的函数#define _CRT_SECURE_NO_WARNINGS 1 #include stdio.h //写一个打印二维数组的函数 void Print(int(*arr)[5], int r, int c) { for (int i 0; i r; i) { for (int j 0; j c; j) { printf(%d , (*(*(arr i))j)); //printf(%d , (*(arr i))[j]); } printf(\n); } } int main() { int arr[3][5] { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} }; Print(arr, 3, 5); return 0; }思路要怎么才能取出二维数组中的每个元素1. 取出二维数组中第i行第j列的元素2. 要找到第i行第j列的地址3. 得找到第i行的首地址4. 那得先找到第i行的这个行地址知道这些然后再进行倒退我们知道数组名arr是二维数组的首地址4. 那么第i行的这个行地址就是arri它指向的是一整行二维数组中每个一维数组的地址如图3. 再找到第i行的首地址用*(arri)表示它指向的是 i 行第 0 个元素的地址但它只知道这一个 格子只指向这第一个元素2. 想让它指向下一个元素的地址用*(arri)j 表示第 i 行第 j 个元素的地址1. 最后取出第i行第j列的元素的值*(*(arr i))j