首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【C语言入门】解锁核心关键字的终极奥秘与实战应用(一)

【C语言入门】解锁核心关键字的终极奥秘与实战应用(一)

作者头像
用户12001910
发布2026-01-20 19:34:48
发布2026-01-20 19:34:48
120
举报

C语言的关键字在编程中至关重要,它们定义了程序的基本结构,控制变量的存储、函数的声明与定义,以及程序的流程控制。这些关键字是C语言功能强大的基础,确保了程序的正确性和高效性,是编写C语言程序不可或缺的要素。

一、void

在C语言编程中,void 关键字具有特殊的含义,它表示“无类型”。void 可以用于多种上下文,包括作为函数的返回类型、函数参数的占位符,以及在指针类型中表示通用指针

1.1. 作用

  • 函数返回类型:当 void 用作函数的返回类型时,表示该函数不返回任何值。这种函数通常用于执行某些操作,如打印输出、修改全局变量或执行某些计算但不返回结果。
  • 函数参数占位符:在函数定义中,如果参数列表为 void(实际上在C语言中函数参数列表为空时通常省略 void,直接写为 ()),则表示该函数不接受任何参数。然而,更常见的是,当函数不接受参数时,参数列表被省略为空,而不是显式地写为 (void)。但在某些上下文中,如函数指针类型定义中,使用 (void) 来明确指出不接受参数可能更为清晰。
  • 通用指针类型void * 表示一个指向任意类型的指针。这种指针可以用于存储任何类型的地址,但在使用之前需要进行类型转换。

1.2. 代码示例

1. 函数返回类型为 void

代码语言:javascript
复制
#include <stdio.h>  
  
// 定义一个返回类型为 void 的函数  
void printMessage() {  
    printf("This is a message from a void function.\n");  
}  
  
int main() {  
    printMessage(); // 调用 void 函数  
    return 0;  
}
  • 运行结果:

printMessage 函数不返回任何值,它的作用仅仅是打印一条消息。

2. 函数参数列表为 void(虽然通常省略):虽然C语言标准中函数不接受参数时参数列表通常省略为空 (),但某些情况下为了明确表明不接受参数,可以使用 (void)。这在函数指针类型定义中更为常见。

代码语言:javascript
复制
#include <stdio.h>  
  
// 定义一个不接受参数的函数(通常省略 void,这里为了说明而显式写出)  
void doNothing(void) {  
    // 不执行任何操作  
}  
  
int main() {  
    doNothing(); // 调用不接受参数的函数  
    return 0;  
}

然而,在实际代码中,doNothing() 的定义更常见地写作 void doNothing() 而不是 void doNothing(void),因为前者是C语言的传统写法。

3. void * 作为通用指针类型

代码语言:javascript
复制
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
  
// 定义一个使用 void* 的函数,用于复制内存块  
void* myMemcpy(void* dest, const void* src, size_t n) {  
    // 注意:这里只是示例,实际的 memcpy 实现会更为复杂  
    char* d = (char*)dest;  
    const char* s = (const char*)src;  
    while (n--) {  
        *d++ = *s++;  
    }  
    return dest;  
}  
  
int main() {  
    char source[] = "Hello, World!";  
    char destination[20];  
      
    // 使用 myMemcpy 复制字符串  
    myMemcpy(destination, source, strlen(source) + 1); // 加1是为了包含终止符 '\0'  
      
    printf("Destination: %s\n", destination);  
      
    return 0;  
}
  • 运行结果:

myMemcpy 函数接受 void* 类型的参数,意味着它可以接受任何类型的指针作为源和目标。然而,在实际使用中,需要注意类型转换和内存对齐等问题,并且通常建议使用标准库中的 memcpy 函数来代替自己实现的版本。

二、基本数据类型(char、int、float、double等)

在C语言编程中,charintfloatdouble等是定义变量的基本数据类型,它们各自具有特定的存储大小和取值范围。这些数据类型是编程的基础,用于存储和处理不同类型的数据。

2.1. char(字符类型)

  • 存储大小:通常为1字节(8位)。
  • 取值范围:在ASCII码表中,取值范围为0到127(或-128到127,取决于编译器和字符集)。在扩展的ASCII码或Unicode中,取值范围可能更大。
  • 用途:用于存储单个字符,如字母、数字或符号。

2.2. int(整型)

  • 存储大小:通常为2字节(16位)、4字节(32位)或8字节(64位),取决于编译器和平台。
  • 取值范围:取决于存储大小和是否有符号(signed)或无符号(unsigned)。例如,32位有符号整型的取值范围为-2,147,483,648到2,147,483,647。
  • 用途:用于存储整数。

