//2024.3.8
//二级指针
//int main() {
// int a = 10;
// int* p = &a; //p是一级指针
// int** pp = &p; //pp是二级指针
// //int ** 是二级指针类型
// //int* 说明pp指向的对象是 int*类型
// //pp+1 跳过4或8字节
// int*** ppp=&pp;
// return 0;
//}
//一般只用到二级指针
//间接访问
//指针数组是一个数组
//存放指针的数组
//char* arr[5];
//指针数组模拟二维数组
//并不是真的二维数组,二维数组是连续存放的,这里是模拟维数组,并不是连续的
//int main() {
// int arr1[] = {1, 2, 3};
// int arr2[] = {2, 3, 4};
// int arr3[] = {3, 4, 5};
// int* arr[] = {arr1, arr2, arr3};
// //打印数组
// for (int i = 0; i < 3; i++) {
// for (int j = 0; j < 3; j++) {
// printf("%d ", *(*(arr + i) + j));
// //和arr[i][j]本质等价
// }
// printf("\n");
// }
// return 0;
//}
//内存访问实际上是指针运算
//保持良好的心态哈哈哈哈哈
//字符指针变量
//int main() {
// //char ch='w';
// //char* pc=&ch;
// char arr[] = "abcd";
// char* pc1 = arr;//数组内容是可以改变的
// *pc1 = 'w';
// //char* pc2 = "abcd";//相当于把首字符的地址传给了pc2,也可以访问这个字符串,连续的
// // *pc2 = 'w';//非法的
// //常量字符串的内容不能变,不能修改
// const char* pc2="abcd";//这种写法可以将错误扼杀在编译器
// printf("%s",pc1);
// return 0;
//}
//相同常量字符串没必要修改,创建一份就可以,节省空间、
//指针数组是数组,存放指针
//数组指针变量
//是一个指针,指向数组
//int main() {
// int arr[10] = {0};
// &arr;//这是数组的地址
// int(*p)[10] = &arr;
// int* p1[10];//p1指针数组,存放指针的数组,[]结合性强
// int (*p2)[10];//p2是一个指针,指向一个数组,十个元素,类型是int
// return 0;
//}
//初始化
//去掉名字就是就是类型
//int (*p)[10]=&a;
//int (*)[10] 这就是类型
//数组指针和指针数组的类型是有差异
//int main(){
// int arr[10]={1,2,3,4,5,6,7,8,9,10};
// int (*p)[10]=&arr;
// for(int i=0;i<10;i++){
// printf("%d ",(*p)[i]);
// }
//}
//这里写的太啰嗦的
//数组指针应用在二维数组传参的时候
//二维数组传参的本质
//void print(int(*p)[5], int row, int clo);
//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;
//}
//void print(int arr[3][5], int row, int clo) {
// for (int i = 0; i < row; i++) {
// for (int j = 0; j < clo; j++) {
// printf("%d ", arr[i][j]);
// }
// printf("\n");
// }
//}
//形参写的是数组的形式
//一维数组,数组名是首元素的地址
//二维数组也是
//例外 &arr sizeof(arr) 数组名表示整个数组的地址
//二维数组传参也是首元素的地址,参数可以写成指针
//但是 二维数组的首元素地址是第一个一维数组的地址
//首元素就是第一行 地址就是第一行的地址 就是一维数组的地址 类型就是数组指针
//void print(int(*p)[5], int row, int clo) {
// //这样类型就匹配了
// for (int i = 0; i < row; i++) {
// for (int j = 0; j < clo; j++) {
// printf("%d ", *(*(p + i) + j));
// }
// printf("\n");
// }
//}
//这里二维数组的参数是数组名,是数组首元素的地址
//对于二维数组来说,二维数组的元素是一维数组
//那么二维数组名是第一个数组的地址
//这里的p相当于&arr *p相当于 *&arr也就是 抵消后就是arr 就是一维数组首元素的地址
//写法上可以写成 arr[][5]可以省略行数 不能省略列数
//学习方法 类比的思想
//二维数组想象成一维数组
//变量的思想很伟大 指针太酷了
//二级指针存放的是一级指针的地址 有根本上的区别
//关键就是数组名就是首元素的地址!!!!!!
//数组指针的应用 就是指向数组的指针
//函数指针
//指向函数的指针
//int add(int x, int y) {
// return x + y;
//}
//int main() {
// printf("%p\n", &add);
// printf("%p\n", add);
// int (*pf)(int, int) = add; //pf就是函数指针
// //形参名字可以省 根本不用
// //去掉名字就是类型
// //这里int(*)(int,int)就是类型
// //*pf必须加上括号 优先级问题不然就成为了函数名
// int arr[10] = {0};
// int (*pa)[10] = &arr; //p这是数组指针
// return 0;
//}
//函数名和&函数名也是一样的
//二者没有区别都是函数的地址 意义相同
//int main() {
// int(*p)(int, int) = add;
// int a = 8;
// int b = 9;
// printf("%d\n", (*p)(a, b));
// printf("%d\n", p(a, b));
// return 0;
//}
//通过函数指针来调用函数也是可以的
//当然也要传参
//什么时候应用呢 以后再说
//等待使用场景出现
//typedef类型重定义关键字
//typedef unsigned int uint;
//typedef int* p;
//typedef int(*pf_t)[5];
//pf_t就是类型名
//typedef void(*pf_t)(int)
//pf就是类型
//用#define不行
//#define P int*
不行
//int* p1,p2;
这样的话 p2是整型
//这样做不够直接
//函数指针数组
//int* arr[5];指针数组
//存放函数指针的数组
//int add(int x, int y) {
// return x + y;
//}
//int sub(int x, int y) {
// return x - y;
//}
//int mul(int x, int y) {
// return x * y;
//}
//int div(int x, int y) {
// return x / y;
//}
//int main() {
// int a=3;
// int b=5;
// int (*pfarr[])(int, int) = {add, sub, mul, div};
// //pfarr是函数指针数组,存的是函数指针
// for (int i = 0; i < 4; i++) {
// printf("%d ", pfarr[i](a,b));//可以不解引用
// }
// return 0;
//}
//转移表
//计算器
//完成整数的加减乘除运算
指针2,文件丢了烦人,删不掉烦人,重装吧,毁灭吧
最新推荐文章于 2024-09-14 22:25:23 发布
本文详细解释了C语言中的一级、二级指针,指针数组、字符指针,以及数组指针和函数指针的概念。通过实例展示了内存访问、指针运算和不同类型的指针在实际编程中的应用,包括数组指针在二维数组传递参数时的作用。
摘要由CSDN通过智能技术生成