指针进阶笔记

  (一)数组指针

(二) 字符指针

(三)指针数组

(四)数组指针的其他替代方式

(五)实战练习

(六)数组参数和指针参数

(七)数组传参

(八)函数指针

(九)函数指针数组

(十)指向函数指针数组的指针

(十一)回调函数

(十二)快排函数

  

总述:指针类型纷繁复杂,但是相信苦心人天不负,一定可以掌握的!.

       字符指针 
           char ch='w';
           char*p=&ch;
       常量字符串
           char*p="ancdef";
       指针数组
           int* p[10];
           char* ch[5]
       数组指针
           int *p3;整形指针
           char* p4;
           int arr[5]
           int (*p3)[5]=&arr;(去掉名字之后就是类型 int(*)[5])

      函数指针:
            int* (*padd)[10]=&arr; 
      函数指针的数组
           int(*pa[5])(int,int);
      指向函数指针数组的指针
          int(*(*ppa)[5]))(int,int)=&pa; 

(一)数组指针(存放数组的地址)

int main()	
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int (*p)[10]=&arr;// &arr指取得是arr的地址 
                        (*p)表示指针变量 
                         []的优先级高于*
                         指针p指向一个数组有十个元素 
	int i=0;
	for(i=0;i<10;i++)
	 {
	 	printf("%d",(*p)[i]);
	 }
	 return 0;	
}
int main()

{
     char* arr[5];
	 char* (*pa)[5]=&arr;  //
        (*pa)     Pa是个指针变量名 *说明整体是指针    
        [5]       指pa指向的数组为5个元素  
        char*     指pa指向的数组的元素类型是char* 
}
使用:*pa==arr 
 int main()
{
	int arr={1,2,3,4,5,6,7,8,9,10};
	int (*pa)[10]=&arr;

	int i=0;
	for(i=0;i<10;i++)
	 {
	 	(*pa)[i];  (*pa拿到数组的地址,对i赋值得到每个值)
	 }
}
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p=a;

int i=0;
for(i=0;i<10;i++)
 printf("%d",*(p+i));
}

 (二)字符指针 

 int main()
 {
  char a='w';
  char* pc=&a;// pc字符指针类型char* 
 }
  


{
  	char arr[]="abcdef";
  	char* pc=arr;//arr为首元素地址,字符指针存放数组名,也就是把首元素a的地址放到pc里。 
  	printf("%s",pc);
	printf("%s",arr); 
 }
 
{
 	char*p="abcdef" (""为常量字符串,实际上是把a的地址赋给p)
 	printf("%c",*p); 
 	printf("%s",p);(从p存的地址处出发开始打印一个字符串)*/}

 	
{ 
  char a1[]="abcdef";
  char a2[]="acbdef";(a1和a2是俩块不同的内存单元)
       (a1!=a2)         {a1和a2分别为数组首元素地址,自然不同}
  char*p1="abcdef" 
  char*p2="abcdef"(俩个字符串一模一样,常量字符串不可修改,在内存中不能存俩份,所以相同) 
       (a1==a2)
	} 

 (三)指针数组

int main()
{
  int* a[10]={0};   存放整形指针的数组 称为整形指针数组 
  char* pch[10];    存放字符指针的数组

 
  int a=10; int b=20; int c=30; int d=40;
  int* arr={&a,&b,&c,&d}  arr[i]是每个元素的地址 


  int i=0;
  for(i=0;i<4;i++)
 {
    *(arr[i]); 
	}   	
}	
int main()
{
    int a1={1,2,3,4,5};
    int a2={2,3,4,5,6};
    int a3={3,4,5,6,7};
    int* prr[]={a1,a2,a3};存入首元素地址

for(i=0;i<3;i++)
  {int j=0;
   for(j=0;j<5;j++)
    {
      *(prr[i]+j);
      } 
}

 (四)数组指针的其他替代方式


int main()
{
	int arr[3][5]={
   
   {1,2,3,4,5},{2,3,4,5,6},{4,5,6,7,8}};
	print1(arr,3,5);
    print2(arr,3,5);
	
}

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");}/*main中写数组名,传参的列表写为数组形式 
	   把二维数组想像为一维数组再去讨论首元素地址,每行为一个元素,则arr有三个元素。即arr代表 
       第一行的地址 */
}

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++)
 
	 	*(p+i);//找到这一行 
	 	*(*(p+i)+j)//找到这一行第j个元素 
	 }
	
 } 
  /*a[i]==*(a+i)==*(p+i) ==p[i] p与arr可以互换 
  [j]==*(a+j)*/

 (五)实战练习

 

int main()
 {
   int a[5];
   int *pa[10];//指针数组 类型int*
   int (*pa)[10];//数组指针 该指针指向一个数组 数组十个元素 每个元素类型int 
   int (*pa[10])[3]/*该指针数组pa[10]有三个元素
    每个元素是一个数组指针,
	该数组指针指向的数组有10个元素,每个元素int */}

(六) 数组参数和指针参数
       

一维数组传参

