网站开发服务税收编码,软件工程的发展前景,郑州seo网站排名优化公司,做冻品的网站指针篇 指针就是地址#xff0c;地址就是指针 指针变量就是存放地址的变量 *号只有定义的时候表示定义指针变量#xff0c;其他表示从地址里面取内容 通过指针的方法使main函数中的data1和data2发生数据交换。
#include stdio.h
void chang_data(int *data1,int *da…指针篇 指针就是地址地址就是指针 指针变量就是存放地址的变量 *号只有定义的时候表示定义指针变量其他表示从地址里面取内容 通过指针的方法使main函数中的data1和data2发生数据交换。
#include stdio.h
void chang_data(int *data1,int *data2)
{int tmp;tmp *data1;*data1 *data2;*data2 tmp;}int main()
{int data1 10;int data2 20;chang_data(data1,data2);printf(data1:%d data2:%d\n,data1,data2);return 0;
}指针指向固定的区域 volatile 防止编译器进行编译优化导致原来的值发生变化 #include stdio.hint main()
{volatile unsigned int *p (volatile unsigned int *)0x0000000001234567;printf(p:%p\n,p);return 0;
}输入三个数要求不管怎么输入在输出的时候要由大到小输出用函数封装的方法 #include stdio.h
int func(int *data1,int *data2,int *data3)
{int tmp;if(*data1 *data2){tmp *data1;*data1 *data2;*data2 tmp;}if(*data1 *data3){tmp *data1;*data1 *data3;*data3 tmp;}if(*data2 *data3){tmp *data2;*data2 *data3;*data3 tmp;}}
int main()
{int data1;int data2;int data3;scanf(%d %d %d,data1,data2,data3);func(data1,data2,data3);printf(大到小%d %d %d \n,data1,data2,data3);return 0;
}1.定义一个指针变量指向数组 在C语言当中数组名不包括形参数组名代表数组中首元素的地址所以p a[0];//或者p a;这两个等价的 2. 指针的偏移偏移多少根据指针的类型int偏移四个字节char就偏移一个字节使用的指针偏移遍历数组 3.指针的访问效率是远远大于数组下标的访问效率的 int main()
{int i 0;int a[] {1,2,3};int *p;p a[0];//或者p a;for(i0;isizeof(a)/sizeof(a[0]);i){printf(a[%d] %d \n,i,*p);}p a;//让指针重新指向数组的首元素地址return 0;
}64位操作系统一个指针占8个字节所以八个字节表示一个地址 struct demo{int a;char c;
};
int main()
{struct demo *test;printf(sizeof int *:%d\n,sizeof(int *));printf(sizeof char *:%d\n,sizeof(char *));printf(sizeof double *:%d\n,sizeof(double *));printf(sizeof struct *:%d\n,sizeof(test));return 0;
}函数封装数组初始化和遍历作为形参的指针在调用函数时也会分配自己的一个地址作为指针指向传过来的地址下面传过来的main函数arr的首地址后续就是对传过来的地址进行操作 ps下面输出遍历的时候为什么不用把parr重新指向arr的首地址因为这是两个函数每个传过来的就是parr就是arr的首地址 #include stdio.hvoid Init_arr(int *parr,int len)
{int i 0;for(i0;ilen;i){*parr i;parr; }
}void Printf_arr(int *parr,int len)
{int *tmp2;for(int i 0;ilen;i){printf(arr:%d\n,*parr);parr;}}int main()
{int arr[5];int len sizeof(arr)/sizeof(arr[0]);Init_arr(arr,len);Printf_arr(arr,len);return 0;
}练习数组翻转
#include stdio.hvoid Init_arr(int *parr,int len)
{int i 0;for(i0;ilen;i){*parr i;parr; }
}void Overturn_arr(int *arr,int len)
{int i,j;int tmp;for(i0;i(len/2);i){j len-1-i;tmp *(arri);*(arri) *(arrj);*(arrj) tmp;
}
}
void Printf_arr(int *parr,int len)
{for(int i 0;ilen;i){printf(arr:%d\n,*parr);parr;}}int main()
{int arr[5];int len sizeof(arr)/sizeof(arr[0]);Init_arr(arr,len);Overturn_arr(arr,len);Printf_arr(arr,len);return 0;
}二维数组的认知 现在有一个二维数组我们可以把二维数组理解为父子数组还有数组名就是地址 int a[3][4] {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; 那么父数组的名字就是a而字数组的名字就是a[0],a[1],a[2],那么我们可以看出a的地址和a[0]的地址是一样的但是要注意他们的偏移量是不一样的a1偏移的是一整个子数组的大小a[0]1是偏移一个数组元素的大小。 a[0] 等价于 a[0][0] a[1]等价于 a[1][0] a[2]等价于 a[2][0] 那么a表示父数组的地址a[0]表示的字数组的首地址 (a)等价与a[0]的首地址因为a不可能取到整个子数组的值*(a)1就是(a[0])1 #include stdio.h
int main()
{int a[3][4] {{1,2,3,4},{5,6,7,8},{9,10,11,12}};printf(a父数组地址 IP:%p %d\n,a,*(a));printf(a[0]子数组地址 IP:%p %d\n,a[0],*(a[0]));printf(a1父数组地址偏移 IP:%p %d\n,(a1),*(a1));printf(a[0]1字数组地址偏移 IP:%p %d\n,(a[0]1),*(a[0]1));//*(a)等价与a[0]的首地址*(a)1就是(a[0])1printf(*(a)字数组地址偏移 IP:%p *(a)1的地址: %p\n,*(a),*(a)1);return 0;
}总结 数组指针就是数组的指针其实就是一个指向数组的指针。 数组指针才是等同于二维数组名 #include stdio.h
int main()
{int arr[2][3] {{1,2,3},{4,5,6}};int (*p)[3];//指向有3个元素数组的指针p arr;int i,j;printf(p%p\n,p);printf(p:%p\n,p);//这里看出地址偏移是12字节就是一个子数组的大小p arr;//这里让p重新指向二维数组名再使用p遍历数组for(i0;i2;i){for(j0;j3;j){//printf(arr:%d\n,arr[i][j]);printf(arr:%d\n,*(*(pi)j));}}return 0;
}数组指针的和二维数组的配合使用 题目用数组指针方法输出二维数组任意行列的数 #include stdio.hvoid InputNum(int *hang,int *lie)
{printf(输入行列号:\n);scanf(%d %d,hang,lie);
}int SearchNum(int (*p)[4],int hang,int lie)
{return (*(*(phang)lie));
}int main()
{int a[3][4] {{0,1,2,3},{4,5,6,7},{8,9,10,11}};int hang,lie;int data;//提示输出InputNum(hang,lie);//找到对于的数字data SearchNum(a,hang,lie);//打印出来printf(第%d行第%d列的数字为%d\n,hang,lie,data);return 0;
}函数指针就是一个指向函数入口地址的指针。 1.函数指针如果程序中定义了一个函数在编译的时候编译系统会为函数代码分配一段存储空间这段存储空间的起始地址又成为入口地址称为这个函数的指针。 2.函数名就是地址 3.如何定义一个函数指针变量int (*p)(int a,int b) 4.定义函数指针的时候要和指向的函数的类型保持一致 #include stdio.hvoid printfWeclme()
{printf(hello world\n);}int DataAdd(int data)
{return data;}int main()
{void (*p)(); //函数指针的定义int (*p2)(int data);p printfWeclme;//指向printfWeclme这个函数p2 DataAdd;(*p)();//利用函数指针调用这个函数printf(data:%d\n,(*p2)(10));return 0;
}练习用函数指针实现两个整数ab输入1 2 或者31输出ab中的大者2输出ab中的小者3输出ab之和 #include stdio.h
#include stdlib.h
int GetMax(int a,int b)
{int Max;if(ab){Max a;}else{Max b;}return Max;
}int GetMin(int a,int b)
{int Min;if(ab){Min a;}else{Min b;}return Min;
}float GetAvg(int a,int b)
{return ((float)a(float)b)/2;
}int dataHandler(int a,int b,int (*func1)(int,int))
{int ret;ret (*func1)(a,b);return ret;}float dataHandler2(int a,int b,float (*func2)(int,int))
{float ret;ret (*func2)(a,b);return ret;}
int main()
{int a 10;int b 20;int mark;int ret;float ret2;int (*func1)(int,int);float (*func2)(int,int);printf(Input:);scanf(%d,mark);switch(mark){case 1:func1 GetMax;break;case 2:func1 GetMin;break;case 3:func2 GetAvg;break;default:printf(Input error\n);exit(-1);}if(mark ! 3){ret dataHandler(a,b,func1);printf(ret:%d\n,ret);}else{ret2 dataHandler2(a,b,func2);printf(ret2:%0.2f\n,ret2);}return 0;
}数组指针 理解指针数组就是存放指针的数组数组的每一项都是指针变量 int main()
{int a 1;int b 2;int c 3;int* arr[3] {a,b,c};for(int i0;i3;i){printf(%d ,*(arr[i]));} return 0;
}定义一个函数指针数组然后进行函数调用 #include stdio.h
#include stdlib.hint GetMax(int a,int b)
{int Max;if(ab){Max a;}else{Max b;}printf(Max:%d\n,Max);return Max;
}int GetMin(int a,int b)
{int Min;if(ab){Min b;}else{Min a;}printf(Min:%d\n,Min);return Min;
}int main()
{int a 10;int b 20;int (*pfun[2])(int,int) {GetMax,GetMin};//定义了一个指向函数入口的函数指针数组每一项都指向一个函数入口地址for(int i0;i2;i){(*pfun[i])(a,b);//进行调用}return 0;
}指针函数返回指针值的函数 有3个学生每个学生对于四门成绩要求用用户输入学生序号后输出该学生的全部成绩。用函数指针实现 #include stdio.hint *getPosPenson(int pos,int (*pstu)[4])//函数指针
{int *p;p (int *)(pstupos);return p;}int main()
{int arr[3][4] {{1,2,3,4},{5,6,7,8},{45,52,63,54} };int *ppos;int pos;//学生0 1 2do{printf(输入学生012:);scanf(%d,pos);}while(pos!0 pos!1 pos!2 );ppos getPosPenson(pos,arr);for(int i0;i4;i){printf(%d ,*(ppos));}return 0;
}二级指针保存指针地址的指针
#include stdio.hint main()
{int data 10;int *p;p data;int **p2;printf(data的地址:%p\n,data);printf(p存放的地址(data的地址):%p\n,p);printf(p本身的地址:%p\n,p);p2 p;printf(p2保存的地址(p本身的地址):%p\n,p2);printf(*p2是:%p\n,*p2);//这里取到的应该是data的地址printf(**p2是:%d\n,**p2);//这里就取到data的值了return 0;
}下面对于ppos的理解
#include stdio.hvoid getPosPenson(int pos,int (*pstu)[4],int **ppos)//函数指针
{*ppos (int *)(pstupos);//*ppos取到的就是main函数一级指针ppos的地址这个指针指向了pstu这个指针的偏移地址所以main函数中的ppos就再*取一次内容就访问到里面的值了}int main()
{int arr[3][4] {{1,2,3,4},{5,6,7,8},{45,52,63,54} };int *ppos;int pos;//学生0 1 2do{printf(输入学生012:);scanf(%d,pos);}while(pos!0 pos!1 pos!2 );getPosPenson(pos,arr,ppos);//这里传过去的时ppos的地址指针的地址需要二级指针来承接for(int i0;i4;i){printf(%d ,*(ppos));}return 0;
}二级指针不能简单粗暴指向二维数组 搞懂下面这张图