《C语言内核深度解析》笔记(3):指针才是C语言的精髓

2023-05-16

第03章 指针才是C语言的精髓

3.2 指针 

int a = 10;
int *p = &a; 
指针变量p和普通变量之间没有本质区别,都是变量空间放了一个数值,只是p里面的数值比较特殊,是a空间的地址,它
指向了空间a。

变量空间的首字节地址,作为整个空间的地址: 实际上内存中的每个自己空间都有一个地址,如果内核由32位地址线,地址以二进制表示,既然
每个字节对应的地址都是32位,那么存放地址的变量大小也是32位的,即四个字节。但只有首字节地址才能作为整个a空间的地址。

指针变量的类型作用:
    某类型一级指针变量 = 该类型一级地址
    该类型二级指针变量 = &(该类型一级指针变量)
    n+1级指针变量 = &(该类型的一级指针变量)

指针使用之三部曲
    定义(声明)
    int *p = NULL; //初始化一下,防止野指针
    关联
    int a = 10;
    p = &a; //a空间的首地址给了p,所以p里面的地址指向了a空间,因此简称p->空间
    引用
    读空间:读值操作,前提是里面存有数据才行。
    int b = *p;     //等价于b = a
    写空间:向空间写入新的值
    *p = 30;        //等价于a = 30;

    3.3 理解指针符号


    * 用在指针定义:
    int *p1, *p2;       //p1和p2都是int型的一级指针变量
    int *p1, p2;        //p1是int型的一级指针变量,p2只是一个普通的int型变量
    * 解引用:
    *p 表示p所指向的空间,这时的*也称为取空间操作。

    &:取地址符,表示变量空间的首地址

    左值: 指的是变量空间,对左值执行的操作都是写空间操作。
    右值: 右值有两种形态,一种是直接写一个数值,另一种就是右值也是一个变量。

3.4 野指针与段错误问题

    野指针:指针指向一个不确定的地址空间或者指向一个确定的地址空间但是引用空间的结果是不可确定的。
    野指针危害: 引发段错误; 未产生任何结果;引发程序连环式错误。
    产生原因: 没有正确初始化;访问权限不允许;内存越界
    避免:定义指针时复制为NULL; 使用前一定要对指针变量初始化或赋值;使用前判断指针是否为空;确定指针不用式,赋值为NULL

    #ifdef      _cplusplus   //如果这个符号定义了,表示当前运行的是C++环境,否则就是C环境
    #define     NULL    0       //在C++中NULL被定义为0
    #else       
    #define     NULL    (void*)0    //在c中NULL被定义为(void*)类型的0

    段错误产生的原因:段错误本质上就是指针错误(地址错误),因为C语言的内存结构式由不同的内存段组成的,所以称为段错误。
                    大段错误: 指针变量指向的地址空间根本不存在;
                    小段错误:  指针变量指向的地址空间存在,但是对该空间的操作权限所受到了限制。

3.5 const关键字与指针


    const对于普通变量的修饰:const在类型前后前还是后都没关系,只要在变量名前面即可。
    const修饰指针的三种形式:  
        int const *p 等价于 const int *p  : 这种修饰表示p所指向的空间是“常量”,不能被修改,但是p本身可以被修改。
                                            int a = 10;
                                            int b = 20;
                                            int const *p = &a;  //p指向了a
                                            *p = 100;       //编译时会报错,因为p指向的空间不能被修改
                                            p = &b;         //正确,因为p本身是可以被修改的
        
        int *const p:  指针变量本身不能被修改,但是p所指向的内容可以被修改
        int const *const p:     p的指向不能发生改变,p所指向的内容也不能发生改变。

3.6 深入学习数组


    类型 数组名[数组元素个数]
    int  buf[100] = {0};

    一维数组中几个关键符号的理解:  
        buf:    两层含义,一是数组名,sizeof(buf)时,buf就是数组名的含义;二是等价于
        &buf[0],表示数组第一个元素的首字节地址,是一个常量值。
        buf[0]: 第一个元素的空间,可以对其进行读写操作。
        &buf[0]:    等价于buf,是一个地址常量,只能作为右值
        &buf:       表示数组首地址,是一个地址常量,只能作为右值。(数组首地址重要用于构建多维数组,加1加的是整个数组空间大小)

