当前位置: 首页 > news >正文

嵌入式八股文篇——P1 关键字篇

嵌入式八股文篇--P1 关键字篇

目录

嵌入式八股文篇--P1 关键字篇

1. Continue

2. Break

3. Return

4. Goto

5. Volatile(编译优化阶段)

6.Struct(结构体) (C和C++区别,求结构体大小,使用的注意事项)

7.class和struct的区别?

8.Union(联合体)

8.1.联合体union和结构体struct的区别:

8.2.联合体一般可以用来判断大小端问题:

8.3.大小端转换问题:

8.4.计算占用空间大小问题:

9.Enum

10.Typedef

11.Const (C中的变量:局部,函数形成,返回值,指针,typedef的区别,数组大小定义,case C++:常函数,常对象)

12.Extern(链接阶段)

13.Register

14.Auto

15.Static (c语言:变量、函数 C++:类中变量、类中静态成员函数)

16.Swicth case

17.Do while

18.Sizeof

19.New/malloc delete/free(指明大小,返回值,初始化)

20.左值和右值是什么?

21. 什么是短路求值

22.++a和a++区别

23.局部变量能不能和全局变量重名?

24. gets和scanf函数的区别(空格,输入类型,返回值)

25. C语言编译过程中,volatile关键字和extern关键字分别在哪个阶段起作用?

26. Printf()函数的返回值

27.C语言中不能用来表示整常数的进制是二进制

28.char *str1 = “hello”和char str2[] = “hello”


1. Continue

continue 仅用于循环语句,作用是跳过本次循环剩余语句,直接进入下一次循环条件判断(不终止整个循环),核心是 “局部跳过当前轮,循环整体仍继续”。

总结:跳本轮回判(跳过本次循环,进入下一轮判断)

2. Break

break 仅用于循环(for/while/do-while)或 switch 语句,作用是强制跳出最近包含它的那一层结构:在循环中,终止当前循环的所有后续迭代;在 switch-case 中,终止当前 case 的执行并跳出整个 switch。若结构嵌套(如 for 循环内有 switch),break 仅影响直接包含它的内层结构,不影响外层。需特别注意:switch 中若缺少 break,会从匹配的 case 开始 “穿透执行” 所有后续分支(包括 default),直到遇到 break 或 switch 结束。

与 continue 对比:break 是 “终止本层结构”,continue 是 “跳过本次循环”。

总结:破层终止(破坏当前层级结构并终止其执行)

3. Return

return 是函数体专用的关键字,作用是立即终止当前函数的所有执行(包括函数内的循环、分支等),退出函数并返回至调用处;若函数为非 void 类型,需携带匹配类型的返回值传递给调用者,void 类型则可直接用 return; 实现提前退出。

总结:退函返值(退出函数并返回值)

4. Goto

goto 是用于当前函数内的无条件跳转语句,可直接跳转到预定义的标签(格式为标签名:)处执行,无需遵循正常代码顺序。主要用途是跳出多层循环或集中处理错误,但滥用会导致逻辑混乱,且不能跨函数跳转。

总结:函数内跳标签(慎用于多层循环跳出)

5. Volatile(编译优化阶段)

volatile 作用于编译优化阶段,用于修饰可能被当前代码外因素(如中断、多线程、硬件寄存器)修改的变量,强制编译器每次使用变量时都从内存重新读取,而非使用寄存器缓存的旧值,避免数据失效。

总结:强读内存禁优化

6.Struct(结构体) (C和C++区别,求结构体大小,使用的注意事项)

struct(结构体)在 C 与 C++ 中差异显著:C 语言结构体仅能包含数据成员,不可有函数、不支持继承,使用时需加struct或通过typedef取别名,成员默认 public 且不可初始化,空结构体大小为 0;C++ 结构体可包含函数、支持继承,可直接用结构体名定义变量,支持权限控制(public/private 等),允许成员初始化,空结构体大小为 1。计算结构体大小时需遵循字节对齐规则(总大小为最大成员类型字节数的整数倍,成员偏移量为自身类型字节数的整数倍)。

总结:C 简 C++ 强,大小看对齐