2.3. float(单精度浮点型)

  • 存储大小:通常为4字节(32位)。
  • 取值范围:大约为3.4E-38到3.4E+38,精度约为7位十进制数。
  • 用途:用于存储小数或需要高精度的数值计算。

2.4. double(双精度浮点型)

  • 存储大小:通常为8字节(64位)。
  • 取值范围:大约为2.2E-308到1.8E+308,精度约为15位十进制数。
  • 用途:用于需要更高精度的数值计算。

2.5. 代码示例

代码语言:javascript
复制
#include <stdio.h>  
#include <limits.h> // 包含整型限制值的头文件  
#include <float.h>  // 包含浮点型限制值的头文件  
  
int main() {  
    // char 类型示例  
    char ch = 'A';  
    printf("char: %c, ASCII value: %d\n", ch, (int)ch);  
  
    // int 类型示例  
    int i = INT_MAX; // 使用 LIMITS_H 中定义的常量  
    printf("int (max): %d\n", i);  
    int j = -INT_MAX - 1; // 最小负整数值(对于有符号整型)  
    printf("int (min): %d\n", j);  
  
    // float 类型示例  
    float f = FLT_MAX; // 使用 FLOAT_H 中定义的常量  
    printf("float (max): %f\n", f);  
    float g = 1.23456789f; // 注意:末尾的 f 表示这是一个 float 类型的字面量  
    printf("float: %.8f\n", g); // 打印8位小数以显示精度  
  
    // double 类型示例  
    double d = DBL_MAX; // 使用 FLOAT_H 中定义的常量  
    printf("double (max): %lf\n", d);  
    double e = 1.23456789012345; // double 类型的字面量不需要特殊后缀  
    printf("double: %.15lf\n", e); // 打印15位小数以显示精度  
  
    return 0;  
}

定义了不同类型的变量,并使用标准库中的常量(如INT_MAXFLT_MAX)来展示这些类型的取值范围。还打印了浮点数的值,并指定了小数点后的位数来展示它们的精度。

实际运行结果:

请注意,实际的取值范围和精度可能因编译器和平台的不同而有所差异。上述代码中的常量(如INT_MAXFLT_MAX)是通过包含<limits.h><float.h>头文件来获取的,这些头文件提供了与数据类型限制和属性相关的宏定义。

三、控制流程语句(if、else、switch、case、default等)

在编程中,控制流程语句用于根据条件改变程序的执行路径。C语言提供了几种基本的控制流程语句,包括ifelseswitchcasedefault,它们允许程序根据特定的条件执行不同的代码块。

3.1. if 和 else 语句

if语句用于根据条件判断执行特定的代码块。如果条件为真(非零),则执行if块中的代码。else语句与if语句配对使用,当if条件为假(零)时,执行else块中的代码。

  • 代码示例
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    int number = 10;  
  
    if (number > 0) {  
        printf("The number is positive.\n");  
    } else {  
        printf("The number is not positive.\n");  
    }  
  
    return 0;  
}
  • 实际运行结果:

因为number大于0,所以程序会打印“The number is positive.”。

3.2. switch 语句

switch语句提供了一种更简洁的方式来处理多个条件。它根据一个变量的值选择执行多个代码块中的一个。case标签用于指定要匹配的值,而default标签用于处理所有不匹配的情况。

  • 代码示例
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    int day = 3;  
  
    switch (day) {  
        case 1:  
            printf("Monday\n");  
            break;  
        case 2:  
            printf("Tuesday\n");  
            break;  
        case 3:  
            printf("Wednesday\n");  
            break;  
        case 4:  
            printf("Thursday\n");  
            break;  
        case 5:  
            printf("Friday\n");  
            break;  
        case 6:  
            printf("Saturday\n");  
            break;  
        case 7:  
            printf("Sunday\n");  
            break;  
        default:  
            printf("Invalid day\n");  
            break;  
    }  
  
    return 0;  
}
  • 运行结果:

day的值是3,所以程序会打印“Wednesday”。注意,每个case块通常以break语句结束,以防止“贯穿”(即执行完一个case块后继续执行下一个case块的代码)。如果没有break,则称为“fall-through”,这有时是有用的,但通常是一个错误。

3.3. 注意事项

  • ifelse语句可以嵌套使用,以处理更复杂的条件逻辑。
  • switch语句中,case标签必须是常量表达式,并且switch表达式的类型必须与case标签的类型兼容。
  • default标签是可选的,但如果提供了,它应该是switch语句中的最后一个标签(尽管在技术上它可以放在任何位置,但放在最后更符合逻辑和可读性)。
  • 如果switch语句中没有break语句,则程序将继续执行下一个case块(或default块,如果存在的话),直到遇到breakswitch语句的末尾。这种行为称为“贯穿”(fall-through)

