zoukankan      html  css  js  c++  java
  • 指针

    概览

    指针是C语言的精华部分,通过利用指针,我们能很好地利用内存资源,使其发挥最大的 效率。有了指针技术,我们可以描述复杂的数据结构,对字符串的处理可以更灵活,对数组 的处理更方便,使程序的书写简洁,高效,清爽。

    1.指针与指针变量

    2.数组与指针

    3.函数指针

    指针与指针变量

    指针:访问变量,首先应找到其在内存的地址,或者说,一个地址唯一指向一个内存变量,称这个地址为变量的指针;

    指针变量:存放指针的变量就是指针变量。

    指针变量的引用:指针变量是对变量一种间接访问形式。对指针变量的引用形式为:*指针变量,其含义是指针变量所指向的值。

    字符串与指针

    #include <stdio.h>
    
    int main(int argc, const char * argv[]) {
        char a[]="abc";
        printf("%x,%s
    ",a,a);//结果:5fbff820,abc,同一个变量a是输出字符串还是输出地址,根据格式参数而定
        printf(a); //结果:abc
        printf("
    ");
        
        char b[]="abc";
        char *p=b;
        printf("b=%s,p=%s
    ",b,p);//结果:b= abc,p= abc
        
        //指针存储的是地址,而数组名存储的也是地址,既然字符数组可以表示字符串,那么指向字符的指针同样也可以,如下方式可以更简单的定义一个字符串
        char *c="abc"; //等价于char c[]="abc";
        printf("c=%s
    ",c); //结果:c= abc
        
        return 0;
    }

    这里需要指出是为什么printf(a)能够直接输出字符串呢?

    我们看一下printf()的定义:int     printf(const char * __restrict, ...) __printflike(1, 2);其实printf的参数要求是指向字符类型的指针,而结合上面的例子和我们之前说的,如果函数形参是指针类型那么可以传入函数名,因此也就能正确输出字符串的内容了

    数组与指针

    对数组来说,数组名就是数组在内存中首地址,即指针;

    例:int a[3] = {1,2,3};

      int *p = a 或 int *p = &a[0];

    指针与一维数组

    假设我们定义一个一维数组,该数组在内存会有系统分配的一个存储空间,其数组的名 字就是数组在内存的首地址。若再定义一个指针变量,并将数组的首址传给指针变量,则该 指针就指向了这个一维数组。我们说数组名是数组的首地址,也就是数组的指针。而定义的 指针变量就是指向该数组的指针变量。对一维数组的引用,既可以用传统的数组元素的下标 法,也可使用指针的表示方法。

    int a[10] , * ptr ; / * 定义数组与指针变量 * /

    做赋值操作: ptr = a ; 或 ptr = &a[0] ;
    则 ptr 就得到了数组的首址。其中, a 是数组的首地址, &a[0] 是数组元素 a [0] 的地址,由于

    a [0] 的地址就是数组的首地址,所以,两条赋值操作效果完全相同。指针变量 p t r 就是指向数 组a的指针变量。

    若 ptr 指向了一维数组,现在看一下 C 规定指针对数组的表示方法:

    1 ) ptr + n 与 a + n 表 示 数 组 元 素 a [n] 的 地 址 , 即 &a[n] 。对整个 a 数 组 来 说 , 共有 10个元素, n的 取 值 为 0 ~ 9 , 则数组元素 的 地 址 就 可 以 表 示 为 ptr + 0 ~ ptr + 9 或 a + 0 ~ a + 9 ,与 &a[0] ~ &a[9]保持一致。

    2) 知道了数组元素的地址表示方法, *(ptr + n )和*(a + n )就表示为数组的各元素即等效于a[ n ] 。

    3) 指向数组的指针变量也可用数组的下标形式表示为 ptr[n] ,其效果相当于 *( ptr + n) 。

    指针与二维数组

    定义一个二维数组:int a[3][4];

    其中 a 是 二 维 数 组 的 首 地 址 , &a[0] [0] 既 可 以 看 作 数 组 0 行 0 列 的 首 地 址 , 同 样 还 可 以 看 作 是 二 维 数 组 的 首 地 址 , a[0] 是第 0 行 的 首 地 址 , 当 然 也 是 数 组 的 首 地 址 。 同 理 a[n] 就是第 n 行的 首址; &a[n] [m] 就是数组元素 a[n] [m] 的地址。

    函数指针

    函数也是在内存中存储的,当然函数也有一个起始地址(事实上函数名就是函数的起始地址),这里同样需要弄清函数指针的关系。函数指针定义的形式:返回值类型 (*指针变量名)(形参1,形参2),拿到函数指针其实我们就相当于拿到了这个函数,函数的操作都可以通过指针来完成,而且通过前面的例子可以看到指针作为C语言的数据类型,可以作为参数、作为返回值,那么当然函数指针同样可以作为函数的参数和返回值。

    #include <stdio.h>
    
    int sum(int a,int b){
        return a+b;
    }
    
    int sub(int a,int b){
        return a-b;
    }
    
    //函数指针作为参数进行传递
    int operate(int a,int b,int (*p)(int,int)){
        return p(a,b);
    }
    
    int main(int argc, const char * argv[]) {
        int a=1,b=2;
        int (*p)(int ,int)=sum;//函数名就是函数首地址,等价于:int (*p)(int,int);p=sum;
        int c=p(a,b);
        printf("a+b=%d
    ",c); //结果:a+b=3
        
        
        //函数作为参数传递
        printf("%d
    ",operate(a, b, sum)); //结果:3
        printf("%d
    ",operate(a, b, sub)); //结果:-1
        
        return 0;
    }

    注意,普通的指针可以写成p++进行移动,而函数指针写成p++并没有意义。

  • 相关阅读:
    PopupWindow设置动画效果
    android判断是否含有某权限
    每日一更提醒
    利用Pattern和Mather来禁止特殊字符的输入
    Android毛玻璃处理代码(Blur)
    how to render html tag
    数组
    复杂度分析
    书写markdown的利器
    cannot insert multiple commands into a prepared statement问题原因及解决办法
  • 原文地址:https://www.cnblogs.com/Lanht/p/10096704.html
Copyright © 2011-2022 走看看