7.class和struct的区别?

class 与 struct 的核心区别集中在权限与功能场景:从访问权限看,class 成员默认 private(仅类内可访问),struct 默认 public(外部可直接访问);从继承权限看,class 默认 private 继承(子类无法直接访问父类成员),struct 默认 public 继承(子类可直接访问父类 public 成员);从功能场景看,class 更侧重封装 “对象实现”(隐藏内部逻辑),struct 更侧重定义 “数据结构”(暴露数据),且 class 可用于定义模板,struct 不支持此功能。

总结:权默异(class 私 struct 公),功能别(class 能模板 struct 不能)

8.Union(联合体)

8.1.联合体union和结构体struct的区别:

union(联合体)与 struct(结构体)的核心区别在于内存分配方式:联合体的所有成员共享同一块内存空间,修改任一成员会直接接影响其他成员;而结构体的成员各自占独立独立内存,总空间是各成员内存的叠加(需考虑字节对齐),成员间数据互不干扰。

总结:联共内(成员共享内存),结叠存(成员内存叠加)

8.2.联合体一般可以用来判断大小端问题:

联合体是判断大小端的常用工具:利用其成员共享内存的特性,通过多字节数据在内存中的存储顺序区分 —— 大端字节序中高字节存低地址、低字节存高地址;小端字节序中低字节存低地址、高字节存高地址。

示例中,联合体myshort tchar b[2]共享内存,当t=0X0102时:若b[0]=0x01b[1]=0x02,为大端;若b[0]=0x02b[1]=0x01,则为小端。

总结:联共内存判端序(高存低为大,低存低为小)

8.3.大小端转换问题:

大小端转换主要通过位运算(与运算 + 位移运算) 实现,核心思路是将数据各字节的存储位置按需求互换。以 32 位数据为例,需将原本 0-7 位(最低字节)移到 24-31 位(最高字节)、8-15 位移到 16-23 位、16-23 位移到 8-15 位、24-31 位(最高字节)移到 0-7 位。

如代码所示,先通过&运算提取各字节(如value & 0x000000ff提取 0-7 位),再用<</>>将其移到目标位置,最后用|运算合并各字节,完成 32 位数据的大小端转换。

//32位大小端交换
int swap(int value)
{
value=((value & 0x000000ff)<<24)|
((value & 0x0000ff00)<<8)|
((value & 0x00ff0000)>>8)|
((value & 0xff000000)>>24);
return value;
}

8.4.计算占用空间大小问题:

对于不同位的操作系统,个别数据类型数据大小不一样,

Long 和unsigned long在32位中是4个字节

在64位中是8个字节

计算联合体(union)和结构体(struct)的占用空间需遵循字节对齐规则,核心要点如下:

  1. 基础规则
    • 总大小必须是成员中最大类型字节数的整数倍
    • 每个成员的偏移量(距起始地址)必须是自身类型字节数的整数倍
  1. 联合体计算:因所有成员共享内存,大小需同时满足:①能容纳最大成员(含数组总大小);②是最大成员类型字节数的整数倍。例如union {double i; int k[5];}中,int[5]占 20 字节,double为 8 字节,故总大小为 24(8 的 3 倍,且≥20)。
  2. 结构体计算:成员内存叠加,需注意:①嵌套联合体时,其起始偏移量需符合自身最大成员类型的对齐要求;②最终总大小是结构体中最大类型(含嵌套类型)字节数的整数倍。例如含int(4 字节)、24 字节联合体(最大成员 8 字节)、double(8 字节)的结构体,总大小为 40(8 的 5 倍)。

总结:对齐看最大,联取容大值,结叠算偏移

9.Enum

enum(枚举)是用于定义离散常量集合的类型,内部常量默认从 0 开始依次自增(可手动指定初始值打破自增序列),为离散值提供语义化名称,增强代码可读性。例如enum Week {Mon, Tue, Wed};中,Mon=0、Tue=1、Wed=2。

总结:枚举常量自增(默认从 0 起,可手动指定)

10.Typedef