int a[10];
        void canshu(int a[]);
        void canshu(int a[10]);    
        void canshu(int*arr);数组名为首元素地址,每个首元素的地址都是int型的        
    int* arr2[10];
        void canshu(int*arr[40]);
        void canshu(int**arr);一级指针的地址放在二级指针中 
首元素为第一行的地址 不能传int*arr 因为它非整型       
        int a[3][5];
        int (*a)[5] 
一级指针传参
    int arr[10]={1,2,3,4,5};
    int *p=arr;    
        void can(int *p)
//思考:当一个函数的参数为一级指针的时候,函数可以接受什么样参数
    void can1(int *pa)
    void can2(char*pa)
    { int a=10;
      int*p1=&a;
      can(p1);
      can(&a);
    }


  // 二级指针传参
    void can(int **p)
      int n=10;
      int*p=&n;
      int**pp=&p;
      can(pp);
      can(*p);
      int* arr[10];
      can(arr); //指针数组传参也可以 

(七) 数组传参

一维数组传参
	int a[10];
		void canshu(int a[]);
		void canshu(int a[10]);	
		void canshu(int*arr);数组名为首元素地址,每个首元素的地址都是int型的	    
    int* arr2[10];
        void canshu(int*arr[40]);
        void canshu(int**arr);一级指针的地址放在二级指针中 
	二维数组传参的时候行可以省略,列不能省略
	且首元素为第一行的地址 不能传int*arr 因为它非整型       
	    int a[3][5];
		int (*a)[5] 
	一级指针传参
	int arr[10]={1,2,3,4,5};
	int *p=arr;	
		void can(int *p)
	思考:当一个函数的参数为一级指针的时候,函数可以接受什么样参数
	void can1(int *pa)
	void can2(char*pa)
	{ int a=10;
	  int*p1=&a;
	  can1(p1);
	  can1(&a);
	  char ch='w';
	  char*pc=&ch;
	  can2(pc);
	  can2(&ch);
	}
	二级指针传参
	void can(int **p)
	  int n=10;
	  int*p=&n;
	  int**pp=&p;
	  can(pp);
	  can(*p);
	  或:
	  int* arr[10];
	  can(arr); 指针数组传参也可以

(八) 函数指针(指向函数的指针)    &函数名==函数名 都是函数的地址

int (*pa)(int,int)=add; 
    (*pa) (2,3)找到函数地址后调用,然后往里面传参 
    void print(char*str)
	{
		printf("%s",str);
		}  
		
	int main()
	{
		void(*p)(char*)=print;
		(*p)(woaini);
		  }	 
		   
(* (void(*)()) 0) () 0强制转换为void(*)()后解引用调用
  
void ( *signal( int , void(*)(int)) ) (int);
 函数名 signal 参数有2个,一个是int,一个是函数指针 
 函数返回类型void(*) (int)
 
 typedef void(*mama)(int);给函数返回类型重新取个名字 
 则上面的可以写成 mama signal(int,mama);

(九)函数指针数组

有一个数组可以存放多个函数的地址---存放函数指针的数组 
      int(*pa[4]) (int,int)={Add,sub,mul,dlv};

      pa先与[]结合说明是数组,类型为int(*)(int,int) ;
       for(i=0;i<4;i++)
        {
        	pa[i](2,3);
		}

    例:char*strcpy(char*a,const char*b);
      写一个函数指针pf,指向strcpy
	   char* (*pf)(char*a,const char*b);
	  写一个函数指针数组
	   char* (*pf[4]) (char*a,const char*b); 
    

 (十)指向 函数指针数组 的指针

 
int main()
{
	int arr={0};
	int (*p)[10]=&arr;
	
	int (*parr[4])(int,int); parr是数组,函数指针的数组
	int(*(*pp)[4]) (int,int)=&parr; pp是一个数组指针,指向一个数组
	每个元素的类型是函数指针,元素类型int(*)(int,int) 
}

(十一)回调函数(通过一个函数指针调用的函数 把函数的地址作为参数传递给另一个函数,
当这个指针被用来指向所调用的函数时称为回调)

 void text(void(*p)(char*))
 {
 	printf("text\n");
 	p("bit");
 }
 void print(char*str)
 {
 	printf("hehe%s",str);
  } 
 
 int main()
 {
   text(print);
 }

(十二)快排函数

 qsort:可以排序任意数组--库函数
           算法为quick sort 

 void*类型的指针 可以接受任意类型的地址 (垃圾桶) 
          不能进行解引用操作 也不能进行加减整数的操作
           return *(int*)e1-*(int*)e2;
         若e1>e2返回一个大于0的数字 

   传参:base(start of target array)
         num(array size in elements)
         width(每个元素多少字节)
         compare function(比较函数,把俩个函数比较的方法写成一个函数传进去,
         ,比较俩个)
         elemt 1()要比较的那俩个元素的地址 
         elemt 2() 
void qsort(void*base,size_t num,size_width,int(*cmp)(const void*e1,const void*e2))
     int cmp(const void*e1,const void*e2)
 {
     
 }       

Supongo que te gusta

Origin blog.csdn.net/m0_63203388/article/details/121383349
Recomendado
Clasificación