【嵌入式八股21】C语言基础知识

一、数据类型说明

在 C 语言中,不同的数据类型在不同平台下占用的字节数有所不同。以下是常见数据类型在 16 位、32 位和 64 位平台下的字节数情况:

数据类型 16 位平台 32 位平台 64 位平台
char 1 字节 1 字节 1 字节
pointer(指针) 2 字节 4 字节 8 字节
short(短整型) 2 字节 2 字节 2 字节
int(整型) 2 字节 4 字节 4 字节
float(单精度浮点数) 4 字节 4 字节 4 字节
double(双精度浮点数) 8 字节 8 字节 8 字节
long(长整型) 4 字节 4 字节 8 字节
long long(长整型) 8 字节 8 字节 8 字节

二、volatile 关键字

volatile 关键字用于指出变量的值是随时可能发生变化的,因此在每次使用该变量时,编译器都会强制从变量的内存地址中重新读取数据,而不是使用保存在寄存器中的缓存值。其常见的应用场景如下:

  1. 并行设备的硬件寄存器:例如,与外部设备进行交互时,硬件寄存器中的值可能会在程序执行过程中由外部设备自行改变,此时需要将访问该寄存器的变量声明为 volatile,以确保每次读取到的都是最新值。
  2. 中断服务子程序中会访问到的非自动变量(Non-automatic variables):在中断服务程序中,可能会访问到一些全局变量或静态变量。由于中断的发生是随机的,这些变量的值可能会在主程序执行过程中被中断服务程序修改。为了保证在主程序中能正确处理这些变量,应将其声明为 volatile。此外,对于这类变量的访问,可以使用关键区保护,以避免在多线程或中断环境下出现数据竞争。
  3. 多线程应用中被几个任务共享的变量:在多线程环境下,多个线程可能同时访问和修改同一个变量。为了确保每个线程都能读取到变量的最新值,避免因编译器优化导致的缓存数据不一致问题,需要将共享变量声明为 volatile。另外,在对共享变量进行操作时,可以考虑关闭系统调度(在某些特定情况下),以保证操作的原子性。

三、指针相关概念

(一)函数指针

函数指针是指向函数的指针变量,其声明格式为:int (*fun)(int *a);,表示 fun 是一个指针,它指向一个返回值为 int 类型,参数为 int * 类型的函数。

(二)函数指针数组

函数指针数组是一个数组,数组的每个元素都是一个函数指针。声明格式为:int (*fun[10])(int *data, int size);,表示 fun 是一个包含 10 个元素的数组,每个元素都是一个指向函数的指针,这些函数的返回值为 int 类型,参数为 int *int 类型。

使用示例:

int (*sort_fun[5])(int *data, int size) = {
    quick_sort,     /* 快速排序 */
    insert_sort,    /* 插入排序 */
    bubble_sort,    /* 冒泡排序 */
    heap_sort,      /* 堆排序 */
    selection_sort  /* 选择排序 */
};
// 或者
sort_fun[0] = quick_sort;
sort_fun[1] = insert_sort;

(三)指针数组

指针数组是一个数组,数组的元素都是指针。声明格式为:int *a[10];,表示 a 是一个包含 10 个元素的数组,每个元素都是一个指向 int 类型的指针。

(四)数组指针

数组指针是指向数组的指针变量。声明格式为:int (*a)[10];,这里 a 是一个指针,它指向一个包含 10 个 int 类型元素的一维数组。当进行 a + 1 操作时,a 会跨过 10 个 int 型数据的长度。

(五)指针的指针

指针的指针是指向指针的指针变量。声明格式为:int **a;,表示 a 是一个指针,它指向的是一个 int * 类型的指针。

四、main 函数的返回值

在 C 语言中,main 函数的返回值用于向操作系统反馈程序的执行状态:

  1. 返回 0:表示程序正常退出,即程序在执行过程中没有遇到任何异常或错误情况,顺利完成了所有操作。
  2. 返回负数:表示程序异常退出,通常意味着程序在执行过程中遇到了某种错误,如内存分配失败、非法操作等。操作系统可以根据返回的负数来进一步分析程序出错的原因。

五、const 关键字

(一)const T

用于定义一个常量,在声明的同时必须进行初始化。一旦声明,该常量的值将不能被改变。

示例:

const int constInt = 10;        // 正确,声明并初始化一个整型常量
constInt = 20;                  // 错误,常量值不可被改变
const int constInt3;            // 错误,未被初始化

(二)const T*

表示指向常量的指针,该指针不能用于改变其所指向的对象的值。