typedef 是编译期关键字,用于给已有类型起别名,具有类型检查功能,可简化数组、指针、结构体等复杂类型的使用,且在其作用域内有效,不能在函数内定义;与 #define(预处理指令,仅做字符串替换,无类型检查)的核心区别在于:定义指针时,typedef 能保证所有变量均为指针类型(如 typedef int* myptr; myptr a,b;ab 都是指针),而 #define 可能导致部分变量类型不符合预期(如 #define myptr int*; myptr a,b;b 是 int 类型)。

总结:类型别名(编译检查,指针定义无歧义)

11.Const (C中的变量:局部,函数形成,返回值,指针,typedef的区别,数组大小定义,case C++:常函数,常对象)

const 是用于定义 “只读实体” 的关键字,在 C 和 C++ 中功能各有侧重:在 C 中,可修饰变量(表值不可改)、函数参数(表函数内不可改参数)、函数返回值(表返回内容不可改),修饰指针时分 “常量指针”(内容不可改)、“指针常量”(地址不可改)、“完全只读指针”(地址和内容均不可改);需注意 C 中 const 变量非编译期常量,不能用于定义数组大小或 switch case 常量,推荐用 #define 定义此类常量。在 C++ 中,除兼容 C 的功能外,还可修饰 “常函数”(类成员函数,仅读类成员不修改)和 “常对象”(仅调用常函数)。存储上,局部 const 变量存栈(C 中可间接修改),已初始化的全局 const 变量存只读数据段(不可修改)。

总结:定义只读实体(C 限变量指针,C++ 加常函数对象)

12.Extern(链接阶段)

extern 是作用于链接阶段的关键字,核心用于跨文件引用实体:一是声明外部变量(告知编译器变量在其他文件已定义并分配内存,本文件仅使用,不可初始化,且全局变量不能定义在头文件,避免多文件包含报 “multiple define” 错误);二是声明外部函数(告知编译器函数在其他文件定义,本文件可调用);此外,extern "C" 专门用于 C++ 中按 C 语言规则编译代码,解决 C++ 名称修饰导致的跨语言调用链接失败问题。

总结:链接声明外部(变量函数跨文件,C++ 用 "C" 调 C)

13.Register

register 是向编译器发起的 “建议性声明”,希望将局部整数类型变量存储到 CPU 寄存器中(利用寄存器高速访问特性提升效率),但编译器可根据寄存器资源情况决定是否采纳;需注意,register 不可修饰浮点数、数组等类型,也不能对被修饰变量执行取地址操作(&)。

总结:建议存寄存器(限局部整数,禁取地址)

14.Auto

auto 是局部变量的默认存储类型(通常可省略),表示 “自动存储期”—— 变量存储在栈中,函数执行结束后会自动销毁,仅在定义它的局部作用域内有效,无法修饰全局变量或静态变量。

总结:局部默认存栈(自动销毁,限局部域)

15.Static (c语言:变量、函数 C++:类中变量、类中静态成员函数)

static 关键字在 C 和 C++ 中功能丰富,核心是限定作用域与延长生命周期:

C 语言中

  1. 静态变量
    • 静态局部变量:仅在函数内可见,生命周期与程序一致(函数退出不销毁),仅初始化一次(保留上次值),存储在数据段 /.bss 段。
    • 静态全局变量:仅在本文件内可见(其他文件无法通过extern访问),生命周期与程序一致,避免全局命名冲突。
  1. 静态函数:仅在本源文件内可调用,其他文件可定义同名函数,实现 “文件私有”。

C++ 扩展(类中)

  1. 静态成员变量:所有对象共享同一块内存,不占类空间,需在类外单独定义(类内仅声明,不可在构造函数中初始化)。
  2. 静态成员函数:属于类而非对象,无this指针,仅能访问静态成员,不能访问非静态成员(面试高频考点)。

总结:静存久,域受限;类静共,无 this

16.Swicth case

switch case 是多分支条件判断结构,核心规则有三:①表达式结果必须是整数 / 字符类型(不可为浮点数或字符串);②case 后必须是常量(不可为变量或字符串,字符因本质是整数可使用);③若无 break,会从匹配 case 开始 “穿透执行” 所有后续分支(直至 break 或结构结束)。

