嵌入式系统高级c语言<1.关键字>

本文详细介绍了C语言的关键字,包括数据类型关键字(如char、int、void等)、控制语句关键字(如break、for、if等)、存储类型关键字(如auto、register、static、extern)以及其他关键字(如const、sizeof、typedef、volatile)。讨论了它们的作用、用法和在内存管理、程序控制以及类型定义等方面的应用。
摘要由CSDN通过智能技术生成
C语言的32个关键字
关键字类型关键字列表
数据类型的关键字(12个)char、double、enum、float、int、long、short、signed、struct、union、unsigned、void
控制语句的关键字(12个)break、case、continue、default、do、else、for、goto、if、return、switch、while
存储类型的关键字(4个)auto、register、static、extern

其他关键字

(4个)

const、sizeof、typedef、olatile

1. 数据类型关键字

        1.1 简单数据类型的位长

                由于运行C语言的平台千差万别,因此K&RC和ANSI C都没有对简单数据类型所应该占据的位长进行严格的规定。

                K&RC规定long不能比short短。

                ANSI C规定了各种整型数的最小位长,char>=8,short>=16, long>=32,int>=16也可以是32,不同编译器对此的约定可能不一样

            印第安序是CPU存放数据的两种不同顺序,

            大端:低地址存放整数的高位字节。

            小端:低地址存放整数的低位字节。

                大低高,小低低->小弟弟

                举例:将0x12345678存放到0x00开始的地址上。

大小端存放
地址0x000x010x020x03
大端0x120x340x560x78
小端0x780x560x340x12

        1.2 unsigned和signed关键字

                每个简单的数据类型都可以是有符号或者无符号,在C语言用unsigned和signed修饰。

                1. 默认情况下,都是有符号的,除了char类型;

                2.char在大多数编译器约定是有符号的,ARM编译器下,是无符号数。

        1.3 void关键字

                1. 用来修饰函数的返回值;(说明该函数没有返回值,因为如果不写函数的返回值类型,则编译器会认为该函数默认返回值为int类型,并返回值随机,为了避免引用这个随机值,就引入void修饰函数的返回值)

                2. 用来声明函数的入口函数;(说明该函数没有入口参数,如果这样声明入口函数,则会忽略传入的参数,在C++不能若声明了,则不能传递任何参数,否则编译器会报错)

                3. 用来声明空类型指针;(该指针不指向任何类型的数据,仅表示一个内存地址,在需要时强制类型转换)

        1.4 struct关键字

                (1)位域

struct 位域结构名
{位域列表};
例如:
struct pack{
    unsigned a:2;
    unsigned b:8;
    unsigned c:6;
}pk1, pk2;

                        把一个字节中的二进制位分为不同的区域,并说明每个区域的位数。一个位域不能跨两个字节

                (2) 结构体内部的成员对齐

                         不同编译器和处理器对齐方式不同,一般都满足以下3个条件:

                         1. 结构体变量的首地址能够被最宽成员的大小整除

                        2. 结构体成员相对于结构体首地址的偏移量都是成员大小的整数倍,有需要会在成员间填充字节;

                         3. 结构体的总大小最宽的成员的整数倍,如有需要在最后一个成员填充字节;

                ​​​​​​​        备注:

                        结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得,在        stddef.h 定义;

                        这里的基本数据类型指的是char、int...,对于复合类型结构体,要寻找结构体内的子成员,在确定了复合类型成员的偏移位置时则是将复合类型作为整体看待。

        1.5 union关键字

union data
{
    char n;
    float f;
};
union data ul = {3};   //只有ul.n被初始化

                 联合变量的所有成员共享同一片存储区,每个时刻只能保存它的某个成员值

        1.6 enum关键字

                枚举是一种用于定义一组命名常量的机制,默认第一个值为0,随后的变量依次递增。

                (1)当随后的变量有赋值,则下一个变量根据当前变量开始递增

enum color {
    RED = 1,
    GREEN,
    BLUE,    
    WHITE = 11,
    GREY,
    BLACK = 15,
};
这时GREEN = 2, BLUE = 3, GREY = 12

                (2)用枚举常量作为数组长度

typedef enum{
    WHITE, 
    READ, 
    BLUE, 
    YELLOW,
    BLACK,
    COLOR_NUM
}COLOR;

float BallSize[COLOR_NUM];//当颜色数量发生变化时,只需要在枚举类型定义中增删颜色即可,相比#define更简洁可靠。

2. 控制语句关键字

        1. break直接跳出循环,continue跳出本次循环(只能用于循环语句)

        2. 不推荐使用goto

