• 指针


    一、
    指针变量:指向地址的变量  
    指针就是地址,用来存放地址的变量
    变量指针:变量地址
    指针是存放地址才出现的,地址是为了标示一块地址空间的。
    指针让地址有地方存放,指针让内存的访问更加便捷。
    指针的大小子在32位平台是4个字节,在64位平台是8个字节。
    二、指针和指针类型
    指针是有类型的,类型是:type+*的方式,比如 int* 类型的指针是为了存放 int 类型的地址。
    (1)、指针+-整形
    #include <stdio.h>
    #include <windows.h>
    int main()
    {
        int num=10;
        char *pc=(char *) &num;
        int *pi=&num;
        printf("%p
    ",&num);// 0070FE94
        printf("%p
    ",pc);  // 0070FE94
        printf("%p
    ",pc+1);// 0070FE95
        printf("%p
    ",pi);  // 0070FE94
        printf("%p
    ",pi+1);// 0070FE98
        system("pause");
        return 0;
            
    }
     
    总结:指针的类型决定了指针行前或者向后走一步有多大(距离)。
    (2)、指针的解引用
    #include <stdio.h>
    #include <windows.h>
     
    int main()
    {
        int num = 0x11223344;
        char *pc = (char *)&num;
        int *pi = &num;
        *pc = 0x55;
        *pi = 0;
        system("pause");
        return 0;
    }
    总结:指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字符)
    比如:char* 的指针解引用就只能访问一个字节,而int* 的指针的解引用就能访问四个字节。
    三、指针数组和数组指针
    指针数组:指针数组是数组,是一个存放指针的数组
    int *arr1[10];
    char *arr2[4];
    数组指针:数组指针是指针
    int (*p)[10];
    数组指针的使用
    #include <stdio.h>
    #include <windows.h>
     
    int main()
    {
        int arr[10] = { 0 };
        //arr 表示数组首元素的地址
        //&arr表示数组的地址
        printf("%p
    ", arr);     //00EFFC3C 
        printf("%p
    ", arr + 1); //00EFFC40
        printf("%p
    ", &arr);    //00EFFC3C
        printf("%p
    ", &arr + 1);//00EFFC64
        system("pause");
        return 0;
    }
    

     

    二维数组传参
    void
    test() {     int arr[3][5];     print(arr); } void print(int arr[][5])//可以 void print(int arr[3][5])//可以 void print(int (*arr)[5])  //推荐 void print(int **arr)   //不推荐 数组传参降级为指针,指向该内部元素的指针。二维数组降级为一维数组是指针。 一级指针传参 #include <stdio.h> #include <windows.h> void test(int *p,int n) {     int i = 0;     for (; i < n; i++)     {        printf("%d ", p[i]);//*(p+i)     } }   int main() {     int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };     int *pt = arr;     int size = sizeof(arr) / sizeof(arr[0]);     test(pt, size);          system("pause");     return 0; }
    二级指针传参
    #include <stdio.h>
    #include <windows.h>
    void test(int  **ptr)
    {
        printf("num=%d
    ", **ptr);
    }
    int main()
    {
        int num = 10;
        int *p = &num;
        int **pp = &p;
        test(pp);
        test(&p);
        system("pause");
        return 0;
    }
    函数指针
         函数指针是指向函数的指针变量,即本质是一个指针变量。
         int (*f)(x,y);
     
    指针函数
    指针函数是带指针的函数,即本质是一个函数。函数返回类型是某一类型是指针。
            类型标识符   *函数名(参数)
          int *f(x,y);
    首先它是一个函数,函数返回值是一个地址值。函数返回值必须用同类型是指针变量来接受,
    也就是说,指针函数一定能有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。
    表示:
        float *fun();
        float *p;
        p=fun(a);
    查看一个月第几周第几天是多少号?
    #include <stdio.h>
    #include <windows.h>
    int *Getdata(int wk,int dy)
    {
        static int calendar[5][7]={{1, 2, 3, 4, 5, 6,7},
                                   {8, 9,10,11,12,13,14},
                                   {15,16,17,18,19,20,21},
                                   {22,23,24,25,26,27,28},
                                   {29,30,31,-1}};
        return &calendar[wk-1][dy-1];
    }
    int main()
    {
        int wk,dy;
        do
        {
            printf("Enter week(1-5)day(1-7)");
            scanf("%d%d",&wk,&dy);
        }while((wk<1||wk>5)||(dy<1||dy>7));
        printf("%d
    ",*Getdata(wk,dy));
        system("pause");
        return 0;
    }

    如何辨别指针函数和函数指针

    看函数名前的指针 *号有没有被括号()包含,如果被包含就是函数指针,反之则是指针函数。
    函数指针数组
    即把函数的地址存放到数组中
    int (*parr[10])();
    转移表(计算器)
    #include <stdio.h>
    #include <windows.h>
    int add(int a,int b)
    {
        return a+b;
    }
    int sub(int a,int b)
    {
        return a-b;
    }
    int mul(int a,int b)
    {
        return a*b;
    }
    int divi(int a,int b)
    {
        if(b==0)
        {
            printf("div is zero
    ");
        }
        else
        return a/b;
    }
    int main()
    {
        int x,y;
        int input=1;
        int ret=0;
        int (*p[5])(int x,int y)={0,add,sub,mul,divi};//转移表
        while(input)
        {
            printf("************************
    ");
            printf("  1:add         2:sub   
    ");
            printf("  3:mul         4:divi  
    ");
            printf("************************
    ");
            printf("请选择:");
            scanf("%d",&input);
            if((input<=4&&input>=1))
            {
                printf("请输入操作数:");
                scanf("%d%d",&x,&y);
                ret=(*p[input])(x,y) ;
            }
            else
            
                printf("输入有错!
    ");
                printf("ret=%d
    ",ret);       
        }
        system("pause");
        return 0;
    }
    指向函数指针数组的指针
    指向函数指针数组的指针是一个指针
    指针指向一个数组,数组的元素都是函数指针;
    #include <stdio.h>
    #include <windows.h>
    void test(const char* str)
    {
        printf("%s
    ",str);
    }
    int main()
    {
        void (*pfun)(const char*)=test;//函数指针pfun;
        void (*pfunArr[5])(const char* str);//函数指针数组pfunArr;
        pfunArr[0]=test;
        void (*(*ppfunArr)[5])(const char*)=&pfunArr;//指向函数指针数组的指针ppfunArr;
        system("pause");
        return 0;
    }
     
    回调函数
           回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
           这有一些大量的示例可以帮助大家理解回调函数https://www.zhihu.com/question/19801131
     
    下面几个例子帮助大家理解
    #include <stdio.h>
    #include <windows.h>
    int int_cmp(const void *p1,const void *p2)
    {
        return (*(int *)p1>*(int *)p2);
    }
    void _swap( void *p1,  void *p2, int size)
    {
        int i=0;
        for(i=0;i<size;i++)
        {
            char tmp=*((char *)p1+i);
            *((char *)p1+i)=*((char *)p2+i);
            *((char *)p2+i)=tmp;
         }
    }
    void bubble(void *base,int count,int size,int(*cmp)(void *,void *))//int(*cmp)(void *,void *)回调函数
    {
        int i=0;
        int j=0;
        for(;i<count-1;i++)
        {
            for(;j<count-1;j++)
            {
                if(cmp((char*)base+j*size,(char*)base+(j+1)*size)>0)
                {
                    _swap((char *)base+j*size,(char*)base+(j+1)*size,size);
                }
             }
        }
    }
    int main()
    {
        int arr[]={5,1,6,2,3,8,4,9,7};
    //    char *arr[]={"aaaa","iiii","cccc","bbbb"};
        int i;
        bubble(arr,sizeof(arr)/sizeof(arr[0]),sizeof (int),int_cmp);
        for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
        {
            printf("%d ",arr[i]);
        }
        printf("
    ");
        system("pause");
        return 0;
    }
     
     
  • 相关阅读:
    CodeForces 173B Chamber of Secrets spfa
    CodeForces 173A Rock-Paper-Scissors 数学
    Codeforces Gym 100803G Flipping Parentheses 线段树+二分
    Codeforces Gym 100803D Space Golf 物理题
    Codeforces Gym 100803F There is No Alternative 暴力Kruskal
    Codeforces Gym 100803C Shopping 贪心
    《白日梦想家》观后感
    select sum也会返回null值
    mysql update更新带子查询的实现方式
    mysql 添加索引 mysql 如何创建索引
  • 原文地址:https://www.cnblogs.com/xjq6898/p/7901318.html
Copyright © 2020-2023  润新知