总结:整表常量判,break 防穿透

17.Do while

do while 是一种循环结构,核心逻辑是 “先执行循环体,再判断条件”—— 无论条件是否成立,循环体至少会执行一次,仅当条件为假时才退出循环,适用于需先执行再判断的场景(如输入验证)。

总结:先执行再判(循环体至少一次)

18.Sizeof

sizeof 是编译期关键字,核心用于计算变量 / 类型的内存占用大小,关键特性与差异如下:

  1. strlen 区别:sizeof 算内存大小(含字符串 \0)、编译期计算、是关键字;strlen 算字符串有效长度(不含 \0)、运行期计算、是函数。
  2. 特殊计算:32 位机下指针大小恒为 4 字节;引用大小与对应类型一致;数组大小 = 类型字节数 × 元素数(如 int[5] 为 20 字节);sizeof(a++) 不执行表达式(a 值不变)。
  3. 特殊值:sizeof("\0") 为 2(含两个 \0),sizeof('\0') 为 4(字符按 int 存储),sizeof(void) 出错或为 1;自定义宏 mysizeof 可通过地址差模拟其功能。

总结:编译算内存(含 \0,不执行表达式,指针 32 位恒 4)

19.New/malloc delete/free(指明大小,返回值,初始化)

new/deletemalloc/free 均用于动态内存管理,但核心差异显著:

  • 性质new/delete 是 C++ 运算符,malloc/free 是 C 标准库函数。
  • 功能new 申请内存后自动调用构造函数初始化,delete 先调用析构函数再释放内存;malloc 仅申请内存(需显式指定大小),free 仅释放内存,均不处理构造 / 析构。
  • 使用new 返回对应类型指针(无需强转),malloc 返回 void*(需显式强转)。

总结:new 带构造免强转,malloc 仅申请需大小

20.左值和右值是什么?

左值和右值是 C/C++ 中用于区分表达式或变量 “可被操作特性” 的概念,核心差异在于是否可被修改、能否放在赋值运算符左侧

  • 左值:本质是 “有明确内存地址、可被修改” 的实体,能出现在赋值运算符左侧(也可出现在右侧)。比如普通变量(int a)、数组元素(arr[0])等,其值可通过赋值改变;但需注意,数组名是 “常量左值”,虽有内存地址,却不可被修改(如str++str = new char[5]均报错)。
  • 右值:本质是 “临时结果、无持久内存地址、不可被修改” 的实体,仅能出现在赋值运算符右侧。比如字面量(10"abc")、表达式结果(a + b)、后置自增(a++,因其返回的是自增前的临时值)等,无法作为赋值对象(如i++ = 5报错)。

核心规则:左值可作右值,右值不能作左值;特殊左值(如数组名)虽有地址,但不可修改。

总结:左值可改放左边,右值只读放右边(数组名是特殊左值,不可改)

21. 什么是短路求值

短路求值是逻辑运算符(|| 逻辑或、&& 逻辑与)的核心特性:在判断表达式结果时,若通过前面的部分已能确定最终结果,就不再执行后续部分,直接返回结果,以此提升效率。具体规则与示例如下:

1. 逻辑或(||):一真则真,遇真即停

只要左侧表达式为 “真”,就无需判断右侧表达式,直接返回 “真”;仅当左侧为 “假” 时,才执行右侧表达式进一步判断。

  • 示例 a>0 || b++>2:左侧 a>02>0)为真,直接确定整体为真,右侧 b++ 未执行,故 b 仍为 3。
  • a<0 || b++>2:左侧 a<02<0)为假,需执行右侧 b++b 从 3 变为 4,最终整体为真。

2. 逻辑与(&&):一假则假,遇假即停

只要左侧表达式为 “假”,就无需判断右侧表达式,直接返回 “假”;仅当左侧为 “真” 时,才执行右侧表达式进一步判断。

  • 示例 a>0 && b++>2:左侧 a>0 为真,需执行右侧 b++b 从 4 变为 5,最终整体为真。
  • a<0 && b++>2:左侧 a<0 为假,直接确定整体为假,右侧 b++ 未执行b 仍为 5。

