• C 语言中的关键字


    C 语言中有 32 个关键字。这是留个编译器用的特殊字符串,用户不可以使用。

    特殊关键字

    sizeof 和 return 是 C 语言中的两个特殊关键字。

    sizeof

    sizeof 用于计算变量所占内存空间的字节数,返回值为 unsigned long 无符号长整型。sizeof 不依赖底层操作系统,可以在编译时直接得到。

    有两种用法:

    int a;
    printf("%lu
    ", sizeof(a));
    printf("%lu
    ", sizeof a);
    

    return

    return 用于执行返回操作,退出当前函数,执行函数调用栈的上一层调用者。

    数据类型

    C 语言中,各种数据类型所占空间大小,跟具体的编译平台相关。例如在 32bit 机器上 int 类型占 4Byte。

    CPU 在一个周期内所能处理数据的最优大小,就是 CPU 的位数,也是对应平台上 int 类型的大小。

    整型和浮点型

    所有的数值类型,默认都是带符号的。如果想使用不带符号的数值,必须用 unsigned 关键字明确指定,例如 unsigned int

    • 整型类型
      char:占 1 个字节,是最小的数据类型。有符号字符型表示范围为 -128~127,无符号字符型表示范围为 0~ 255
      short:一般占 2 字节
      int:2 字节(16 bit CPU)或 4 字节(32 bit CPU)。有符号 int 型表示范围为 -32768~32767,无符号 int 型表示范围为 0~ 655355
      long:4 字节或 8 字节,可以拼接 long long l 表示更大的数据。
    • 浮点类型
      float:4 字节
      double:8 字节

    浮点数有多种不同的表示方法,虽然表示范围很大,但是可能有精度丢失。浮点数默认是 double 类型,但可以在浮点数末尾加个 f 来表示采用 float 类型,例如:

    float f = 3.14 * 2; // 3.14 会分配一个 double 类型的空间
    float f2 = 1.234f + 2.333f;
    

    无符号和有符号

    所有的数值类型,默认都是带符号的。如果想使用不带符号的数值,必须用 unsigned 关键字明确指定,例如 unsigned int

    通常来说,可以进行各种运算的数值用默认的有符号类型,而单纯的数据(例如信号、二进制数据)则使用无符号的类型。

    有符号数的位运算

    • 对于有符号整数,每一次右移操作采用的是sar算术右移指令,高位补充的是1
    • 对于无符号整数,每一次右移操作采用的是shr逻辑右移指令,高位补充的是0
    • 对于左移,无论是算术左移(sal)还是逻辑左移(shl),低位补充的都是0
    #include <stdio.h>
    
    int main()
    {
    	char c1 = 0x80;
    	unsigned char c2 = 0x80;
    	printf("0x%x	0x%x
    ", c1, c2);
    	int i;
    	for (i = 0; i < 8; i++) {
    		c1 = c1 >> 1;
    		c2 = c2 >> 1;
    		printf("0x%x	0x%x
    ", c1, c2);
    	}
    }
    

    输出:

    0xffffff80	0x80
    0xffffffc0	0x40
    0xffffffe0	0x20
    0xfffffff0	0x10
    0xfffffff8	0x8
    0xfffffffc	0x4
    0xfffffffe	0x2
    0xffffffff	0x1
    0xffffffff	0x0
    

    void 类型

    void 相当于一个占位符,可以声明变量或返回值,但是void 类型的变量不可直接使用,需要强制转换为其他类型才可以。

    void a;
    void fun();
    

    void 通常用于:

    • 对函数返回的限定
    • 对函数参数的限定

    溢出

    每种数据类型在存储数据时,都有范围限制。如果把超过限制的数据存入某个变量,会导致各种异常状况。编译时会有警告。

    char c = 666;
    printf("%d", c);
    

    输出:

    /code/main.c: In function ‘main’:
    /code/main.c:5:1: warning: overflow in implicit constant conversion [-Woverflow]
    char c = 666;
     ^
    -102
    

    自定义数据类型

    struct、union、enum 是 3 种自定义的数据类型,typedef 是为数据类型起一个别名。

    自定义数据类型,就是把已有的数据类型进行组合,得到一个匹配实际的资源类型的存储类型。

    使用自定义数据类型时,必须在变量前指明这个变量是哪一个数据类型,例如 struct MyStruct s;

    struct 结构体

    struct 结构体就是变量的集合,把已有的类型组合到一起,形成新的类型的语句。struct 中的变量按照顺序存储。

    struct 也是一条语句,定义时必须以分号结尾。使用时必须用 struct 自定义的名称 变量名 的形式来声明变量,示例:

    #include <stdio.h>
    
    struct People {
    	unsigned int age;
    	char* name;
    }; // 这里必须加分号
    
    int main()
    {
    	struct People s = {20, "jack"};
    	printf("%d, %s", s.age, s.name);
    }
    

    union 共用体

    union 共用体中,所有变量共享同一块内存。因为内存的起始地址重合,任何时刻都只能存储一个变量。

    #include <stdio.h>
    
    union myUnion {
    	unsigned int i;
    	char c;
    }; // 这里必须加分号
    
    int main()
    {
    	union myUnion s;
    	s.i = 666;
    	printf("%d", s.i);// s 中只有 i 一个元素,如果打印 c 会报错
    	s.c = 'a';
    	printf("%c", s.c);// s 中只有 c 一个元素,如果打印 i 会报错
    }
    

    输出为:``666a

    enum 枚举

    C 语言中能用 enum 实现的代码,都可以不用 enum 实现。

    enum 是常量的集合。例如一周的七天,可以用 #define 或 const int 来定义,也可以打包放到 enum 中。enum 特点是:

    • enum 中首元素默认是 0,可以指定为任意 int 类型的整数,后序所有元素依次加一。
    • enum 枚举类型可以不指定名称,因为 enum 中的每一个元素都可以当做全局常量直接使用

    下面示例中的三种写法等价,用法是一样的:

    #include <stdio.h>
    
    /*
    #define SUN 7
    #define MON 1
    #define TUE 2
    
    const int SUN = 7;
    const int MON = 1;
    const int TUE = 2;
    */
    
    enum {SUN = 0, MON, TUE}; // 默认第一个元素是0,后序元素依次加一
    
    int main()
    {
    	printf("%d
    ", TUE);
    }
    

    typedef

    typedef 为已有的数据类型起别名,可以让程序可读性更高。通常在 Linux 内核源码中,用 typedef 起的别名,后缀都是 _t

    #include <stdio.h>
    
    typedef unsigned int uint_t;
    
    int main()
    {
    	uint_t a = 666;
    	printf("%d", a);
    	return 0;
    }
    

    逻辑结构

    分支语句

    if else 语句

    if (3 < 4)
    {//...}
    

    switch case default 语句

    语法:

    switch(整型变量)
    {
    	case 整型数字:
    		// 执行语句
    		break; // 必须加,否则会向下执行
    	default:
    		// 上面没有匹配到时,默认执行这里的语句
    }
    
    #include <stdio.h>
    
    int main()
    {
    	int i;
    	for (i = 0; i < 5; i++)
    	{
    		switch (i/3)
    		{
    			case 0:
    				printf("%d
    ", i);
    			case 1:
    				printf("%d
    ", i);
    			case 2:
    				printf("%d
    ", i);
    				break;
    			default:
    				printf("this is default
    ");
    		}
    	}
    }
    

    因为没加 break 会导致 switch case 贯穿,输出如下:

    0
    0
    0
    1
    1
    1
    2
    2
    2
    3
    3
    4
    4
    

    循环语句

    for 循环

    跟次数相关。

    C 语言中,for 循环的初始化语句中,必须用已经声明过的变量,比较差:

    int i;
    for (i = 0; i < 10; i++)
    {//...}
    

    do while 循环

    至少执行一次。

    int a = 666;
    do {
    	printf("%d", a);
    } while (a++ < 0);
    

    while 循环

    跟条件相关。

    continue、break、goto 语句

    continue:结束本次循环,开始下次循环
    break:结束语句所在的循环
    goto:跳转到指定语句位置

    类型修饰符

    变量的数据类型定义之后,变量所占用的存储空间大小就固定了。变量的具体存储位置,就需要用类型修饰符来控制。默认的类型是 auto,int a 等价于 auto int a

    • auto:变量默认的修饰符,存储在普通内存中。通过地址来寻址,可以用 & 查看具体地址。
    • register:变量存储在 CPU 内部的寄存器中,速度快,容量小。& 取地址符号对这种变量无效。变量访问频率很高时,才考虑放在寄存器中。编译器会尽量把变量放在寄存器中,但如果寄存器不足,则变量还是会放在内存中。通常每个寄存器都有特殊名字,例如 ARM 的 R0,R1 等。
    • static:有 3 中使用场景
      • 修饰函数内变量:static int a;
      • 修饰函数外变量:
      • 修饰函数:static int fun(){}
    • const:常量定义。实际上是只读变量,还是有办法修改(借助指针)。
    • extern:外部声明,表示函数或变量在外部文件中
    • volatile:告诉编译器,不优化编译。部分变量不仅软件可以修改,外部硬件也可以修改,编译器此时的优化可能导致错误。
  • 相关阅读:
    支持向量机
    Redis(六)应用问题解决
    Redis(七)新数据类型、新功能
    Redis(五)主从复制、集群
    MacOS解决too many open files
    使用systemd让程序自启保活
    vue 生产环境开启 vuedevtools
    mac完整卸载vmware
    将 .gradle文件 从C盘移动到D盘
    【转】微信小程序推送消息
  • 原文地址:https://www.cnblogs.com/kika/p/10851511.html
Copyright © 2020-2023  润新知