C语言:指针进阶

  1. 字符指针
  2. 数组指针
  3. 指针数组
  4. 数组传参和指针传参
  5. 函数指针
  6. 函数指针数组
  7. 指向函数指针数组的指针
  8. 回调函数
  9. 指针和数组面试题解析

 

  • 字符指针

    • 在指针的类型中有一种指针类型为字符指针 char*
    • 一般使用
char* p="abcde"; //常量字符串,不能被改
//p存放的是字符串的起始地址

准确写法是加const修饰
const char* p="abcde";

 面试题:

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	const char* p1 = "abcdef";
	const char* p2 = "abcdef";   //p1,p2存的是同一个地址
	if (arr1 == arr2)
	{
		printf("hehe\n");
	}
	else
	{
		printf("haha\n");
	}
	if (p1 == p2)
	{
		printf("hehe\n");
	}
	else
	{
		printf("haha\n");
	}
	return 0;
}
  • 数组指针

    • 是指针,能够指向数组的指针,用来存放数组的地址   int(*p)[N]=&arr;   *p==arr
    • 	char* parr[5];
      	char* (*pa)[5] = &parr;

    • 基本用法;

      • #include <stdio.h>
        
        //参数是数组
        void print1(int arr[3][5],int x,int y)
        {
        	int i = 0;
        	int j = 0;
        	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 = 0;
        	for (i = 0; i < x; i++)
        	{
        		int j = 0;
        		for (j = 0; j < y; j++)
        		{
        			//arr[i] == *(arr+i) == *(p+i) == p[i]
        			//*(p+i) == p[i]     *(p[i]+j) == p[i][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} };
        	print1(arr, 3, 5);//arr数组名   首元素地址    第一行的地址
        	print2(arr, 3, 5);
        	return 0;
        }

  • 指针数组

    • 是数组,用来存放指针的数组
  • #include <stdio.h>
    
    int main()
    {
    	int i = 0;
    	int j = 0;
    	int arr1[] = { 1,2,3,4,5 };
    	int arr2[] = { 2,3,4,5,6 };
    	int arr3[] = { 3,4,5,6,7 };
    	int* arr[] = { arr1,arr2,arr3 };
    	for (i = 0; i < 3; i++)
    	{
    		for (j = 0; j < 5; j++)
    		{
    			printf("%d\t", *(arr[i] + j));
    		}
    		printf("\n");
    	}
    	return 0;
    }

     

  • 数组传参和指针传参

    • 一维数组传参可以用数组或指针,数组大小可以省略
      • void test( int arr[ ] )   void test( int* arr )
    • 二维数组传参可以用二维数组或数组指针,数组的行可以省略,列不可以省略
      • void test( int arr[ ][ N ] )    void test( int (*arr)[ 5 ])
    • 一级指针传参用一级指针
      • int a = 10;
        int* p = &a;
        test(p);
        
        
        
        void test(int* p)
        {
            
        }

         

    • 二级指针或一级指针数组传参用二级指针
    • int n = 10;
      int* p = &n;
      int** pp = &p;
      test(pp);
      test(&p);
      
      int* arr[10];
      test(arr);
      
      
      
      void test(int** ptr)
      {
          
      }

       

  • 函数指针

    • 是指向函数的指针,存放函数的地址   //&函数名 和 函数名 都是函数的地址
    •  定义:返回类型 (*p)(参数类型)      p就是函数指针
    • #include <stdio.h>
      
      int add(int x,int y)
      {
      	int z = x + y;
      	return z;
      }
      int main()
      {
      	int (*pa)(int, int) = add;
          //两种都可以
      	printf("%d\n", (pa)(2, 3));
      	printf("%d\n", (*pa)(2, 3));//*没什么作用
      	return 0;
      }

       

    • //代码1
      //void (*)() 0 把0强制类型转换成 void(*)() 函数指针类型,0就是一个函数地址
      //调用0地址该处的函数
      (* (void (*)())0 )();
      
      
      
      //代码2
      //signal是一个函数声明
      //signal返回类型是一个函数指针
      void (*  signal(int,void(*)(int))  )(int);
      
      typedef void(* pfun_t)(int);
      pfun_t signal(int,pfun_t);
      
      
      typedef unsigned int uint;
      

       《C陷阱和缺陷》

  • 函数指针数组

    • 存放函数指针的数组
      • 用途:转移表 

      • #include <stdio.h>
        
        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 menu()
        {
        	printf("********************\n");
        	printf("***1.add    2.sub***\n");
        	printf("***3.mul    4.div***\n");
        	printf("****** 0.exit ******\n");
        }
        
        int main()
        {
        	int input = 0;
        	int x = 0;
        	int y = 0;
            //pfarr 是一个函数指针数组——————转移表
        	int (*pfarr[5])(int, int) = {0, add,sub,mul,div };
        	do
        	{
        		menu();
        		printf("请选择模式:\n");
        		scanf_s("%d", &input);
        		if (input >= 1 && input <= 4)
        		{
        			printf("请输入两个操作数:\n");
        			scanf_s("%d%d", &x, &y);
        			int ret = pfarr[input](x, y);
        			printf("结果是:%d\n", ret);
        		}
        		else if (input == 0)
        		{
        			printf("退出.......\n");
        		}
        		else
        		{
        			printf("输入错误,请重新选择:\n");
        		}
        	} while (input);
        }

         

  • 指向函数指针数组的指针

    • 指向函数指针数组的指针是一个指针,指针指向一个数组,数组元素都是函数指针
    • int arr[10] = { 0 };
      	//指针数组
      	int (*p)[10] = &arr;
      	//函数指针的数组
      	int(*parr[10])(int, int);
      	//pparr是一个数组指针,指针指向的数组有10个元素,元素类型是函数指针
      	int(*(*pparr)[10])(int, int) = &parr;

       

  • 回调函数

    • 回调函数就是一个通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数,回调函数不是由该函数直接调用,而是在特定的事件或条件发生时由另外一方调用,用于对该事件条件的响应
    • #include <stdio.h>
      
      //回调函数
      void print(char* str)
      {
      	printf("hehe:%s\n", str);
      }
      
      void test(void (*p)(char*))
      {
      	printf("test\n");
      	p("bit");
      }
      
      int main()
      {
      	test(print);
      
      	return 0;
      }

      void *  类型的指针不能进行解引用操作

    •  

  • 指针和数组面试题解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值