3.7 指针与数组的天生“孽缘”

    使用指针访问数组: 
        int buf[6] = {0, 1, 2, 3, 4, 5 };
        利用下标访问: buf[i];
        利用指针常量访问: *(buf + i); 注意,*(buf++)是错的,buf是常量不能赋值;
        指针常量访问: int *p=buf;  *(p+i);

    内存角度理解:数组中元素空间在内存中相连,地址连续,且元素类型相同,空间大小相同。
    类型匹配问题: int buf[5]; int *p = NULL; p=&buf;   这个做法错误,&buf是数组首地址,是int(*)[5]类型,不是in*型。

3.8 指针类型与强制类型转换

    数据的存入与读取:
        数据写入三步曲
        利用变量名或者直接利用地址,找到空间首地址。
        根据类型制定的空间大小,从首字节地址开始,找出向后顺序延长后的空间大小。
        按照类型数据存储格式要求,将数据写入空间。
    数据读出三步曲
        利用变量名或者直接利用地址,找到空间首地址。
        根据类型指定的空间大小,找出从首字节地址开始向后顺延后的空间大小。
        按照类型数据存储格式要求,将数据从空间读出。

    普通变量的强制转换:
        普通变量的数据类型转换,就是将数据的空间大小和数据的存储结构转变后,存入另一个空间,所以转换时回导致空间大小和数据存储结构的变化。

    指针变量数据类型的强制转换:
        对于指针来说,一律要求显式强制类型转换,不允许使用隐式类型转换。设计两个方面,对指向空间的强制类型转换,对指针变量本身做强制类型转换。

        指向空间的强制类型转换:
            int a;
            float b = 136.23;
            int *pa=&a;
            float *pb = &b;
            *pa = (int)*pb;     //等价于a = (int)b;

        指针本身强制类型转换————改变的是对其引用空间的引用方式:
            int a;
            int *pa=&a;
            float *pb = NULL;
            pb = (float *)pa;     //或者pb = (float *)&a;
            pb里面的地址值与pa里面的地址值是相等的,但是pa放的是(int*),pb放的是(float *)型,虽然都指向一个空间a,但是*pb去使用变量空间a时,会以float型的空间大小和数据结构使用a空间的值。

3.9 指针、数组与sizeof运算符


    如果要求传递一个30个元素的整型数组的话
    int fun(int *p);
    int fun(int p[30]);
    这两种写法都没问题,但是第二种写法易读性高,虽然30在这里并没有意义,可有可无。

    一般传递数组时,传递的只是数组首元素地址,如果要操作整个数组空间,需要将数组的元素个数传递过去:
    void fun(int n, int buf[n])
    {
        printf("%d\n", sizeof(buf));
    }
    int main(void)
    {
        int buf[100];

        fun(sizeof(buf),buf);
    }

    #define 只是简单宏替换,在预编译时被处理
    typedef 在编译时被处理

    区别一:
    #define dpchar char*
    typedef char* tpchar;
    dpchar p1,p2;       //只做简单的替换,等价于char* p1, p2;只有p1才是指针变量
    tpchar p1,p2;       //不是简单的替换,等价于char *p1, *p2; p1,p1和p2都是指针变量 

    区别二:#define 方式可实现类型组合,但是typedef不行
    #define dint int
    typedef int tInt;
    unsigned dInt p1,p2;    //正确,等价于unsigned int p1, p2
    unsigned tInt p1,p2;    //不可以

    区别三:
    typedef 可以组建新类型,但是#define不行
    typedef char[200] charBuf;
    charBuf buf; //等价于char buf[200],但是#define 不可以 (这个有讲)

