ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C语言:指针进阶

2021-06-13 11:00:42  阅读:85  来源: 互联网

标签:arr 进阶 int void C语言 数组 printf 指针


  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 *  类型的指针不能进行解引用操作

    •  

  • 指针和数组面试题解析

标签:arr,进阶,int,void,C语言,数组,printf,指针
来源: https://blog.csdn.net/LWJWJL00/article/details/117667520

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有