指针中容易混淆的概念以及常见笔试题
Posted 不倒翁*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针中容易混淆的概念以及常见笔试题相关的知识,希望对你有一定的参考价值。
C语言指针
文章目录
1.字符串指针
注:注意代码中的注释
- 注: void* 类型的指针可以接收任意类型的指针
- void 类型的指针不能进行解引用的操作,也不能进行加减整数的操作*
int main()
char arr1[]="abcdef";
char arr2[]="abcdef";
char* p1="abcdef"; //常量字符串 不能修改
char* p2="abcdef";
if(arr1==arr2) //arr相当于数组首地址 所以不相等
printf("相等\\n");
else
printf("不相等\\n");
if(p1==p2) //指针里面放的常量字符串 ,所以相等
printf("相等\\n");
else
printf("不相等\\n");
2.指针数组
指针数组是数组,存放指针的数组
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[]=arr1,arr2,arr3;
int i=0,j=0;
for(i=0;i<3;i++)
for(j=0;j<5;j++)
printf("%d ",*(parr[i]+j))
printf("\\n");
return 0;
打印结果为:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
3.数组指针
数组指针—指向数组的指针—存放数组的地址
int* p1[10]; 指针数组
int (*p2)[10] 数组指针
arr表示的是数组首元素的地址
&arr表示的是数组的地址,而不是数组首元素的地址
int mian()
char* arr[5];
char* (*p)[5]=&arr; //&arr取出的是一个数组的地址
return 0;
int main()
int arr[5]=1,2,3,4,5;
int (*p)[5]=&arr;
int i=0;
// for(i=0;i<5;i++)
//
// printf("%d ",*(*p+i)); //*p=arr
//
//或者下面这种写法
for(i=0;i<5;i++)
printf("%d ",(*p)[i]); //打印出1,2,3,4,5
return 0;
#include <stdio.h>
void print1(int arr[3][5],int x,int y)
int i,j;
for(i=0;i<x;i++)
for(j=0;j<y;j++)
printf("%d ",arr[i][j]);
printf("\\n");
void print2(int (*p)[5],int x ,int y)
int i,j;
for(i=0;i<x;i++)
for(j=0;j<y;j++)
printf("%d ",*(*(p+i)+j)); //*(p+i)代表每行首元素的地址
printf("\\n");
int main()
int arr[3][5]=1,2,3,4,5, 2,3,4,5,6, 9,3,4,5,6;
print1(arr,3,5);
print2(arr,3,5); //传的是一维数组的地址
//数组名arr代表首原素的地址
//但是二维数组的首元素是二维数组的第一行,所以这里传递arr,其实相当于第一行的地址,是一维数组的地址,可以用数组指针来接收
return 0
下面看看几种常见的写法:
int arr[5]; //arr是一个5个元素的整形数组
int* parr1[10]; //parr是一个数组,数组有10个元素,每个元素的类型是int*,parr1是指针数组
int (*parr2)[10]; //parr2是一个数组,数组有10个元素,每个元素的类型是int, parr2是数组指针
int (*parr3[10])[5]; //parr3是一个数组,该数组有10个元素,每个元素是一个数组指针,该数组指针指向的数组有5个元素,每个元素是int.
4.数组参数,指针参数
二维数组传参可以省略行,但不能省略列.
二级指针传参可以传哪些参数: 如下代码中的三种都行
void test(char **p)
int main()
char c = 'b';
char*pc = &c;
char**ppc = &pc;
char* arr[10];
test(&pc);
test(ppc);
test(arr);//Ok?
return 0;
5.函数指针 - 指向函数的指针
函数指针 - 指向函数的指针----存放函数地址的指针
int Add(int x ,int y)
int z = x+y;
return z;
int main()
int a = 10 ;
int b = 20 ;
//&函数名和函数名都是函数的地址
int (*p)(int, int)=Add;// 把add的地址传给了p
printf("%d\\n", (*p)(2,3));//5
printf("%d\\n",p(2,3)); //5
//*可以加也可以不加
return 0;
void (* signal(int ,void(*)(int)))(int) (1)
typedef void(*pfun)(int); (2)
pfun signal(int , pfun) (3)
(2)(3)等效为(1)
6.函数指针数组
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 i = 0;
//下面这个函数指针数组可以存放4个函数的地址
int (*parr[4])(int , int ) = Add , Sub , Mul , div
for(i=0;i<4;i++)
printf("%d\\n",parr[i](2,3)); //5 -1 6 0
return 0;
//char* my_strcpy(char* dest , const char* src)
//1.写一个函数指针pf,能够指向my_strcpy
char* (*pf)(char* , const char*)
//2.写一个函数指针数组,能够存放4个my_strcpy函数的地址
char* (*fp[4])(char* , const char*)
函数指针数组的用途 : 转移表
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 ;
void meun()
printf("**********************\\n");
printf("**** 1.Add 2.Sub ****\\n");
printf("**** 3.Mul 4.Div ****\\n");
printf("****** 0.exit ********\\n");
printf("**********************\\n");
int main()
int x =0 ,y=0;
int input = 0;
meun();
printf("请选择哪种算法\\n:");
scanf("%d",&input);
printf("请输入两个数:> ");
scanf("%d%d",&x , &y);
int (*parr[5])(int ,int )=0,Add,Sub,Mul,Div;
do
if(input>=1&&input<=4)
printf("%d\\n",parr[inpnt](x,y));
else if(input==0)
printf("退出\\n");
else
printf("选择错误\\n");
while(input)
return 0;
//注: 这题也可以用swich case ,但代码长度较长
小结
int Add(int x , int y)
return x+y;
int main()
//指针数组
int* parr[4];
//数组指针
int* (*P)[4]=&parr;
// 函数指针
int (*p)(int ,int )=Add;
//函数指针的数组
int (*parr[4])(int , int)=Add,Sub,Mul,Div;
//指向函数指针的数组的指针
int (*(*parr)[4])(int , int);
-
回调函数: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针作为参数传递给另一个函数,当这个指针被用来调用其他所指向的函数时,我们就是说这是一个回调函数.回调函数不是由该函数的现实方直接调用,而是在特定的事件或条件发生时有另一方调用的,由于对该事件或条件进行响应. 如 :
void cola (int (*fp)(int ,int))
cola(Add);
//cola 函数能Add函数的地址void print(char* str) printf("%s",str) ; void test(void(*p)(char *)) printf("TEST "); p("hello world"); int main() test(print); //输出:TEST hello world return 0 ;
7.库函数qsort的用法: qsort(void* p,int num1 , int num2 , int (cmp)(counst void e1, counst void* e2) )
第一个参数 : 待排序数组首元素的首地址
第二个参数 : 待排序数组元素的个数
第三个参数 : 待排序数组每个数组元素的大小—单位为字节
第四个参数 : 函数指针–比较两个元素函数的地址,这个函数要自己实现
//自己实现一个qsort排序
struct stu
char name[10];
int age;
;
void swap(char *p1 ,char *p2, int witdh)
int i= 0;
for(i=0;i<witdh;i++)
char temp=*p1;
*p1=*p2;
*p2=temp;
p1++;
p2++;
void bubble_sort(void* base, int sz ,int width , int (*cmp)(void *e1, void *e2))
int i=0;
//趟数
for(i=0;i<sz-1;i++)
int j=0 ;
//每一趟比较的对数
for(j=0;j<sz-1-i;j++)
//两个元素的比较 得到两个元素的首地址
if( cmp((char*)base+j*width , (char*)base+(j+1)*width ) >0 )
//交换
swap((char*)base+j*width , (char*)base+(j+1)*width ,width);
int cmp_init(void* p1,void* p2)
return *(int*)p1-*(int*)p2;
void test1()
int i=0;
int arr[]=9,8,7,6,5,4,3,2,1,0;
int sz=sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr,sz,sizeof(arr[0]),cmp_init);
for(i=0;i<sz;i++)
printf("%d",arr[i]);以上是关于指针中容易混淆的概念以及常见笔试题的主要内容,如果未能解决你的问题,请参考以下文章