3.10 指针与函数传参


    普通传参:
    c语言中值传递的本质就是,当调用被调函数时,被调用参数会在自己的函数栈中开辟相同类型的形参空间,并且将传递过来的值写入形参空间保存。

    传递地址:
    同样开辟空间,不过传递进来的是地址,因此操作也是面向地址的。

    传递数组:
    数组没有普通值传递,只有地址传递,如果传递值的话,效率较低。

    传递结构体:
        成员值传递:传递结构体成员值,就是普通值传递
        成员地址传递:传递结构体成员的地址,其实就是地址传递
        传递整个结构体: 将整个结构体视为一个普通值进行传递,形参需要开辟同等大小的结构体空间,用于存放传递过来的结构体内容
        结构体的地址传递: 传递真个结构体变量的地址
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《C语言内核深度解析》笔记(3):指针才是C语言的精髓 的相关文章

  • 雷达测距测速测角基本原理

    由雷达发射机产生的电磁波经收发开关后传输给天线 xff0c 由天线将此电磁波定向辐射于大气中 电磁波在大气中以近光速传播 xff0c 如目标恰好位于定向天线的波束内 xff0c 则它将要截取一部分电磁波 目标将被截取的电磁波向各方向散射 x
  • 信号处理之脉冲压缩

    一 xff0c 脉冲压缩的背景 随着飞行技术的飞速发展 xff0c 对雷达的作用距离 分辨能力 测量精度和单值性等性能指标提出越来越高的要求 测距精度和距离分辨力对信号形式的要求是一致的 xff0c 主要取决于信号的频率结构 xff0c 为
  • MTI动目标指示和MTD动目标检测

    MTI 是一种频域滤波器 radar主席的ppt 中说到 xff0c 它是对多组脉冲回波的同一个距离单元加权求和 xff0c 得到一个结果 xff1b 也就是多个输入一个输出 xff1b 相当于一个高通滤波器 xff0c 用来抑制固定目标和
  • 复旦微开发过程中遇到的问题总结(二)

    一 xff0c 将bin文件放到flash中0地址处能识别并且启动吗 xff1f xlinx的放在0地址处可以识别启动 xff0c 我尝试复旦微这个没反应 要用procise生成 xff0c 第一个必须是FSBL out 只能是procis
  • 用链表实现fifo功能缓存和拼接数据功能

    fifo h ifndef LIST QUEUE H define LIST QUEUE H include lt stdio h gt include lt stdlib h gt include 34 xil types h 34 in
  • zynq bootgen配置启动

    一 xff0c Zynq 7000 SoC 启动头文件 0x00 0x1F Arm 矢量表 由 Bootgen 使用虚拟矢量表填充 xff08 Arm 操作代码 0xEAFFFFFE xff0c 即用于捕获未初始化矢量的 branch to
  • 制作四个文件启动的镜像

    一 环境搭建 xff1a vivado2018 3 xff0c petalinux2018 3 xff0c 1 petalinux环境设置 所使用的编译环境需要使用petalinux这个软件 xff0c 第五章Petalinux 的安装 里
  • ubuntu虚拟机更改镜像源(中科大或者阿里云镜像源)

    ubuntu虚拟机更改镜像源 xff08 中科大或者阿里云镜像源 xff09 1 进入终端后 xff0c 编辑源列表文件 xff1a 输入 xff1a sudo vim etc apt sources list 后输入 xff1a i 2
  • 海康威视客户端iVMS-4200连接NVR

    海康威视客户端 iVMS 4200 连接 NVR 陈拓 2021 07 30 2021 08 01 1 概述 iVMS 4200 客户端是一款与网络监控设备配套使用的综合应用软件 xff0c 可满足用户多方面需求 xff0c 如设备管理 人
  • 匿名上位机使用方法分享--总体介绍

    不知不觉 xff0c 匿名科创已经走过了7个年头 xff0c 这里首先要感谢大家这么久以来对匿名的支持与帮助 xff01 匿名为了提供给大家一个更好的调试工具 xff0c 始终在维护开发我们的匿名上位机软件 xff0c 7年时间 xff0c
  • 匿名上位机使用方法分享--高级收码

    匿名上位机总体介绍移步 xff1a https blog csdn net wangjt1988 article details 83684188 本文视频介绍 xff1a https www bilibili com video av35
  • 匿名上位机使用方法分享--波形显示

    匿名上位机总体介绍移步 xff1a https blog csdn net wangjt1988 article details 83684188 波形显示可以说是上位机的功能重点 xff0c 是各种调试 数据分析的有力助手 xff0c 下
  • 匿名数传使用方法分享

    目录 欢迎使用匿名数传模块匿名数传的特点硬件介绍使用介绍指示灯连接匿名飞控建议 欢迎使用匿名数传模块 大家调试各种设备时 xff0c 一般用什么方式呢 xff1f 相比答案大多是上位机 43 串口的方式 如果您还在使用usb转串口芯片然后连
  • 匿名科创--X2212版到手飞套件介绍

    匿名科创到手飞X2212版 xff0c 使用朗宇X2212系列无刷电机 xff0c 配合特制的6mm正反螺纹螺旋桨安装柱 xff0c 可以同时兼容8寸普通螺旋桨和9寸9450自锁螺旋桨 优点 xff1a 可直接使用普通8寸螺旋桨 xff0c
  • vscode最皮实的C++格式化的配置方法

    1 安装C C 43 43 2 在vscode界面 xff0c 按 34 Ctrl 43 34 进入设置界面 xff0c 搜索Format 3 设置保存文件时 xff0c 按格式对代码排版 4 向下拉 xff0c 找到下图选项 xff0c
  • 通过openmv生成apriltag标签

    Apriltag官网提供的tag图片分辨率很低 xff0c 完全无法使用 xff0c 通过openmv生成apriltag标签 生成方法如下 xff1a openmv IDE的下载与安装 openmv官方提供了各种版本的IDE xff0c
  • 串口传输数据错位 的几种解决办法

    1 代码优化等级 2 使用晶振 晶振自身产生时钟信号 xff0c 为各种微处理芯片作时钟参考 无源晶振需要用CPU内部的振荡器信号差接线麻烦石英 gt 陶瓷有源晶振是一个完整的振荡器信号好接线简单灵活性较差 3 使用降低传输速率 xff1f
  • sip 认证分析

    SIP类似Http协议 其认证模式也一样 Http协议 xff08 RFC 2616 xff09 规定可以采用Basic模式和摘要模式 xff08 Digest schema xff09 RFC 2617 专门对两种认证模式做了规定 RFC
  • MicroPython移植

    MicroPython移植 1 目标板 stm32f407zgt6 2 下载移植准备 micropython源码 arm交叉编译工具 sudo apt get install git sudo apt get install gcc arm