总结:|| 遇真停,&& 遇假停(后续表达式不执行)

22.++a和a++区别

++a(前置自增)与 a++(后置自增)的核心区别在于自增操作的执行时机、返回值类型及效率,具体差异如下:

1. 执行时机与返回值:核心差异

两者最终都会让 a 的值 + 1,但 “何时 + 1” 和 “返回什么值参与后续运算” 完全不同:

  • a++(后置自增):先取值,后自增步骤:①先将 a 当前的值存入临时变量(返回的是自增前的 “旧值”);②再对 a 本身执行 + 1 操作;③后续运算使用的是临时变量中的 “旧值”。例:int a=1; int b=a++; → 先将 a=1 存入临时变量给 b(故 b=1),再让 a 自增为 2。
  • ++a(前置自增):先自增,后取值步骤:①先对 a 本身执行 + 1 操作;②直接返回 a引用(无需临时变量,返回的是自增后的 “新值”);③后续运算使用的是 a 自增后的 “新值”。例:int a=1; int b=++a; → 先让 a 自增为 2,再将 a=2 直接给 b(故 b=2)。

2. 效率差异:前置自增更高

  • a++ 需额外开辟临时变量存储自增前的旧值,运算结束后还要释放临时空间,存在额外开销。
  • ++a 直接操作原变量并返回引用,无需临时变量,效率更高。(尤其在循环(如 for 循环)或高频调用场景中,++a 的效率优势更明显。)

3. 复杂运算示例:结合返回值特性分析

所有运算均基于 “返回值” 进行,需明确两者返回的是 “旧值” 还是 “新值引用”:例:int i=1; printf("%d\n", ++i / i--);

  • 第一步:++i 先执行 → i 自增为 2,返回 i 的引用(此时引用指向 i=2)。
  • 第二步:i-- 执行 → 先将 i=2 存入临时变量(返回旧值 2),再让 i 自减为 1(此时 ++i 的引用指向 i=1)。
  • 第三步:运算 ++i 的返回值(1) / i-- 的返回值(2) → 1/2=0(整数除法),最终输出 0。

总结:a++ 先值后增(需临时变量,效率低),++a 先增后值(无临时变量,效率高)

23.局部变量能不能和全局变量重名?

局部变量与全局变量可以重名,但会触发 “局部变量屏蔽全局变量” 的规则 —— 在局部变量的作用域内(如函数、代码块),代码默认操作的是局部变量,全局变量会被 “隐藏”,无法直接访问。

若需在局部作用域中使用被屏蔽的全局变量,可通过 extern 关键字声明该变量为 “外部全局变量”,明确指定使用全局版本。

示例如下:

#include <stdio.h>
int a = 1; // 全局变量avoid test() {int a = 2; // 局部变量a(与全局变量重名)printf("局部变量a:%d\n", a); // 默认操作局部变量,输出2// 用extern声明,显式使用全局变量{extern int a; printf("全局变量a:%d\n", a); // 输出1}
}int main() {test();return 0;
}

总结:可重名,局部屏蔽全局;用 extern 显式访全局

24. gets和scanf函数的区别(空格,输入类型,返回值)

getsscanf 均为输入函数,但在处理方式、适用场景和返回值上差异显著,核心区别如下:

  1. 空格处理
    • gets完整读取一行输入(包括空格),直到遇到换行符(\n)才停止,且会自动丢弃换行符。
    • scanf 遇空格、制表符或换行符时默认视为输入分隔符,会停止当前变量的输入(除非用格式控制符如 %[^\n] 特殊处理)。
  1. 输入类型
    • gets 仅用于读取字符串(char*),功能单一。
    • scanf 是格式化输入函数,可通过格式符(%d%f%s 等)读取整数、浮点数、字符串等多种基础类型。
  1. 返回值
    • gets 返回 char* 指针:成功时返回输入字符串的地址,失败(如读入错误)时返回 NULL
    • scanf 返回 int 整数:表示成功赋值的变量个数,遇到文件结尾时返回 EOF(通常为 -1)。

