梦回大学,因它难以入睡,今一文总结之

2023-05-16

依稀记得10年前的大学第一门课就是它——c语言,而指针作为c语言的核心之一,当时一直难以理解,从而转战java。而今10余年过去了,依然还是放不下它,也同时为了阅读openJDK源码做准备,就重新拾起。其实就是因为喜欢研究底层这个癖好,才让我走上了不归路。没办法,重新拾起c语言基础。
其实对技术学习本来就应该是兴趣驱动,但目前太多人学习技术都过于功利,工作中用什么学什么,失去了自己对技术的追求,我又何尝不是呢?其实都是为了生存罢了。
不再感慨了,下面一小段代码,总结了指针的基础:

#include <stdio.h>

#include <stdlib.h>
struct Person
{
    char name;
    int age;
};

int test(int a,int b) {
    printf("%d %d\n", a, b);
    return a + b;
};

int test2(int a,int b) {
    printf("%d %d\n", a, b);
    return a - b;
};

void test3(struct Person persons) {
    persons.age = 10;
    //printf("persons.age: %d\n", persons.age);
}

void test4(struct Person *persons_p) {
    persons_p->age = 10;
    //printf("persons.age: %d\n", persons_p->age);
}

int main() {

    // 变量a,其内存地址为0x7ffee3a1ab38
    /**
     *             a
     *       0x7ffee3a1ab38
     *  |——————————————————————|
     *  |         10           |
     *  |——————————————————————|
     *
     */
    int a = 10;
    // int *pInt 定义一个指针类型变量,pInt本身会分配一个内存空间,即分配一个内存地址,pInt本身存放的值为变量a的内存地址
    // &a即取a的内存地址0x7ffee3a1ab38
    /**
     *
     *                                              a
     *            pInt ——————————————————————> 0x7ffee3a1ab38
     *         0x7ffee1ab2b30
     *  |——————————————————————|        |——————————————————————|
     *  |    0x7ffee3a1ab38    |        |         10           |
     *  |——————————————————————|        |——————————————————————|
     *
     *
     *
     */
    int *pInt = &a;

    // '*'即定义一个指针类型的变量,变量值为内存地址,'&'即取地址符,取得指定变量的内存地址
    printf("%p\n", &a);              //输出:0x7ffeef5e5b38,a的内存地址
    printf("%p\n", pInt);            //输出:0x7ffeef5e5b38,指针变量pInt的值
    printf("%p\n", &pInt);           //输出:0x7ffeef5e5b30,指针变量pInt的内存地址
    printf("%d\n", *pInt);           //输出:10,*pInt即解引用,取出其引用地址变量所存储的值,即变量a的值

    /**
     * 再看一个例子
     */
    // *p:p的值为0x11223344,它的内存地址为0x7ffee5cafb24
    int *p = 0x11223344;
    // 变量p的值赋值给a1,即a1=0x11223344
    int a1 = p;

    // a1为变量p的值0x11223344,&a1为变量a1的实际内存地址
    printf("%p\n", a1);           //输出:0x11223344
    printf("%p\n", &a1);          //输出:0x7ffee264cb24
    printf("%p\n", &p);           //输出:0x7ffee264cb28


    /**
     * '**':指向指针的指针,其实这么解释'**'的人就有点不负责任了,什么叫指向指针的指针呢?
     * 其实就是一个二维指针,看图:
     *                                                                              a
     *                                          pInt ——————————————————————> 0x7ffee3a1ab38
     *       pInt1 ——————————————————————>    0x7ffee1ab2b30
     * |——————————————————————|        |——————————————————————|        |——————————————————————|
     * |    0x7ffee1ab2b30    |        |    0x7ffee3a1ab38    |        |         10           |
     * |——————————————————————|        |——————————————————————|        |——————————————————————|
     *
     * **pInt1就代表pInt1指向pInt指针变量,*pInt1即取得pInt1的引用PInt的值,即0x7ffee3a1ab38。
     *                                  *(*pInt1)即取得pInt的引用a的值,即为10。
     *
     */
    int **pInt1 = &pInt;

    printf("*pInt1:%p\n", *pInt1);
    printf("**pInt1:%d\n", *(*pInt1));
    printf("%p\n", &pInt1);


    /**
     * 常量指针,指针常量
     */
    // 常量指针:能修改指针的指向,不能修改指针的实际值
    const int * c = 0x321312;
    //*c = 1;     // 此行报错
    // 指针常量:能修改指针的实际值,不能修改指针的指向
    int * const c1 = 1;
    //c1 = &a;    // 此行报错
    // 常量指针+指针常量:即不能修改指针指向,也不能修改值
    const int * const c2 = 2;
    //*c2 = 1;    // 此行报错
    //c2 = &a;    // 此行报错

    /**
     * 函数指针
     */
    // 即定义了返回值为int类型,参数为int,int类型的函数指针,p_test直接接收返回值
    int (*p_test) (int, int);
    p_test = test(1,2);
    p_test = test2(1,2);

    printf("p_test:%d\n", p_test);

    /**
     * 不同类型变量转换
     */
    // int 转 char,因为int类型在64位机器上占4个字节
    int *t = 0x11223344;
    // int转char,char占1个字节,所以只能取变量t中的一个字节,因为是小端机(什么是小端,自己普及),所以取得44,大端应该输出11
    char s = (char *)t;
    // int 转 long double
    long double *d = (long double *) t;

    printf("%p\n", s);           //输出:0x44
    printf("%p\n", d);           //输出:0x11223344

    /**
     * 通过指针方式操作数组
     */
    // 数组,通过指针的方式取char数组中的其中一个字符。
    char name[] = "test";
    // 这行是通过指针方式来获取name变量的第二个字符,因为char占1个字节,所以name+1即取得指向test数组的index为2的位置,
    // 即*(name + 1)取得对于的char字符e
    char i = *(name + 1);

    printf("%c\n", i);           //输出:e


    /**
     * 函数之值传递、引用传递
     */
    // 值传递,传递的变量本身,不会修改变量的值
    struct Person person1;
    person1.age = 1;
    test3(person1);
    printf("%d\n", person1.age);    // 输出:1

    // 引用传递,传递的是变量的内存地址,会修改变量的值
    struct Person person2;
    person2.age = 1;
    test4(&person2);
    printf("%d\n", person2.age);   // 输出:10

    return 0;
}

