🍃大小端的区别

大端: 低字节存储在高地址,高字节存储在低地址
小端: 低字节存储在低地址,高字节存储在高地址


🍃写一段程序获取CPU大小端

union
{
    int a;
    char b;
}c;

#define LITTLE_ENDIAN 0
#define BIG_ENDIAN 1

int check_cpu()
{
    c.a = 0x12345678;
    if(c.b == 0x78)
    {
        return LITTLE_ENDIAN;
    }
    else
    {
        return BIG_ENDIAN;
    }
}

🍃volatile的作用有哪些?

1、禁止编译器对变量做缓存。volatile 强制编译器:每次访问变量都必须从内存中读取,每次修改都必须写入内存,绝不使用寄存器缓存。在读取硬件寄存器时,值可能会被硬件修改,需要每次都从硬件寄存器中读取
2、禁止编译器对变量做指令重排
3、避免编译器删除未使用的变量。这个变量可能是给中断或者硬件使用


🍃static关键字的作用有哪些?

1、static声明的变量在函数内多次调用保持值不变且只会初始化一次
2、static声明的全局变量只能在本文件使用
3、static声明的函数只能在本文件使用


🍃static定义的int型全局变量,不初始化,值是多少?

1、所有存储在全局 / 静态区的变量(无论是否加 static),不手动初始化,编译器会在程序启动前(main 函数执行前)自动将其初始化为0,无论全局变量是否有加static,都会初始化为0.


🍃请问下面三种变量的区别?

  • int const p(等价于 const int p)

    • 解读:指向「常整型」的指针(指针可变,指向的内容不可变)
    • 拆解:const 右侧是 int → 修饰 “指针指向的整型值”,所以:
    • ✅ 可以修改指针 p 本身(让它指向其他地址);
    • ❌ 不能通过指针 p 修改指向的整型值。
  • int *const p

    • 正确解读:指向「整型」的常指针(指针不可变,指向的内容可变)
    • 拆解:const 右侧是 p → 修饰 “指针变量 p 本身”,所以:
    • ❌ 不能修改指针 p 本身(不能让它指向其他地址);
    • ✅ 可以通过指针 p 修改指向的整型值。
  • int const p

    • 正确解读:指向「“指向整型的常指针”」的指针(二级指针)
    • 拆解(从内到外):最内层 int const:是 “指向整型的常指针”(记为 q,q 不可改指向,但 q 可改);外层 p:p 是一个普通指针,指向 int const 类型的变量(即 q);
    • ✅ 可以修改 p 本身(让它指向其他 int *const 类型的指针);
    • ❌ 不能通过 p 修改它指向的那个 “常指针”(即 p 不可改指向);
    • ✅ 可以通过 **p 修改最终指向的整型值。

🍃一个可执行程序都分为哪些段?

  • 代码段(.bss)

    • 存放程序的可执行指令(比如函数、逻辑运算、循环等代码)
  • 数据段(.data)

    • 存放程序中已初始化的全局变量和静态变量(非 const)
  • 未初始化数据段(.bss)

    • 存放未初始化的全局变量、静态变量,以及初始值为 0 的全局 / 静态变量
  • 只读数据段(.rodata)

    • 存放只读的常量数据。
  • 栈段(stack)

    • 存放局部变量、函数参数、返回地址、函数调用上下文等。生长方向从高地址到低地址
  • 堆段(heap)

    • 存放程序运行时动态分配的内存(手动申请、手动释放)。生长方向从低地址到高地址