示例对比:

char str1[20], str2[20];
gets(str1);       // 输入 "hello world",str1 会存储完整字符串(含空格)
scanf("%s", str2); // 输入 "hello world",str2 仅存储 "hello"(遇空格停止)

总结:gets 读整行含空格(仅字符串),scanf 遇空格停(多类型),返回值类型不同

25. C语言编译过程中,volatile关键字和extern关键字分别在哪个阶段起作用?

在 C 语言编译过程中,volatileextern 关键字的作用阶段不同:

  • volatile:作用于编译阶段。它告诉编译器,被修饰的变量可能被意外修改(如硬件中断、多线程等),禁止编译器对该变量进行优化(如缓存变量值到寄存器、省略重复读取等),确保每次访问都直接从内存中读取最新值。
  • extern:作用于链接阶段。它用于声明外部变量或函数,告知编译器 “该实体在其他文件中定义”,在链接时由链接器根据声明找到对应的定义并完成地址关联,实现跨文件引用。

总结:volatile 防编译优化(编译期),extern 助跨文件链接(链接期)

26. Printf()函数的返回值

printf() 函数的返回值是成功输出的字符总数(包括数字、字母、空格、换行符 \n 等所有输出的字符),若输出失败则返回负数。

具体示例解析:

  1. printf("%d\n", 241);输出内容为 "241\n",包含 3 个数字字符 + 1 个换行符 \n,共 4 个字符,故返回值为 4。
  2. printf("%d\n", printf("%d", 241));
    • 内层 printf("%d", 241) 输出 "241"(3 个字符),返回值为 3。
    • 外层 printf 输出内层返回的 3 加换行符 \n,即 "3\n"(2 个字符),但整体输出结果为 "2413\n",外层函数返回值为 2。
    • 最终屏幕显示 "2413"(换行被包含在输出中)。
  1. printf("%d\n", printf("%d\n", 241));
    • 内层 printf("%d\n", 241) 输出 "241\n"(4 个字符),返回值为 4。
    • 外层 printf 输出 4 加换行符,即 "4\n",整体输出为 "241\n4\n",外层返回值为 2。
    • 最终屏幕显示 "241" 换行后再显示 "4"

总结:返回输出字符总数(含所有符号和控制字符)

27.C语言中不能用来表示整常数的进制是二进制

在 C 语言中,整常数的表示仅支持十进制、八进制、十六进制三种进制,不支持二进制直接表示,具体规则如下:

  1. 十进制:默认形式,由数字 0-9 组成,不能以 0 开头(除非数值本身是 0)。例:123-450
  2. 八进制:以数字 0 开头,后续由 0-7 组成。例:012(对应十进制的 10)、077(对应十进制的 63)。
  3. 十六进制:以 0x0X 开头,后续由 0-9a-fA-F 组成。例:0x1A(对应十进制的 26)、0XFF(对应十进制的 255)。

若需使用二进制数值,需通过其他进制间接转换(如将二进制 1101 转为十进制 13、八进制 015 或十六进制 0xD 后使用),或借助 C99 及后续标准中的 %b 格式符(部分编译器支持,非标准),但无法直接以二进制形式定义整常数。

总结:C 语言整常数无二进制表示,仅支持十进制、八进制、十六进制

28.char *str1 = “hello”和char str2[] = “hello”

char *str1 = "hello"char str2[] = "hello" 是 C 语言中字符串两种常见定义方式,核心区别体现在存储位置、可修改性及变量性质上,具体差异如下:

1. 存储位置与内存性质

  • char str2[] = "hello"(字符数组):字符串 "hello" 被存储在栈区(局部数组)或数据段(全局数组),数组会分配独立内存空间(长度为 6,含终止符 \0),内容是字符串的副本。
  • char *str1 = "hello"(字符指针):字符串 "hello" 被存储在只读数据段(常量区),指针 str1 仅在栈区存储该常量字符串的首地址,本身不存储字符串内容。