本文这小段代码挺小白的,因为对于c语言来说,我也是个小白。

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

梦回大学,因它难以入睡,今一文总结之 的相关文章

  • 利用tldr工具再也不怕记不住Linux命令

    文章目录 1 前言2 tldr3 安装4 使用 1 前言 linux命令非常多 xff0c 少用的命令往往易忘记 xff0c 甚至常用的语法较为复杂的命令也不好记住 当然有些太复杂的命令也不需要死记硬背 xff0c 我们往往会借助man命令
  • C++中的二阶构造函数

    文章目录 1 前言2 二阶构造3 总结 1 前言 构造函数用于创建对象时对象成员的初始化 xff0c 如赋初值 申请内存 加载文件等 xff0c 即是自动完成对象的初始化任务 在C 43 43 语言中 xff0c 构造函数执行顺序是 xff
  • open函数簇与fopen函数簇区别和用法

    文章目录 1 前言2 open与fopen区别2 1 标准不同2 2 层次不同2 3 适用对象不同 xff08 返回值不同 xff09 2 4 缓冲区2 5 效率不同 3 使用方法3 1 open3 2 fopen 1 前言 linux系统
  • 基于STM32的OLED多级菜单GUI实现(简化版智能手表)

    前言 xff1a 本文的OLED多级菜单UI 为一个综合性的STM32小项目 xff0c 使用多传感器 与OLED显示屏 实现智能终端 的效果 项目中的多级菜单UI使用了较为常见的结构体索引法 去实现功能与功能之间的来回切换 xff0c 搭
  • 【RTD】铂电阻测温原理与具体方法

    文章目录 1 基本原理2 铂电阻2 1 铂电阻测温原理2 2 铂电阻类型和测量方法2 2 1 两线式铂电阻2 2 2 三线式铂电阻2 2 3 四线式铂电阻 3 小结 相关文章 xff1a RTD 铂电阻测温原理与具体方法 RTD AD779
  • 【RTD】AD7793三线式铂电阻PT100/PT1000应用

    文章目录 1 AD7793简介2 AD7793 三线式铂电阻测量2 1 阻值计算 3 小结 相关文章 xff1a RTD 铂电阻测温原理与具体方法 RTD AD7793三线式铂电阻PT100 PT1000应用 RTD AD7793四线式铂电
  • 【RTD】AD7793四线式铂电阻PT100/PT1000应用

    文章目录 1 前言2 AD7793 四线式铂电阻测量2 1 阻值计算 3 小结 1 前言 上一篇文章描述的是RTD驱动芯片AD7793特点 xff0c 以及其与三线式RTD连接使用方法 本文描述四线式RTD与AD7793的使用 相关文章 x
  • 【RTD】AD7793两线式铂电阻PT100/PT1000应用

    文章目录 1 前言2 AD7793 两线式铂电阻测量2 1 阻值计算 3 小结 1 前言 上一篇文章描述的是RTD驱动芯片AD7793与四线式RTD连接使用方法 本文描述两线式RTD与AD7793的使用 相关文章 xff1a RTD 铂电阻
  • 【RTD】AD7793驱动程序

    文章目录 1 前言2 AD7793驱动程序2 1 spi访问接口2 2 寄存器和常用配置值2 3 初始化2 4 原始数据获取2 5 阻值换算 3 使用4 完整工程代码 1 前言 前面文章主要描述AD7793分别与两线 三线 四线RTD连接电
  • 【RTD】二分法查找和分段线性插值算法在RTD中应用

    文章目录 1 前言2 二分法查找2 1 复杂度2 2 实现 3 分段线性插值4 RTD实例 1 前言 处理器通过RTD采集电路 xff08 芯片 xff09 精确获得当前RTD电阻值后 xff0c 再结合RTD与温度线性关系表 xff0c
  • 24系列EEPROM/FRAM通用驱动库移植到RT-Thread

    文章目录 1 前言2 接口实现2 1 i2c收发函数实现2 2 页写延时函数2 3 写保护函数2 4 设备注册 3 对接RT Thread设备驱动3 1 标准设备驱动接口3 2 注册到RT Thread3 3 导出到msh3 4 测试 4
  • 【RT-Thread】TCA9534 8位I/O扩展器驱动软件包

    文章目录 1 简介1 1 目录结构1 2 许可证 2 芯片介绍3 支持情况4 使用说明4 1 依赖4 2 获取软件包4 3 初始化4 4 访问设备4 5 msh finsh测试查看设备注册执行sample 5 代码仓库 1 简介 tca95
  • 【代码质量】RAII在C++编程中的必要性

    文章目录 1 前言2 什么是RAII3 为什么用RAII4 RAII应用5 小结 1 前言 C C 43 43 相比其他高级编程语言 xff0c 具有指针的概念 xff0c 指针即是内存地址 C C 43 43 可以通过指针来直接访问内存空
  • C++ RAII典型应用之lock_guard和unique_lock模板

    文章目录 1 前言2 lock guard3 lock guard使用4 unique lock5 相关文章 1 前言 常用的线程间同步 通信 xff08 IPC xff09 方式有锁 xff08 互斥锁 读写锁 自旋锁 xff09 屏障
  • 基于STM32的实时操作系统FreeRTOS移植教程(手动移植)

    前言 xff1a 此文为笔者FreeRTOS专栏 下的第一篇基础性教学文章 xff0c 其主要目的为 xff1a 帮助读者朋友快速搭建出属于自己的公版FreeRTOS系统 xff0c 实现后续在实时操作系统FreeRTOS上的开发与运用 操
  • 通过sysinfo获取Linux系统状态信息

    系统运行状态信息是我们关注的重点 xff0c 通过当前系统的输出信息 xff0c 如内存大小 进程数量 运行时间等 xff0c 以便分析CPU负载 软硬件资源占用情况 xff0c 确保系统高效和稳定 Linux系统中 xff0c 提供sys
  • Keil AC5/Keil AC6/IAR指定数据绝对存储地址

    文章目录 1 前言2 实现方法3 例子 1 前言 编译过程中 xff0c 指定数据绝对存储地址在实际项目中会经常使用到或者必须用到 xff0c 这样使得项目实现某些功能可以非常灵活 xff0c 常用的场景有 xff1a IAP升级时候 xf
  • 嵌入式开发常用到的在线工具

    文章目录 IP地址计算常用加解密 xff0c AES DSE Base64 MD5异或 xff08 BCC xff09 校验CRC计算十六进制格式化字符串Json格式化HTML运行器常用在线编译器 xff08 C C 43 43 C JAV
  • STM32H7xx 串口DMA发送&接收(LL库)

    文章目录 1 前言2 STM32H7实现2 1 关键步骤2 2 注意事项 3 代码仓库 1 前言 关于串口DMA收发实现 xff0c 不同CPU其套路都是类似的 xff0c 不同之处在于寄存器配置 依赖BSP库等差异 串口DMA收发详细实现
  • 正交编码器溢出处理

    文章目录 1 正交编码器1 1 参数特性1 2 应用范围 2 正交编码器使用2 1 溢出问题2 2 中断模式2 3 循环模式延伸 1 正交编码器 正交编码器一般指的是增量式光栅 xff08 磁栅 xff09 编码器 xff0c 通常有三路输