随机推荐

  • 了解ESP32睡眠模式及其功耗

    陈拓翻译 2022 05 30 2022 05 30 原文 https lastminuteengineers com esp32 sleep modes power consumption 毫无疑问 xff0c ESP32是许多WiFi
  • 浅谈布隆过滤器

    什么是布隆过滤器 布隆过滤器是一种数据结构 xff0c 比较巧妙的概率型数据结构 xff08 probabilistic data structure xff09 xff0c 特点是高效地插入和查询 xff0c 可以用来告诉你 某样东西一定
  • 浅谈CGI基本原理和底层基本实现

    历史来由 xff1a 早期的Web服务器 xff0c 只能响应浏览器发来的HTTP静态资源的请求 xff0c 并将存储在服务器中的静态资源返回给浏览器 随着Web技术的发展 xff0c 逐渐出现了动态技术 xff0c 但是Web服务器并不能
  • linux的两种共享内存方式---mmap和shmat区别

    linux中的两种共享内存 一种是我们的IPC通信System V版本的共享内存 xff0c 另外的一种就是我们今天提到的存储映射I O xff08 mmap函数 xff09 在说mmap之前我们先说一下普通的读写文件的原理 xff0c 进
  • tcp发送窗口(滑动窗口)、拥塞窗口

    TCP发送窗口拥塞窗口试题分析 题目一 xff1a 来源2015年408计算机综合 试题链接 xff1a https www nowcoder com questionTerminal 3241441c88f04ab58585a187716
  • mktime函数性能分析

    mktime函数性能分析 1月 02 2019 in Linux环境高级编程 mktime函数性能分析 mktime是一个将break down时间 struct tm 转化为日历时间 time t 的转换函数 它的转换与struct tm
  • iptables原理和防火墙主要命令使用场景

    https www zsythink net archives 1764 朱双印的个人日志 xff0c 写的非常的通俗易懂 xff0c 好文章 https blog csdn net u011277123 article details 8
  • 链路mtu

    常常见到交换机和网卡说明中提到支持Jumbo Frame xff0c 但我一直对以太网的Jumbo Frame xff08 巨帧 xff09 如何使用不太理解 xff0c 今日在网上找到2则现摘录下来 xff0c 相信看了以后大家会有收获
  • eggjs

    https editor csdn net md not checkout 61 1 amp spm 61 1001 2014 3001 4503 https blog csdn net weixin 42304193 article de
  • mini6410上HelloQt4运行出现libQtGui.so.4: cannot open shared的原因

    主要原因是在3 3 3节中 xff0c 编写的环境变量搭建文件setqt4env中设置路径不对 export LD LIBRARY PATH 61 xff08 看看有没有文件中的目录 xff09 应该改成你所在的qt4 7目录中的lib目录
  • VINS技术路线与代码详解

    VINS技术路线 写在前面 xff1a 本文整和自己的思路 xff0c 希望对学习VINS或者VIO的同学有所帮助 xff0c 如果你觉得文章写的对你的理解有一点帮助 xff0c 可以推荐给周围的小伙伴们 xff0c 当然 xff0c 如果
  • 用MicroPython开发ESP32- 用Thonny写程序

    陈拓 2022 06 11 2022 06 12 1 简介 在 用MicroPython开发ESP32 固件烧写与测试 https zhuanlan zhihu com p 527291091 https blog csdn net che
  • 单片机 stm32 接收数据和处理

    背景 1 单片机串口接收数据处理 xff0c 这个代码已经过很多项目验证 xff0c 没有问题 用这个代码帮了好几个同事解决数据接收久了就异常 2 这个代码做到接收和处理分开 避免不必要的处理逻辑问题 3 也可用于网口tcp xff0c u
  • odroid Xu4介绍

    Odroid xu4介绍 下面对这块开发板做一下简单的介绍 xff0c 共需要用到的人参考 从参数上来看 xff0c ODROID XU4的整体性能基本和目前的中端智能手机差不多 xff0c 它搭载了主频
  • OdroidXu4开发环境搭建

    OdroidXu4开发环境搭建 一 烧录镜像 1 SD卡烧录 首先准备一张至少16G的sd卡 镜像可以在官网 xff1a http odroid com dokuwiki doku php id 61 en odroid xu4 softw
  • 大小端:字节序与比特序

    https blog csdn net fzy0201 article details 26876711 https blog csdn net qq 40334837 article details 89042607 前言 前两天被问到一
  • VLC Buffering机制介绍

    一 简介 了解一定播放器知识的同学应该都知道 xff0c 播放器内部是有缓存的 xff08 非直播场景 xff09 缓存的作用主要是解决生产者和消费者速度的不匹配 xff0c 给用户更好的使用体验 例如 xff0c 在网络不稳定的情况下 x
  • Linux静态库和动态库学习总结

    一 废话 之前由于工作需要 xff0c 要封装一个Linux加密解密转换的动态库 xff0c 这个之前只做过Windows下面的 xff0c Linux下面还真没有做过 xff0c 之后做了整一个晚上才算做好 xff0c 不过其中也学到了不
  • UART的FIFO功能

    经常听到UART的FIFO功能 xff0c 但是从来没有真正使用过和认真思考过它的作用 正好有客户用到这个功能 xff0c 在这里做个总结 FIFO 是 First In First Out 的缩写 xff0c 它是一个具有先入先出特点的缓
  • 《C语言内核深度解析》笔记(3):指针才是C语言的精髓

    第03章 指针才是C语言的精髓 3 2 指针 int a 61 10 int p 61 amp a 指针变量p和普通变量之间没有本质区别 xff0c 都是变量空间放了一个数值 xff0c 只是p里面的数值比较特殊 xff0c 是a空间的地址