2. 可修改性

  • 字符数组 str2
    • 数组名是常量指针(地址不可变),不能执行 str2++ 等修改地址的操作。
    • 但数组元素(内存内容)可修改,如 str2[0] = 'W' 是合法的(修改栈 / 数据段的副本)。
  • 字符指针 str1
    • 指针本身是变量,可修改指向的地址,如 str1 = "world" 是合法的(指向新的常量字符串)。
    • 但指向的内容(只读数据段的常量)不可修改,如 *str1 = 'w' 会触发段错误(写入只读内存)。

3. 本质区别总结

特性

char str2[] = "hello"

char *str1 = "hello"

变量性质

数组(分配独立内存存储内容)

指针(仅存储常量字符串地址)

地址可改性

不可改(数组名是常量指针)

可改(指针可指向新地址)

内容可改性

可改(修改数组内的副本)

不可改(指向只读常量区)

存储区域

栈区 / 数据段(可写)

指针在栈区,内容在只读数据段

简言之:数组存副本(内容可改,地址不可改),指针存地址(地址可改,内容不可改)

29. 局部变量和全局变量同名的时候如何使用全局变量

当局部变量与全局变量同名时,若要在局部作用域中使用全局变量,最直接的方式是通过 extern 关键字显式声明,明确指定引用全局版本。具体用法如下:

#include <stdio.h>int a = 10; // 全局变量int main() {int a = 20; // 局部变量(与全局变量同名)// 默认使用局部变量printf("局部变量 a: %d\n", a); // 输出 20// 使用 extern 声明,显式引用全局变量{extern int a; // 声明此处使用全局变量 aprintf("全局变量 a: %d\n", a); // 输出 10}return 0;
}

原理extern int a; 告诉编译器 “此处的 a 是外部全局变量”,从而绕过局部变量的屏蔽,直接访问全局版本。声明需放在局部作用域内(如代码块 {} 中),避免影响其他部分对局部变量的使用。

此外,也可通过 函数封装全局变量 的方式间接访问(适用于复杂场景):

int a = 10; // 全局变量int get_global_a() {return a; // 函数内部无同名局部变量,直接返回全局 a
}int main() {int a = 20; // 局部变量printf("全局变量 a: %d\n", get_global_a()); // 输出 10(通过函数获取全局值)return 0;
}

总结:局部屏蔽全局时,用 extern 显式声明或函数封装可访问全局变量

http://www.dtcms.com/a/435269.html

相关文章:

  • 河源正规网站建设价格广东省深圳市公司
  • Core Speech Kit简介
  • 【OTA专题】3.实现简单的boot和APP程序逻辑
  • 营销单页模板网站怎么买网站域名
  • 织梦做商城网站wordpress 自建邮件
  • 小江网站建设必须重视的问题之一
  • Bella Beauty WordPress Theme — Aesthetic Medical Clinic
  • Java_钻石操作符详解
  • 网站做qq微信微博登录爱做的小说网站
  • 大文件推送到git仓库
  • 对招聘网站页面设计做建议wordpress主题cute
  • Spring cloud快速入门
  • STM32 智能垃圾桶项目笔记(五):语音合成模块(SYN6288)配置与语音播报实现
  • 移动互联网开发应聘四川网站营销seo费用
  • 找北京赛车网站开发wordpress 自定义页面
  • MATLAB信号处理实用指南:从入门到精通
  • 成都住建局官网报名入口网址兴安盟seo
  • 中国建设银行手机网站下载安装托管的服务器如何做网站
  • P13977题解
  • 网络推广岗位职责和任职要求成都做整站优化
  • DAY 38 Dataset和Dataloader类 - 2025.10. 2
  • Privacy Eraser(隐私保护软件)多语便携版
  • C4D R20新增功能概述及体积对象SDF类型深度解析
  • 上海做网站公司推荐简单网上书店网站建设php
  • HarmonyOS应用开发深度解析:ArkTS语法精要与UI组件实践
  • 北京示范校建设网站wordpress快速发布
  • 常用网站布局土巴兔这种网站怎么做
  • toLua[四] Examples 03_CallLuaFunction分析
  • 建设景区网站推文企业网站排名怎么优化
  • 汽车信息安全测试与ISO/SAE 21434标准