随机推荐

  • PX4多旋翼期望姿态矩阵生成算法

    1 PX4多旋翼期望姿态生成算法 1 1 求期望体轴X轴向量1 2 求期望体轴Y轴向量1 3 求期望姿态矩阵1 4 求期望姿态角 1 PX4多旋翼期望姿态生成算法 PX4多旋翼期望姿态生成采用旋转矩阵方法 xff0c 基本思路为根据外环解算
  • git安装

    Git介绍 分布式 xff1a Git版本控制系统是一个分布式的系统 xff0c 是用来保存工程源代码历史状态的命令行工具 保存点 xff1a Git的保存点可以追踪源码中的文件 并能得到某一个时间点上的整个工程项目的状态 xff1b 可以
  • linux更改ssh连接方式将publickey改为用户名密码登录

    1 vim etc ssh sshd config 2 PermitRootLogin no 改为 PermitRootLogin yes 3 service restart sshd
  • dsp2812 pmsm foc之速度环电流环

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 速度环PI 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • leetcode(c++)

    放假没事刷几道leetcode xff0c 一些常见典型题的答案和解析 平时python用的比较多 xff0c 但分析复杂度的时候用python编程不方便 xff0c 所以刷题的时候用了c 43 43 C 43 43 基础 C 43 43
  • 基于STM32的超声波雷达项目【可拟合构建平面地图】(代码开源)

    前言 xff1a 本文为手把手教学基于STM32的超声波雷达 项目 HC SR04雷达 本次项目采用的是STM32作为MCU xff0c 搭配常用的HC SR04超声波模块与舵机SG90实现模拟雷达检测 的效果 模拟了雷达图UI 可以拟合构
  • android sdk manager不显示更新,只显示已安装,解决办法

    启动 Android SDK Manager xff0c 打开主界面 xff0c 依次选择 Tools Options xff0c 弹出 Android SDK Manager Settings 窗口 xff1b 在 Android SDK
  • detectron2学习:KeyError: “No object named ‘XXXXX‘ found in ‘BACKBONE‘ registry!“

    问题来源 在使用FB的框架detectron2改写模型的时候碰到了KeyError 34 No object named 39 XXXXX 39 found in 39 BACKBONE 39 registry 34 的bug 分析 xff
  • linux内核网络协议栈--linux网络设备理解(十三)

    网络层次 linux网络设备驱动与字符设备和块设备有很大的不同 字符设备和块设备对应 dev下的一个设备文件 而网络设备不存在这样的设备文件 网络设备使用套接字socket访问 xff0c 虽然也使用read write系统调用 xff0c
  • makefile使用--命令(三)

    一 Make的概念 Make这个词 xff0c 英语的意思是 34 制作 34 Make命令直接用了这个意思 xff0c 就是要做出某个文件 比如 xff0c 要做出文件a txt xff0c 就可以执行下面的命令 span class t
  • 【笔记】ubuntu18.04 ros melodic turtlebot3 源码下,导航gmapping仿真

    编写本笔记原因 xff1a 源码编译没问题 xff0c 但是在运行roslaunch turtlebot3 slam turtlebot3 slam launch slam methods 61 cartgrapher时出现下面这个错误 x
  • 从kernel层面分析synchronized、volatile,进大厂必备硬核小伎俩(上)

    synchronized volatile对于java程序员来说再熟悉不过了 xff0c 但 是你知道这两个关键字底层是如何实现的吗 xff08 甚至在操作系层面是 通过什么指令来实现的 xff09 xff1f 以及与其相关的术语 xff1
  • linux内核原理剖析——内存寻址(一)

    最近总想分享点硬核的原创文章出来 xff0c 一是硬核技术是一个程序员真正应该修炼 的内功 xff1b 二是修炼硬核技能是通往架构师领域的必经之路 本系列文章将分享关 于linux内核设计原理相关的内容 xff0c 希望能打通我们的七经八脉
  • linux内核原理剖析——磁盘寻址、分区

    继上一篇 lt lt linux内核原理剖析 内存寻址 xff08 一 xff09 gt gt 之后 xff0c 发现大家 对底层技术关注度比较高之后 xff0c 今天继上一篇的内存寻址一文后 xff0c 补 充一篇关于更为底层的 磁盘寻址
  • Redis集群从搭建到设计,总有一些你不曾了解的东西

    Redis集群是Redis服务器高可用的设计模型 xff0c 也是我们线上应用最多的Redis部署架构 本文主要针对Redis集 群入门搭建 Redis集群节点及其底层数据结构 hash槽 重新分片 消息等核心操作及原理进行分享 本文是基于
  • java成神之路学习线路

    自己总结了下java后端学习线路 xff0c 也是我八年的工作学习积累 xff0c 供各位同学参考 线路图还不全 xff0c 之后我会逐渐补全 下面思维导图中的技术 xff0c 我争取在2020年的博文中都分享给大家 xff0c 形成一个系
  • 实时操作系统系统FreeRTOS的学习(1)——任务

    前言 xff1a 在本专栏 FreeRTOS 中已经为读者朋友详细介绍了FreeRTOS以及关于FreeRTOS于STM32下的手动移植 从今天开始将带领大家系统学习FreeRTOS xff0c 这款常见的轻量化小型 实时操作系统 当然 x
  • 万字博文,Spring系列之抽丝剥茧Spring源码(一)

    当5G来临 xff0c 当211高校已经开启人工智能课程 xff0c 当甲骨文大批量裁员 xff0c 大家的心是否像我一样为之一颤呢 xff1f 当科技不断发展 xff0c 技术迅速迭代 xff0c 程序员愈发年轻化的今天 xff0c 而作
  • 面试大厂必读、小厂吊打面试官必读书籍推荐

    通过我多年在互联网公司摸爬滚打 xff0c 以及近三年一直担任公司技术面试管经历 xff0c 本文结合我的工作经历 xff0c 分享给众多从事以及将要从事java后端软件开发的程序员们推荐一些必读书籍 xff0c 但并不只限于技术类书籍 深
  • 梦回大学,因它难以入睡,今一文总结之

    依稀记得10年前的大学第一门课就是它 c语言 xff0c 而指针作为c语言的核心之一 xff0c 当时一直难以理解 xff0c 从而转战java 而今10余年过去了 xff0c 依然还是放不下它 xff0c 也同时为了阅读openJDK源码