zoukankan      html  css  js  c++  java
  • C专家编程(4)

    数组与指针

    在大部分情况下,数组和指针是可以互换的。书中的第4章主要讲解了数组和指针的不同之处,而在第9章则着重讨论两者可以互换的场景。

    不同之处

    对于两者的不同之处,主要在于访问两者时有一些不同。

    编译器会为每个变量分配一个地址,每个符号的地址在编译时可知(如数组的名字)。那么在访问数组中的数据时,可以通过符号表直接得出数组的起始地址,加上偏移量即可访问对应的数据。

    而对于指针,必须先在运行时取得它当前存储的值,再对它解引用来获取(数组的)起始值,最后才能加上偏移量来访问数据。


    其他区别

    指针 数组
    保存数据的地址 保存数据
    间接访问数据,首先取得指针的内容,把它作为地址,然后从这个地址提取数据。
    如果指针有一个下标[i],就把指针的内容加上i作为地址,从中提取数据
    直接访问数据,a[i]只是简单的a+i为地址取得数据
    通常用于动态数据结构 通常用于存储固定数目且数据类型相同的元素
    相关的函数为malloc(),free() 隐式分配和删除
    通常指向匿名数据 自身即为数据名

    相同之处

    在书中,主要从“声明”和“使用”两种情况下进行讨论,直接看图:

    在C语言标准中,有若干条规则对两者间的联系进行了说明,本书作者对其进行了进一步的说明:

    1. “表达式中的数组名”就是指针
    2. C语言把数组下标作为指针的偏移量
    3. “作为函数参数的数组名”等同于指针

    编程挑战

    #include <stdio.h>
    
    #define PR(fmt,val) printf(#val " = %" #fmt "	", (val))
    #define NL putchar('
    ')
    
    #define PRINT1(f,x1) PR(f,x1), NL
    #define PRINT3(f,x1,x2,x3) PR(f,x1), PRINT2(f,x2,x3)
    
    static void func1(char ca[]) { PRINT3(#x, &ca, &(ca[0]), &(ca[1])); }
    
    static void func2(char* pa)
    {
      PRINT3(#x, &pa, &(pa[0]), &(pa[1]));
      PRINT1(#x, ++pa);
    }
    
    char ga[] = "abcdefg";
    
    int main()
    {
      PRINT3(#x, &ga, &(ga[0]), &(ga[1]));
      func1(ga);
      func2(ga);
      return 0;
    }
    

    运行结果如下:

    &ga = 0x37c3b010        &(ga[0]) = 0x37c3b010   &(ga[1]) = 0x37c3b011
    &ca = 0x7f38c918        &(ca[0]) = 0x37c3b010   &(ca[1]) = 0x37c3b011
    &pa = 0x7f38c918        &(pa[0]) = 0x37c3b010   &(pa[1]) = 0x37c3b011
    ++pa = 0x37c3b011
    

    可以看出作为参数,数组的地址和数组的第一个元素的地址是不同的。

  • 相关阅读:
    docker中centos7安装ssh服务
    redis加入systemctl服务
    elasticsearch设置执行脚本并添加开机启动 (转)
    CentOS7使用firewalld打开关闭防火墙与端口
    腾讯地图JSAPI开发demo 定位,查询
    C# 开发AliYun(阿里云) 小蜜调用接口代码
    VSCode 开发Core教程
    Rabbit原理理解
    Exceptionless 本地部署
    Visual Studio 2019 自带混淆工具DotFuscator不需要去网络下载
  • 原文地址:https://www.cnblogs.com/maxiaowei0216/p/14247509.html
Copyright © 2011-2022 走看看