C语言基础——关键词

发布于:2025-07-25 ⋅ 阅读:(14) ⋅ 点赞:(0)

C语言中的关键词是编程语言的基础,它们被用来定义数据类型、控制结构、存储类型以及其他重要的编程操作。C语言标准定义了32个关键词,这些关键词可以分为四个主要类别:数据类型关键词、控制语句关键词、存储类型关键词和其他关键词。

1.数据类型关键词

数据类型关键词用于声明变量或函数的类型。这些关键词包括:

char:声明字符型变量或函数。

double:声明双精度浮点型变量或函数。

float:声明单精度浮点型变量或函数。

int:声明整型变量或函数。

short:声明短整型变量或函数。

long:声明长整型变量或函数。

unsigned:声明无符号类型变量或函数。

signed:声明有符号类型变量或函数。

struct:声明结构体变量或函数。

union:声明共用体(联合)数据类型。

void:声明函数无返回值或无参数,声明无类型指针。

enum:声明枚举类型。

2.控制语句关键词

控制语句关键词用于控制程序的流程。这些关键词包括:

fordowhile:用于循环结构。

break:跳出当前循环。

continue:结束当前循环,开始下一轮循环。

ifelse:用于条件语句。

goto:无条件跳转语句。

switchcasedefault:用于多重分支结构。

return:用于函数返回。

3.存储类型关键词

存储类型关键词用于声明变量的存储类别。这些关键词包括:

auto:声明自动变量。

extern:声明变量是在其他文件中定义。

register:声明寄存器变量。

static:声明静态变量。

4.其他关键词

其他关键词用于声明只读变量、计算数据类型长度、给数据类型取别名以及防止编译器优化。这些关键词包括:

const:声明只读变量。

sizeof:计算数据类型长度(字节数)。

typedef:给数据类型取别名。

volatile:所修饰的对象不能被编译器优化。

5.关键词的用法

1.数据类型

首先数据类型关键词不必多说,在声明所需的数据类型时用于声明所需要的数据类型。具体使用方法如下

int a = 10;

声明一个整型数据a,赋值为10。

2.控制语句

C语言中的控制语句关键词用于控制程序的执行流程,包括条件判断、循环执行和跳转等。也就是我们通俗来讲的语法,所有控制语句关键词用法如下

1.if

用于根据条件表达式的真假来决定是否执行某一段代码。

if (condition) {
    // 执行代码
}

当condition 为真时执行代码块中的内容,否则跳过。

2.else

配合if语句使用,表示条件不成立时执行的代码。

if (condition) {
    // 条件成立时执行
} else {
    // 条件不成立时执行
}

if条件为假时,执行else后面的代码。

3.else if

用于在多个条件判断中选择其中一个符合条件的分支。

if (condition1) {
    // 执行代码1
} else if (condition2) {
    // 执行代码2
} else {
    // 执行代码3
}

if的条件为假时,继续判断后面的else if条件,直到找到为真为止。

4.switch

用于根据不同的值选择执行不同的代码块。常用于多个条件判断时。

switch (expression) {
    case value1:
        // 执行代码1
        break;
    case value2:
        // 执行代码2
        break;
    default:
        // 执行默认代码
}

 根据expression的值与各个case的值进行匹配,匹配成功时执行相应的代码。若没有匹配项,则执行default后的代码。

5.for

用于创建一个循环,常用于已知次数的循环。

for (initialization; condition; increment) {
    // 循环体
}

先执行初始化语句,然后判断条件是否为真,若为真则执行循环体,再执行增量或更新操作。重复此过程,直到条件为假。

6.while

用于创建一个循环,常用于条件未知的循环。

while (condition) {
    // 循环体
}

先判断条件是否为真,若为真则执行循环体,然后重新判断条件,直到条件为假。

7.do

while配合使用,构成do-while循环,至少执行一次循环体(与while的区别),然后再判断条件。

do {
    // 循环体
} while (condition);

先执行一次循环体,然后判断条件,若条件为真则继续执行循环,直到条件为假。

8.break

用于跳出循环或switch语句,结束当前的执行过程。

break;

 立即结束最近的forwhiledo-while循环或switch语句的执行。

9.continue