四、循环控制语句(for、while、do-while)

在编程中,循环控制语句允许程序重复执行某段代码,直到满足特定的条件为止。C语言提供了三种基本的循环控制语句:forwhiledo-while

4.1. for 循环

for循环是最常用的循环结构之一,它通常用于已知循环次数的场景。for循环的语法结构包括初始化部分、条件判断部分和迭代部分,这些部分都包含在圆括号中,并以分号分隔。

  • 代码示例
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    for (int i = 0; i < 5; i++) {  
        printf("i = %d\n", i);  
    }  
    return 0;  
}

for循环从i = 0开始,每次循环迭代后i的值增加1,直到i的值达到5为止。因此,循环体内的代码会执行5次,分别打印出i的值为0到4。

4.2. while 循环

while循环在每次迭代之前都会检查条件是否为真。如果条件为真,则执行循环体内的代码;如果条件为假,则跳出循环。while循环通常用于不确定循环次数的场景,但可以通过某种方式在循环体内更新条件以确保最终能够跳出循环。

  • 代码示例
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    int i = 0;  
    while (i < 5) {  
        printf("i = %d\n", i);  
        i++;  
    }  
    return 0;  
}
  • 运行结果:

while循环的行为与前面的for循环相同,都是打印出i的值为0到4。

4.3. do-while 循环

do-while循环与while循环类似,但有一个重要的区别:do-while循环至少会执行一次,因为条件检查是在循环体的末尾进行的。意味着,即使条件一开始就是假的,do-while循环体内的代码也会执行一次。

  • 代码示例
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    int i = 0;  
    do {  
        printf("i = %d\n", i);  
        i++;  
    } while (i < 5);  
    return 0;  
}
  • 运行结果:

do-while循环同样会打印出i的值为0到4。与while循环不同的是,即使将i的初始值设置为5(或任何大于或等于5的值),do-while循环体内的代码仍然会执行一次(尽管在这种情况下,条件判断会立即失败,导致循环不会再次执行)。

4.4. 注意事项

  • 在使用循环时,确保循环条件最终能够变为假,以避免无限循环。
  • 小心处理循环中的变量更新,确保它们在每次迭代后都按照预期的方式改变。
  • for循环中声明的变量(如上面的int i = 0;)在循环结束后将不再可用。这是因为它们在循环的初始化部分中声明,并且其作用域仅限于循环体。
  • 使用适当的缩进和代码格式来提高循环结构的可读性。

五、控制流程改变语句(break、continue、goto)

在编程中,breakcontinuegoto语句用于改变程序的正常流程。它们允许程序在特定条件下提前跳出循环、跳过当前迭代或跳转到指定的代码位置。

5.1. break 语句

break语句用于立即终止最近的循环或switch语句。当程序执行到break时,它会跳出当前的循环或switch块,并继续执行紧随其后的代码。

  • 代码示例
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    for (int i = 0; i < 10; i++) {  
        if (i == 5) {  
            break; // 当i等于5时,跳出循环  
        }  
        printf("i = %d\n", i);  
    }  
    printf("Loop exited.\n");  
    return 0;  
}
  • 运行结果:

i等于5时,break语句会终止for循环,程序会继续执行Loop exited.的打印语句。

5.2. continue 语句

continue语句用于跳过当前循环迭代中的剩余部分,并立即开始下一次迭代。它不会终止整个循环,只是跳过当前迭代中continue之后的代码。

  • 代码示例
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    for (int i = 0; i < 10; i++) {  
        if (i % 2 == 0) {  
            continue; // 跳过偶数  
        }  
        printf("i = %d\n", i);  
    }  
    return 0;  
}
  • 运行结果:

continue语句会跳过所有偶数的打印,因此只有奇数(1, 3, 5, 7, 9)会被打印出来。

5.3. goto 语句

goto语句允许程序跳转到同一个函数内的指定标签位置。尽管goto在某些情况下可能很有用(例如,从深层嵌套的循环中跳出),但它通常被认为是一种不良的编程实践,因为它会使代码难以理解和维护。因此,在现代编程中,应尽量避免使用goto

  • 代码示例(尽管不推荐使用,但为了完整性而提供):
代码语言:javascript
复制
#include <stdio.h>  
  