3. 存储类型关键字

        1. 变量的存储类型是指存储变量值存储器类型

        2. 变量的存储类型决定了变量何时创建、何时销毁以及其值保存多久

        3. C语言中变量可以存放在三个地方:普通内存、运行时的堆栈、CPU内部的通用寄存器。堆栈也是内存,只是往往用于暂存数据,内容变化频繁。

        4. 变量的存储类型首先取决于它的声明位置

        5. 在函数外声明的变量都是全局变量,编译器在编译过程中将全局变量映射在普通内存中,在程序的整个执行期间该变量始终占用编译器为它分配的内存空间,始终保持原值,直至重新赋值程序结束,所以也称全局变量是静态的。ARM编译器在编译过程中会生成2个全局变量段:RW(有初值)和ZI(无初值)的,链接器将所有C文件的RW和ZI段进行拼接并对其中的全局变量进行重新定位

        3.1 auto关键字

                局部变量默认就是auto自动变量,这个变量存储在堆栈或CPU内部的寄存器中,所以没有实际用途。

        3.2 register关键字

                用于自动变量的声明。提示编译器将register修饰的自动变量存储在CPU内部的通用寄存器,而不是存储器。

                注:编译器可能忽略register关键字,自己去分配存储的位置,所以一般也不会用。

        3.3 static关键字

                该关键字的含义取决于不同上下文

                1. 修饰函数内的局部变量时,会改变局部变量的存储类型,由自动变量变为静态变量,在编译期间分配一个静态的存储空间,不再存储在堆栈或寄存器中。函数可能变得不可重入

                2. 修饰函数时,作用域限制在此C文件中,其他文件不可访问。

                3. 修饰全局变量时,作用域限制在此C文件中,其他文件不可访问。

        3.4 extern关键字

                默认情况下,函数和全局变量作用域只是在定义或声明的C文件内部,如果其他文件想访问必须使用extern。这是因为C编译器是以C文件为单位进行编译的,如果引用了其他文件的就会报错未定义,所以就引入了这个关键字,extern告诉编译器这个函数或变量是在其他文件定义过。两种方式:

                1. 在C文件直接用extern声明变量或函数;

                2. 在头文件用extern声明变量或函数,然后在其他的C文件使用;推荐!!

4. 其他类型关键字

        4.1 const关键字

                声明一个不可改变的变量,称为“只读”的变量

const int a;和int const a;没区别   //声明整数变量a是只读的

const int *a;   //声明一个指向整数的指针变量,*a指向的整数是只读的
int *const a;   //声明一个指向整数的指针变量,a指针变量是只读的
int const * const a;   //声明一个指向整数的指针变量,*a和a都是只读的

                1. 本质上没改变一个变量属性

                2. 为给读代码的人传达非常有用的信息,声明一个常量

                3. 给编译器的优化器一些附加的信息,也许能产生更紧凑的代码,比如很多编译器在处理const修饰的变量时,往往会把这些变量分配到ROM的地址;

                4. 合理的使用可以使编译器很自然地保护不希望被改变的参数,防止被无意的改掉,当不经意修改时,报错提醒程序员。

                5. 只有在定义的时候初始化,后面就没机会了

                6. 在函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内不能修改

        4.2 sizeof关键字

                是一个关键字,不是函数,看传入的值可以看出来sizeof(int)。作用是返回一个对象或者类型所占的内存字节数,有三种使用形式:

sizeof(var);          //sizeof(变量);
sizeof(type_name);    //sizeof(类型);
sizeof var;           //sizeof 变量;

举例:
char *ss = "0123456789";
sizeof(ss);   //4 是指向字符串常量的字符指针
sizeof(*ss);  //1 *ss是第一个字符

char ss[] = "0123456789";
sizeof(ss);   //11 计算到'\0'位置,因此10+1=11
sizeof(*ss);  //1 *ss是第一个字符

char ss[100] = "0123456789";
sizeof(ss);   //100 开辟内存的大小100*1=100
strlen(ss);   //10 '\0'为止之前的长度

int ss[100] = "0123456789";
sizeof(ss);   //400  开辟的内存大小100*4=400
strlen(ss);   //错误 strlen参数只能是char*且必须'\0'结尾

        4.3 typedef关键字

                通过typedef定义新的数据类型

typedef char* ptr_to_char;

char* a;等价于 ptr_to_char a;

        4.4 volatile 关键字

                直接存取原始内存地址的值。优化器用到这个变量时必须每次小心地重新获取这个变量的值,而不是使用保存在寄存器里的备份

下面是volatile变量几个例子:
1.并行设备的硬件寄存器(如状态寄存器); (因为每次读写都可能有不同的意义)
    比如要初始化寄存器0xff800001,多次读取这个寄存器的值,编译器会优化成只读最后一次
2.一个中断服务子程序中会访问到的非自动变量;
    非自动变量指的是全局变量或静态变量
static int i=0;
int main(int argc, char **argv)
{
    while(1)
    {   
        if(i)
            do_something();
    }   
}
 
/* Interrupt service routine */
void ISR_2(void)
{
    i=1;
}
3.多线程应用中被几个任务共享的变量;
    一个线程读取了这个变量后放到寄存器中,当其他线程修改了这个变量,这个线程再去读取的时候会从寄存器读取,但是值已经改变了

备注:
1.一个参数既可以是const也可以是volatile,只读状态寄存器。
2.一个指针可以是volatile,例如当一个中断服务子程序修改一个指向buffer的指针时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值