用于跳过当前循环中的剩余语句,直接进入下一次循环的判断条件。

continue;

 跳过当前循环中的后续代码,开始下一次循环的判断。(通常可以省略循环内的if判断)

10.goto

用于无条件跳转到程序中指定的标签处。

goto label;
// 其他代码
label:
    // 跳转到此处

 从代码中任意位置跳转到指定的标签位置,通常不推荐过度使用。会造成代码易读性降低,也容易造成代码结构混乱,一般不使用

3.存储类型

在C语言中,autoexternregisterstatic 都是存储类说明符(Storage Class Specifiers),它们用来描述变量的存储方式、生命周期、作用域等特性。

1.auto

auto 是 C 语言中的默认存储类,它用于声明局部变量。实际上,局部变量如果没有显式指定存储类,默认就是 auto。在大多数情况下,auto 关键字是可以省略的,因为它不会对变量的行为产生实质性的影响。

特点:

  • 局部性auto 变量只在其所在的函数或代码块中有效。
  • 自动存储:当函数调用结束时,auto 变量会被销毁。它的生命周期是与函数调用的开始和结束相关联的。
  • 作用域auto 变量的作用域仅限于声明它的代码块。
void foo() {
    auto int x = 10;  // 自动变量
    printf("%d", x);  // x 只能在 foo() 函数内使用
}

在现代 C 语言编程中,auto 关键字已不常用,因为我们声明的局部变量默认就是auto。 

2.extern

extern 用于声明一个变量或者函数是在其他源文件中定义的。通过 extern 关键字,C语言程序可以引用其他文件中定义的变量或函数,而不需要在当前文件中重新定义它们。

特点:

  • 链接外部符号extern 表示该变量或函数在其他文件中定义,告诉编译器该符号已经在其他地方声明过。
  • 全局作用域extern 变量通常是全局变量,它的生命周期贯穿整个程序。
  • 无内存分配extern 声明仅仅是声明,不会分配内存。内存分配在实际定义时发生。
// file1.c
int x = 10;  // 在 file1.c 中定义变量 x

// file2.c
extern int x;  // 在 file2.c 中声明变量 x
void foo() {
    printf("%d", x);  // 访问 file1.c 中定义的 x
}

这里,xfile1.c 中定义,在 file2.c 中声明并使用。 

3.register

register 用来声明寄存器变量。它告诉编译器该变量应该尽可能保存在 CPU 的寄存器中,而不是内存中。这通常用于频繁访问的变量,以提高性能。虽然现代编译器通常能够自动优化变量的存储位置,但仍然可以使用 register 来建议编译器将某个变量存放在寄存器中。

特点:

  • 存储在寄存器中:编译器会尽量把变量存储在 CPU 寄存器中,以加速对该变量的访问。
  • 局部性register 变量只能是局部变量,不能是全局变量。
  • 无法取地址:由于 register 变量存储在寄存器中,所以不能通过取地址符 & 获取其地址。
void foo() {
    register int count = 0;  // 尝试将 count 存储在寄存器中
    for (int i = 0; i < 100; i++) {
        count++;
    }
    // printf("%p", &count);  // 错误,无法获取寄存器变量的地址
}

这里,count 可能会被存储在寄存器中,以提高访问速度,但取决于编译器的优化策略。(本人很少使用) 

4.static

static 用于声明静态变量,静态变量有两种主要用途:

  1. 静态局部变量:在函数内部声明时,static 使得变量的值在函数调用结束后不会丢失,而是保留在内存中,直到程序结束。
  2. 静态全局变量:在文件作用域内声明时,static 使得该变量只能在声明它的文件中访问,防止外部文件访问。

特点:

  • 静态局部变量:静态局部变量的生命周期与程序相同,它在程序运行期间一直存在,即使函数调用结束,它的值仍然被保留。
  • 静态全局变量:静态全局变量只在定义它的文件中可见,不能在其他文件中使用。

例子:

  • 静态局部变量

void foo() {
    static int count = 0;  // 静态局部变量
    count++;
    printf("%d\n", count);  // 每次调用 foo(),count 都会累加
}

每次调用 foo 时,count 的值不会被重置,而是上次调用时的值。 

  • 静态全局变量