示例:

const int i = 5;
const int i2 = 10;
const int* pInt = &i;           // 正确,指向一个 const int 对象,即 i 的地址
//*pInt = 10;                   // 错误,不能改变其所指向的对象的值
pInt = &i2;                     // 正确,可以改变 pInt 指针本身的值,此时 pInt 指向的是 i2 的地址
const int* p2 = new int(8);     // 正确,指向一个 new 出来的对象的地址
delete p2;                      // 正确
//int* pInt = &i;               // 错误,i 是 const int 类型,类型不匹配,不能将 const int * 初始化为 int *
int nValue = 15;
const int * pConstInt = &nValue;    // 正确,可以把 int * 赋给 const int *,但是 pConstInt 不能改变其所指向对象的值,即 nValue
*pConstInt = 40;                    // 错误,不能改变其所指向对象的值

(三)const int* 与 int* const 的区别

指针本身是一种对象,int* const 表示常量指针,即指针本身的值不可改变,声明时必须初始化。

示例:

int nValue = 10;
int* const p = &nValue;
int *const p2 = &nValue;
// const int* 指针指向的对象不可以改变,但指针本身的值可以改变;int* const 指针本身的值不可改变,但其指向的对象可以改变。
int nValue1 = 10;
int nValue2 = 20;
int* const constPoint = &nValue1;
//constPoint = & nValue2;           // 错误,不能改变 constPoint 本身的值
*constPoint = 40;                   // 正确,可以改变 constPoint 所指向的对象,此时 nValue1 = 40

const int nConstValue1 = 5;
const int nConstValue2 = 15;
const int* pPoint = &nConstValue1;
//*pPoint  = 55;                    // 错误,不能改变 pPoint 所指向对象的值
pPoint = &nConstValue2;             // 正确,可以改变 pPoint 指针本身的值,此时 pPoint 绑定的是 nConstValue2 对象,即 pPoint 为 nConstValue2 的地址

(四)const int* const

表示一个指向常量对象的常量指针,即既不可以改变指针本身的值,也不可以改变指针指向的对象的值。

示例:

const int nConstValue1 = 5;
const int nConstValue2 = 15;
const int* const pPoint = &nConstValue1;
//*pPoint  = 55;                    // 错误,不能改变 pPoint 所指向对象的值
//pPoint = &nConstValue2;           // 错误,不能改变 pPoint 本身的值

(五)const 助记方法

  1. 把一个声明从右向左读char * const cp; 应读成 cp is a const pointer to char,即 cp 是一个指向 char 类型的常量指针;const char * p; 读成 p is a pointer to const char,即 p 是一个指向 const char 类型的指针;char const * p;const char * p 等价,因为在 C++ 中没有 const* 的运算符,所以 const 只能属于前面的类型。
  2. C++ 标准规定,const 关键字放在类型或变量名之前等价
    • char * const cp:定义一个指向字符的指针常数,即 const 指针。
    • const char* p:定义一个指向字符常数的指针。
    • char const* p:等同于 const char* p
    • const char **:是一个指向指针的指针,那个指针又指向一个字符串常量。
    • char **:也是一个指向指针的指针,那个指针又指向一个字符串变量。

六、浮点数存储方式

(一)float 类型

float 类型占用 4 个字节(32 bits),其存储结构如下:

部分 位数 说明
符号位 1 bit 表示浮点数的正负,0 表示正数,1 表示负数。
指数位 8 bits 用于表示浮点数的指数部分,以确定数值的大小范围。
尾数部分 23 bits 表示浮点数的有效数字部分。

(二)double 类型

double 类型占用 8 个字节(64 bits),其存储结构如下:

部分 位数 说明
符号位 1 bit 表示浮点数的正负,0 表示正数,1 表示负数。
指数位 11 bits 用于表示浮点数的指数部分,相比 类型,能表示更

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

嵌入式八股/模拟面试拷打 文章被收录于专栏

一些八股模拟拷打Point,万一有点用呢

全部评论

相关推荐

06-12 17:46
门头沟学院 Java
运营你豪哥:来说重点: ​1.项目前置,时间倒序。​​ 2.​项目描述强化结果与量化效果(STAR原则里的R)。​​ ​3.个人技能精炼,明确掌握程度,突出核心。​​ ​4.增加强有力开头的个人总结部分。​​ 5.​优化教育背景(成绩排名)、合并奖项与活动。​​
听劝,我这个简历该怎么改...
点赞 评论 收藏
分享
评论
2
6
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务