壹 数组名的理解
“数组名是首元素地址”该话本身并没有什么错误,但是值得注意两个意外:
①:sizeof(数组名):
sizeof 中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
②:&数组名:
这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的),除此之外,任何地方使用数组名,数组名都表示首元素的地址。
贰 使用指针访问数组
叁 一维数组传参的本质
交换值形,实参访问的不是一块空间,但数组传参时访问的是同一个首地址
数组传参是降级变成首元素地址了,在函数内部无法求数组长度,只能在主函数里求
数组传参本质上传递的是数组首元素地址,所以函数形参的部分理论上应该使用指针变量来接收首元素的地址,那么在函数内部我们写 sizeof(arr) 计算的是一个地址的大小(单位字节)而不是数组的大小(单位字节)。正是因为函数的参数部分本质是指针,所以在函数内部是没办法求数组元素的个数的。
总结:一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
肆 冒泡排序
核心思想:相邻的两个元素比较,如果不满足顺序就交换。
伍 二级指针
指针变量也是指针
一级指针:
char* pc;
int* pi;
double* pd;
二级指针:
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a; //取出a的地址
int ** pp = &p;
return 0;
}
陆 指针数组
数组是“指针数组”的主语
类比:
整型数组——存放整型数据的数组(数组中的每个元素是整型类型)
字符数组——存放字符数据的数组(数组中的每个元素是字符类型)
指针数组——存放指针的数组(数组中的每个元素是指针类型)
- int arr[10]; 整型数组
- char ch[5]; 字符数组
- double data[4]; 浮点型数组
此时假设要求我们写一个数组,数组有四个元素,每个元素是整型指针
int* arr[4] //每个元素是整型指针,所以是指针数组
float* pf[6];
float* pf = &a;
此时有一个整型变量 a(int),但 pf 是 float 型指针变量,所以 pf 只能指向 float 型的变量,
所以即便 pf 接收到了整型变量 a 的首地址,但是因为指针 pf 只能指向 float 型的变量,所以 pf 没有目标,就得到了0.
柒 指针模拟二维数组
模拟出二维指针效果,但不是二维指针!
arr1,2,3 在内存中不是连续存放的
arr[i][j] ---> *(*(arr + i) + j)
void Print(int(*p)[5], int r, int c)
{
int i = 0, j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("%d ", *(*(p + 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;
}