static int globalCount = 0;  // 静态全局变量,仅在当前文件内可见

void increment() {
    globalCount++;
}

void printCount() {
    printf("%d", globalCount);
}

globalCount 变量仅在当前文件中可见,其他文件无法访问。 

这里有一个很有意思的区别,那静态局部变量和全局变量有什么区别呢??

个人认为有两大区别

1作用域

静态局部变量的作用域仅限于它所在的函数或代码块。也就是说,它只能在定义它的函数内访问,外部代码无法访问它。全局变量的作用域是整个文件(如果使用 static 修饰则局限于文件内部),并且可以在该文件的任何地方访问。

void foo() {
    static int x = 10;  // 仅在 foo 函数内部有效
    printf("%d\n", x);
}

// 无法从外部访问 x

int x = 10;  // 全局变量

void foo() {
    printf("%d\n", x);  // 在 foo 函数内访问全局变量
}
2 访问权限

静态局部变量只能在定义它的函数内访问,外部无法访问或修改它,即它的作用域受限于该函数。全局变量在整个程序中都可以访问,包括其他文件(通过 extern 声明)。

void foo() {
    static int x = 5;  // 静态局部变量
    printf("%d\n", x);
}

int main() {
    foo();  // 可以访问静态局部变量
    // printf("%d", x);  // 错误:x 不能在 main() 中访问
    return 0;
}






int x = 10;  // 全局变量

void foo() {
    printf("%d\n", x);  // 可以访问全局变量
}

int main() {
    foo();  // 访问全局变量
    printf("%d\n", x);  // 也可以在 main 中访问
    return 0;
}

4.其他关键字

1.const

const 关键字用于声明常量或只读变量。它保证了变量的值在初始化后无法被修改。在声明时,使用 const 可以确保某个值在程序执行过程中保持不变。

  • const 可用于常量或只读参数的定义,使得该变量在程序执行过程中不允许被改变。
  • 常用于函数参数,以保证输入数据不被修改。
  • 还可以用于数组、指针、结构体等。(主要用途)
const int* ptr;  // 声明一个指向常量的指针,指针所指向的数据不能修改

2.sizeof

sizeof 运算符用于返回类型或变量所占的内存字节数。它在编译时就会计算出结果,而不是在运行时计算。它是一个非常重要的工具,尤其是在处理动态内存分配、数组或不同类型时。

  • 计算数据类型的大小。
  • 计算数组的元素个数。
  • 获取结构体或类对象的内存大小。
int x = 5;
printf("%lu\n", sizeof(x));  // 输出 int 类型所占字节数

 通常被认为是string.h内的函数,也可以当作函数来调用。

3.typedef

typedef 用于为现有的数据类型创建一个新的别名。它不会创建新的数据类型,而是简单地为已有类型提供一个新的名称。这使得代码更易于阅读、理解和维护。

  • 改进代码的可读性:尤其在结构体、指针、函数指针等复杂数据类型上,使用 typedef 可以让代码看起来更简洁。
  • 创建结构体类型的别名,简化代码。
typedef struct {
    int x;
    int y;
} Point;  // 创建一个结构体类型别名 Point
Point p1;  // 使用 Point 来定义结构体变量

4. volatile

volatile 关键字用于告诉编译器,修饰的变量可能会在程序的不同地方被修改,而编译器在优化时不应假设该变量的值不会改变。它常用于硬件寄存器、外部设备的状态寄存器、或多线程程序中的共享数据。

  • volatile 关键字告诉编译器,该变量的值在任何时刻都可能被外部因素修改(例如硬件中断、外部输入或多个线程)。
  • 编译器不会对带有 volatile 修饰符的变量进行优化处理,避免将其缓存到寄存器中或减少对该变量的访问次数。
volatile int flag = 0;
void check_flag() {
    while (flag == 0) {  // 如果没有 volatile,编译器可能优化掉这个循环
        // 等待 flag 变为非零
    }
}

 在多线程环境下,一个线程可能会修改 flag,另一个线程需要读取这个值。如果没有 volatile,编译器可能会假设 flag 不会发生变化,从而优化掉对它的检查。这会导致程序错误。


网站公告

今日签到

点亮在社区的每一天
去签到