zoukankan      html  css  js  c++  java
  • C语言中的指针

    请先看C++中的指针概述,这里只是扩充

    数组指针

      其实这里主要说的就是c++中的指针运算

    /*
     
     数组元素指针:
        一个变量有地址,一个数组包含若干个元素,每个数组元素都有相应的地址,
        指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中)
        所谓数组元素的指针就是数组元素的地址
        可以用一个指针变量指向一个数组元素
     
        int a[10]={1,2,3,4,5,6,7,3,2,3};
        
        int *p;
        
        p=&a[0]; 等同与 p=a; 等同与 int *p=a; 等同与 int*p=&a[0]
     
        注意:
        1) 数组名a不代表整个数组,只代表数组首元素的地址
           p=a 的作用是"把a数组的首元素的地址赋给指针变量p",而不是"把数组a各个元素的值赋给p"
     
     
     数组指针:
        指向数组元素的指针
     
     数组指针的作用:
        使用数组指针间接访问数组的元素
    
     数组指针的定义:
        int *p;
    
     数组指针的初始化;
     
        int a[4] ={1,2,3,4};
        int *p = a;//数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素的地址),P指向数组的第一个元素
        
        int *p = &a[0];//等价上面一句话
     
     数组指针如何访问数组的元素:
        1) p+1 表示指向数组的下一个元素
        2) p-1 指向数组的上一个元素
     
     误区:
        用数组指针遍历数组
        for(int i=0;i<4; i++){
            printf("%d	",*p++);
        }
     
        //学习的误区: 数组名 a 是一个常量 等同与 *(10++)
        //数组名++ 这是错误的
        printf("*a=%d
    ",*a++);//这种写法是错误的
     
     
     */
    

    逆序数组:把数组中的内容前后对调

    void nixuArray(int a[],int len){
            int i=0,j=len-1;
            while(i<j){
                temp=*(p+i);
                *(p+i)=*(p+j);
                *(p+j)=temp;
                //修改下标
                i++,j--;
            }
        }
    

    一维指针数组

    指针数组的定义:
            
            数据类型*数组名[数组长度];
            
            int* pa[3];
            
            //定义一个指针数组,数组名是pa,可以用来存放3个指针(必须是int类型变量的指针);
     
        指针数组的使用:
        
            int a=3,b=4,c=5;
     
            int *pa[3] ={&a,&b,&c};
     
            pa[0] a的地址
     
            pa 数组的首地址,又是变量a的地址
     
            //使用数组名来访问 a的值
     
            printf("%d
    ",**pa);
     
            int a1[2][2]={1,2,3,4};
            
            //定义了一个指针数组,赋值为a1[0]是第一行的指针
            int *pa1[2]={a1[0],a1[1]};
            printf("**pa1=%d
    ",**pa1);
            
            //*pa1 取到的是指针数组pa1中首地址的值= a1[0]
            //同时a1[0] = a1的首地址
             *pa1 = a1[0]
     
             printf("&a1[0] = %d
    ",a1[0]);
     
             printf("*pa1 = %d
    ",*pa1);
            
            //正推
            //所以 **pa1 即 *(*pa1)=*(*pa1[0])=*(a1)=*(a1[0])=*(&(a1[0][0]))=a1[0][0] =1;
            //**(pa1+1)=*(*(pa1+1))=*(*pa1[1])=*(a1[1])=*(&(a1[1][0]))=a1[1][0]=3
            
            //逆推
            //所以想拿数字2的时候 就相当于
            2=a1[0][1]=*(&a1[0][1])=*(&a1[0][0]+1)=*(a1[0]+1)=*(a1+1)=*(*pa1[0]+1)=*(*pa1+1)
            //拿数字3
            3=a1[1][1]=*(&a1[1][1])=*(&a1[1][0]+1)=*(a1[1]+1)=*(pa1[1]+1)=*(*(pa1+1)+1)
     
    

    数组名访问二维数组

    公式 *(*(a+i)+j) == a[i][j]
    

    用普通指针访问二维数组

    //这种写法虽然也可以获取到二维数组中的元素,但是这样写是不符合规范的,利用了内存存储的机制

    数据在内存中存放的方式,从高地址依次向下存放

    int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
            
            int *p=a
            
            for(int i=0;i<12;i++){
                printf(" %d 
    ",*(p+i));
            }
    

    二维数组指针

            一般形式:
                数据类型 (*指针变量名)[二维数组列数];
            其中"类型说明符"为所指数组的数据类型. “*” 标示其后的变量是指针类型
     
            如要将二维数组赋给一指针,应这样赋值:
            int a[3][4];
            int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组
            p=a;         //将该二维数组的首地址赋给p,也就是a[0]或 &a[0][0]
            p++;         //该语句执行过后,也就是p=p+1; p 跨过行a[0][] 指向行a[1][]
     
            所以数组指针也称指向一维数组的指针
     
            遍历二维数组的元素
     
            int a[3][4]={1,3,4,5,6,7,8,9,10,13,15,17};
            
            int (*p)[4]=a;
            
            所以之前遍历中的 数组a 可以替换为 p  :*(*(p+i)+j)
    

    指针数组和二维数组指针变量的区别

       int *pa[3]={&a,&b,&c}; pa是一个指针数组
        int *pa1[2]={a[0],a[1]}
        int (*pa)[3] ;//二维数组指针
     
        应该注入指针数组和二维数组指针变量的区别,这两者虽然都可以用来标示二维数组,但其表示方法和意义是不同的
        二维数组指针变量是单个的变量,其一般形式中(*指针变量名)两边的括号不可少,而指针数组类型表示的是多个指
        针(一组有序指针)在一般形式中"*指针数组名"两边不能有括号.
        例如:
            int(*p)[3]; //表示一个指向二维数组的指针变量,该二维数组的列数为3或分解为一维数组的长度为3
            int *p[3];  //表示p是一个指针数组,有三个下标变量p[0],p[1],p[2]均为指针变量
       
    

    字符串指针

        char *变量名 ="字符串内容" // "字符串内容"是常量
                                //当指向的为'' 单引号时,为字符指针 ""双引号时为字符串指针
    

    字符串指针与字符数组的区别

        //字符串指针  指向可以改变
            char *ss="abc";
     
                ss="bcd";
     
        //字符数组
            char s1[]="abc";
                s1="hello" 这是错误的 可以改变里面的内容但是不能重新指向
     
    

    指针函数

    一个函数的返回值类型是指针,我们就称为指针函数
    格式:
        类型说明符 * 函数名( 形参表){
            函数体
        }

    例:
        //返回两个数中的大数的地址
        //返回的是形参x 和 y 中大数的地址
        int * max( int x,int y){
          printf("x= %p ",&x);
          printf("y= %p ",&y);
          return x>y?&x:&y;
        }

    函数指针

    函数指针
        在C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。
        
        我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数.然后通过指针变量就可以找到并调用这个函数.我们把这种指向函数的指针变量称为"函数指针变量"
    
    函数指针定义方法:
        函数指针变量定义的一般形式为:
            类型说明符  (*指针变量名)(函数的参数);
        其中"类型说明符" 表示被指函数的返回值的类型
        "(* 指针变量名 )" 表示 "*" 后面的变量是定义的指针变量 
    
    
    
       函数的声明:
    
        int sum(int a,int b);----->函数指针 int (*p)(int a,int b);
    
        //定义了一个函数指针p
        //p可以存放返回值是int类型, 并且有两个形参,形参的类型还都是int类型的函数的地址
    
        //函数指针的初始化
         p = sum;//sum存得就是函数在内存中的首地址
        
    
        //定义函数指针的时候,可以不用写形参名
        int (*p)(int int);
    
    函数指针的使用 
        
        
            1.定义函数指针
                int(*p) (int int);
            2.给函数指针初始化
                p=sum;
            3.用函数指针间接的调用函数
                int s=p(23,45);
    
     函数指针的用处:
    
          例如 + - x /时 ,只需要判断符号 ,然后 p = sum / p = jian  就可以
    
            
    

      

  • 相关阅读:
    使pre的内容自动换行
    textarea文本换行和页面显示换行符
    SQL查询包含汉字的行
    网站引导页插件intro.js 的用法
    jquery.cookie中的操作
    sql自动生成汉语拼音和首字母函数
    IE,Chrome滚动条样式CSS
    Vcenter server 5.5上传ISO镜像
    Vcenter server 5.5添加用户角色及分配权限
    Vcenter server 5.5安装部署
  • 原文地址:https://www.cnblogs.com/developer-wang/p/4488993.html
Copyright © 2011-2022 走看看