韦东山老师嵌入式C语言加强学习笔记

本文围绕嵌入式C语言编程展开,介绍了变量与指针的概念及使用,阐述了sizeof和关键字(volatile、const、static、extern)的用法和作用,还讲解了字节对齐、类型转换等知识。此外,探讨了全局变量、局部变量的初始化,main函数调用,局部变量存储位置及栈的作用等核心问题。


这是学习韦东山老师嵌入式C语言的视频,自己整理的学习笔记
原md文件已上传gitee:

1. 变量与指针

2个口诀:

  • 变量变量,能变,就是能读能写,必定在内存里
  • 指针指针,保存的是地址,32位处理器中地址都是32位的,无论是什么类型的指针变量,都是4字节

变量

变量变量,能变,就是能读能写,必定在内存里

  • 能变:变量,顾名思义,其值可以在程序执行过程中发生变化。这意味着变量是可以读写的,即我们可以获取变量的当前值(读操作),也可以改变变量的值(写操作)。
  • 在内存里:变量存储在程序的内存空间中。程序运行时,操作系统会为程序分配一定的内存空间,变量就被分配在这块内存空间中的某个位置。通过变量的地址,我们可以访问和修改它的值。

在嵌入式C语言编程中,由于内存资源有限,合理地使用和管理变量显得尤为重要。通常,我们需要考虑变量的生命周期、作用域以及存储类别,以确保程序的高效运行和内存的有效利用。

指针

指针指针,保存的是地址,32位处理器中地址都是32位的,无论是什么类型的指针变量,都是4字节

  • 保存的是地址:指针是一个特殊的变量,它存储的是另一个变量的内存地址。通过这个地址,我们可以间接地访问和修改该变量的值。
  • 32位处理器中地址都是32位的:在32位处理器上,内存地址通常是一个32位的整数。这意味着无论我们指向何种类型的变量(如int、char、float等),指针变量本身都占用4个字节(32位)的内存空间来存储这个地址。

在嵌入式C语言编程中,指针的使用非常广泛,特别是在操作硬件寄存器、动态内存分配以及数据结构管理等方面。然而,由于嵌入式系统的内存限制和实时性要求,指针的使用也需要格外小心,以避免内存泄漏、野指针等问题。

示例

下面是一个简单的C语言示例,展示了变量和指针的使用:

#include <stdio.h>

int main() {
   
   
    int myVariable = 10; // 定义一个整型变量并初始化
    int *myPointer; // 定义一个整型指针变量

    myPointer = &myVariable; // 将指针指向myVariable的地址

    printf("Value of myVariable: %d\n", myVariable); // 直接访问变量值
    printf("Address of myVariable: %p\n", (void *)&myVariable); // 打印变量地址
    printf("Value pointed by myPointer: %d\n", *myPointer); // 通过指针间接访问变量值
    printf("Address stored in myPointer: %p\n", (void *)myPointer); // 打印指针存储的地址值

    return 0;
}

2. sizeof和关键字

2.1 sizeof

sizeof是一个运算符,用于计算变量、类型或对象在内存中所占的字节数。对于指针变量,sizeof(p)返回的是指针变量本身所占用的内存大小,而不是它所指向的内存区域的大小。而sizeof(*p)则返回指针p所指向的对象的大小。

示例:

int arr[10] = {
   
   0};
int *p = arr;

printf("Size of pointer p: %zu bytes\n", sizeof(p)); // 输出指针p的大小
printf("Size of object pointed by p: %zu bytes\n", sizeof(*p)); // 输出指针p所指向的int类型对象的大小
printf("Size of array arr: %zu bytes\n", sizeof(arr)); // 输出整个数组的大小

2.2 volatile

volatile是一个类型限定符,用于告诉编译器不要对某个变量进行特定的优化,因为该变量的值可能在程序的正常控制流之外被改变。这通常发生在以下几种情况:

  1. 硬件寄存器访问:在嵌入式编程中,程序员经常需要直接访问硬件寄存器。这些寄存器的值可能会在任何时候由硬件自身改变,而程序并不知道这种改变。使用volatile可以确保每次访问该变量时都会从内存中读取其实际值,而不是使用编译器可能为其存储的缓存值。

  2. 中断服务程序:当中断发生时,中断服务程序(ISR)可能会修改某些全局变量的值。如果这些变量没有被声明为volatile,编译器可能会认为这些变量在中断之外不会被修改,从而进行优化,导致程序行为不正确。

  3. 多线程环境:在多线程环境中,一个线程可能修改了一个变量的值,而另一个线程需要读取这个值。如果不使用volatile,编译器可能会优化掉对变量的多次读取,导致第二个线程读取到的不是最新的值。

  4. 外部设备或信号:当变量与外部设备或信号(如传感器输入)相关联时,这些设备或信号可能会在任何时候改变变量的值。

使用volatile可以确保编译器在每次使用变量时都进行实际的内存访问,从而避免了由于优化而导致的潜在问题。但是,滥用volatile

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值