
大家好我是Halcyon.平安欢迎文末添加好友交流共同进步目录C中 define 和 const 的区别?C 中 char*、const char*、char* const、const char* const 的区别?C中 inline的作用它有什么优缺点C中数组和指针的区别C中sizeof 和 strlen的区别?C中extern有什么作用externC有什么作用?C 中 explicit 的作用?C中 final关键字的作用?C中野指针和悬挂指针的区别什么是内存对齐为什么要内存对齐目录C中 define 和 const 的区别?define 是预处理阶段的宏定义可以是宏常量也可以是带参宏函数由预处理器做简单的文本替换没有类型检查const 是编译阶段定义的只读变量有类型、会进符号表、可以调试对比项defineconst处理阶段预处理编译类型检查无纯文本替换有编译器会检查类型内存不分配内存就地展开通常要分配内存作用域从定义处到文件尾除非#undef受作用域限制类、函数、文件调试不能预处理后宏名就没了可以看到变量名(我觉得如果问到了的话可以主动延伸const比如Day1——修饰变量修饰指针修饰成员变量修饰引用等等)C 中 char*、const char*、char* const、const char* const 的区别?记忆口诀const 在*左边修饰指向的内容在*右边修饰指针本身。char*普通字符指针指向和内容都能改const char*等价于char const*能改指向不能改内容char* const不能改指向能改内容const char* const指向和内容都不能改C中 inline的作用它有什么优缺点作用建议编译器把函数调用处直接展开成函数体省去函数调用的开销压栈、跳转、返回优点避免函数调用开销提高执行效率适合短小、频繁调用的函数缺点代码膨胀每处调用都展开一份可能影响指令缓存命中率如果函数太大或递归编译器会拒绝 inline建议只是建议修改 inline 函数后所有调用它的地方都得重新编译注意点inline 只是对编译器的建议最终是否展开由编译器决定C17 起可以用inline定义变量inline 变量在类内定义的成员函数隐式 inlineC中数组和指针的区别数组一段连续的内存数组名可以看作首元素地址但数组名本身不是指针不能自增、不能重新赋值指针一个变量存的是某块内存的地址对比项数组指针sizeof得到整个数组占的字节数得到指针本身大小4/8 字节内存连续不一定连续可修改性数组名不能重新指向可以随意改指向传参大多数情况会退化成指针本身就是指针C中sizeof 和 strlen的区别?sizeof 是运算符求的是类型/变量占的内存大小编译期就确定包含结尾\0strlen 是函数求的是字符串实际长度运行时算遇到\0停止且不包含\0constchar*shello;sizeof(s);// 指针大小通常 8sizeof(hello);// 65 个字符 \0strlen(s);// 5C中extern有什么作用externC有什么作用?extern声明一个在别处定义过的变量/函数告诉编译器这个符号在别的地方有定义链接时再去找常用于跨文件使用全局变量extern “C”告诉 C 编译器按 C 的风格编译这一段代码。因为 C 编译时会对函数名做名字修饰name manglingC 不会混编时链接不上。常见用法#ifdef__cplusplusexternC{#endifvoidc_func(inta,intb);// 按 C 风格编译方便 C 代码调用#ifdef__cplusplus}#endifC 中 explicit 的作用?用在单参数构造函数或 C11 后所有但有一个参数的构造函数前面禁止编译器做隐式类型转换只允许显式调用场景避免一些不期望的自动转换带来意外行为classA{public:explicitA(intx){}};Aa1(10);// OK显式构造A a210;// 编译报错因为没有 explicit 才允许这种隐式转换C中 final关键字的作用?修饰类这个类不能再被继承修饰虚函数这个虚函数不能再被派生类 overrideclassBasefinal{};// Base 不能被继承classDerived:publicBase{virtualvoidf()final;// 派生类再 override f 就会报错};C中野指针和悬挂指针的区别野指针未初始化的指针随机指向一块内存那块内存可能根本不存在或没权限访问悬挂指针dangling pointer指针本来指向一块合法内存但那块内存已经被释放/回收了指针还保存着旧地址再去访问就是未定义行为int*p;// 野指针没初始化int*qnewint(1);deleteq;*q;// 悬挂指针q 指向的内存已经被 delete 了避免方法指针定义时初始化nullptr释放后立刻置空。什么是内存对齐为什么要内存对齐点击查看——结构体 / 内存对齐详解是什么编译器在分配内存时会按照一定的对齐倍数通常是成员大小或平台默认对齐值来摆放数据让数据的地址是其大小的整数倍中间可能填充空字节为什么要对齐硬件原因CPU 读取内存是按字长4/8 字节成块读取的不对齐可能要读两次再拼效率低平台原因某些平台ARM 等不对齐会直接硬件异常 crash缓存友好对齐的数据更可能落在同一缓存行里怎么对齐结构体规则每个成员按其自身大小对齐整个结构体大小是最大成员对齐值的整数倍structA{charc;// 1 字节// 填充 3 字节inti;// 4 字节};// sizeof(A) 8而不是 5