int main() {  
    int i = 0;  
  
    if (i == 0) {  
        goto skip; // 跳转到标签skip  
    }  
  
    printf("This will not be printed.\n");  
  
    skip: // 标签skip  
    printf("i = %d, jumping here.\n", i);  
  
    return 0;  
}
  • 运行结果:

由于i等于0,程序会跳转到标签skip的位置,并打印出i = 0, jumping here.This will not be printed.语句将不会被执行。

5.4. 注意事项

  • 谨慎使用goto语句,因为它会破坏代码的结构和可读性。
  • breakcontinue语句通常用于循环和switch语句中,以改变它们的正常流程。
  • 在使用breakcontinue时,确保它们不会导致逻辑错误或无限循环。

通过合理使用这些控制流程改变语句,可以编写出更加灵活和强大的程序。然而,应始终注意保持代码的可读性和可维护性,避免过度使用这些语句导致代码变得难以理解。

六、return

6.1. 作用

1. 结束函数执行:当执行到return语句时,函数会立即停止执行,并将控制权返回给调用该函数的地方。

2. 返回值

  • 如果函数返回类型为void,则return语句不需要(也不能)包含返回值。
  • 如果函数返回类型不是void,则return语句必须包含一个与该返回类型相匹配的值。

3. 返回值的使用:调用者可以使用从函数返回的值进行进一步的操作。

6.2. 代码示例

示例1:返回类型为void的函数

代码语言:javascript
复制
#include <stdio.h>  
  
void printMessage() {  
    printf("This is a message.\n");  
    return; // 结束函数执行,不需要返回值  
}  
  
int main() {  
    printMessage();  
    return 0;  
}

printMessage函数没有返回值(返回类型为void),因此return语句后面没有跟任何值。

示例2:返回类型为int的函数

代码语言:javascript
复制
#include <stdio.h>  
  
int add(int a, int b) {  
    return a + b; // 返回两个整数的和  
}  
  
int main() {  
    int sum = add(3, 4); // 调用add函数,并将返回值赋给sum  
    printf("Sum: %d\n", sum); // 输出:Sum: 7  
    return 0;  
}

add函数返回两个整数的和,类型为int。在main函数中,调用add函数,并将返回值(即3和4的和)赋给变量sum

示例3:没有显式返回值的非void函数(错误示例)

代码语言:javascript
复制
#include <stdio.h>  
  
int getNumber() {  
    // 这里缺少return语句,这是一个错误  
}  
  
int main() {  
    int num = getNumber(); // 这将导致未定义行为,因为getNumber没有返回值  
    printf("Number: %d\n", num);  
    return 0;  
}

在这个错误的例子中,getNumber函数应该返回一个整数,但实际上没有返回任何值。这将导致未定义行为,因为main函数中的num变量将接收一个未初始化的值。

注意:在C/C++等语言中,如果函数声明了返回类型(不是void),则必须确保在所有可能的执行路径上都有return语句返回一个值。否则,编译器将报错或产生未定义行为。


博主简介 byte轻骑兵,现就职于国内知名科技企业,专注于嵌入式系统研发,深耕 Android、Linux、RTOS、通信协议、AIoT、物联网及 C/C++ 等领域。乐于技术分享与交流,欢迎关注互动! 📌 主页与联系方式

  • CSDN:https://blog.csdn.net/weixin_37800531
  • 知乎:https://www.zhihu.com/people/38-72-36-20-51
  • 微信公众号:嵌入式硬核研究所
  • 邮箱:byteqqb@163.com(技术咨询或合作请备注需求)

⚠️ 版权声明 本文为原创内容,未经授权禁止转载。商业合作或内容授权请联系邮箱并备注来意。


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、void
    • 1.1. 作用
    • 1.2. 代码示例
  • 二、基本数据类型(char、int、float、double等)
    • 2.1. char(字符类型)
    • 2.2. int(整型)
    • 2.3. float(单精度浮点型)
    • 2.4. double(双精度浮点型)
    • 2.5. 代码示例
  • 三、控制流程语句(if、else、switch、case、default等)
    • 3.1. if 和 else 语句
    • 3.2. switch 语句
    • 3.3. 注意事项
  • 四、循环控制语句(for、while、do-while)
    • 4.1. for 循环
    • 4.2. while 循环
    • 4.3. do-while 循环
    • 4.4. 注意事项
  • 五、控制流程改变语句(break、continue、goto)
    • 5.1. break 语句
    • 5.2. continue 语句
    • 5.3. goto 语句
    • 5.4. 注意事项
  • 六、return
    • 6.1. 作用
    • 6.2. 代码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档