C语言入门系列:三个与函数相关的关键字extern/static/const

文章目录

在C语言编程中,函数是执行特定任务的代码块。

为了更好地控制函数的行为和属性,C语言提供了一系列的与函数相关的关键字,如externconststatic

这些说明符能够影响函数的链接属性、常量性以及存储方式,从而帮助程序员更精确地管理程序的结构和资源。

一,extern 函数说明符

1,含义与用途

extern关键字用于声明函数或全局变量存在于另一个文件中,即将要使用的函数或变量是在其他源文件中定义的。

它主要用于解决跨文件引用的问题,使得编译器知道该函数或变量将在程序的其他部分定义。

2,示例代码

main.c

c 复制代码
#include <stdio.h>

// 声明extern函数
extern int add(int a, int b);

int main() {
    int result = add(5, 3);
    printf("The sum is: %d\n", result);
    return 0;
}

functions.c

c 复制代码
int add(int a, int b) {
    return a + b;
}

在这个例子中,add函数在functions.c文件中定义,而在main.c文件中通过extern进行了声明。

这样,main.c就能够调用functions.c中的add函数,而无需了解其具体实现细节。

不过,由于函数原型默认就是extern,所以这里不加extern,效果是一样的。

二,const 函数参数说明符

1,含义与用途

在函数参数前使用const关键字,表示该参数在函数内部被视为只读,不可被修改,启动对变量值的保护作用。

这有助于提高代码的安全性和可读性,同时也便于编译器进行类型检查,避免无意中修改了不应改动的数据。

2,保护指针指向的内存

c 复制代码
#include <stdio.h>

// 使用const修饰参数,表示不修改传入的字符串
void printMessage(const char* message) {
    printf("%s\n", message);
    // 修改指针指向的内存值,编译器会报错
    *message = "更新message";
}

int main() {
    char greeting[] = "Hello, World!";
    printMessage(greeting);
    return 0;
}

上述代码中,printMessage函数的参数message前有const修饰,这意味着函数内部不能更改message指向的字符串内容。这向阅读代码的人明确表示了函数的设计意图------只读取而不修改输入的字符串。

但是,要注意的是指针变量本身是可以被修改的,不能修改的指针指向的内存中的值。

// 使用const修饰参数,表示不修改传入的字符串
void printMessage(const char* message) {
    printf("%s\n", message);
    // 修改指针指向的内存值,编译器会报错
    *message = "更新message";
  
   int num = 100;
   // 更新message变量本身是允许的,更新之后message指向一个新的地址
   message = &num;
}

int main() {
    char greeting[] = "Hello, World!";
    printMessage(greeting);
    return 0;
}

2,双重保护:保护指针指向的内存和指针本身不被修改

如果要保护指针指向的内存和指针本身不被修改,如果想同时限制修改message和*message,需要使用两个const。

// 使用const修饰参数,表示不修改传入的字符串
void printMessage(const char* const message) {
    printf("%s\n", message);
    // 修改指针指向的内存值,编译器会报错
    *message = "更新message";
  
   int num = 100;
   // 更新message变量本身也报错
   message = &num;
}

int main() {
    char greeting[] = "Hello, World!";
    printMessage(greeting);
    return 0;
}

三,static 函数说明符

1,static用在函数声明中

当在函数声明前加上static关键字时,该函数变为静态函数,意味着它的作用域仅限于定义它的文件内。

静态函数不能被其他文件访问,这有助于隐藏实现细节,减少命名冲突,并可能带来性能上的微小提升(因为编译器可以做出更好的优化)。

utils.c

c 复制代码
#include <stdio.h>

// 静态函数,仅在本文件中可见
static void privateFunction() {
    printf("This function is private.\n");
}

void publicFunction() {
    privateFunction();
}

main.c

c 复制代码
#include <stdio.h>

void publicFunction();

int main() {
    publicFunction(); // 正确调用
    // privateFunction(); // 错误!无法直接访问privateFunction
    return 0;
}

在这个例子中,privateFunction被声明为静态函数,因此只能在utils.c文件中被调用。尽管publicFunction能够调用privateFunction,但main.c中的代码却无法直接访问到privateFunction,体现了static关键字在限制函数作用域方面的作用。

2,static用在局部变量声明中

static用于函数内部变量,使用static说明符修饰,表明被修饰变量只初始化一次,以后每次调用时都会使用上一次的值,造成递增的效果。

注意,static修饰的变量初始化时,只能赋值为常量,不能赋值为变量。

clike 复制代码
#include <stdio.h>

void countCalls() {
    // static变量必须赋常量
    static int callCount = 0;
    int num = 1;
    // 不能把变量赋值给static变量
    static int num2 = num;
    callCount++;
    printf("Function has been called %d times.\n", callCount);
}

int main() {
    // 第一次调用后callCount的值是1
    countCalls();
    // 第一次调用后callCount的值是2
    countCalls();
    return 0;
}

callCount是一个静态局部变量,每次函数调用时,其值不会被重置,而是在上一次调用的基础上加1,展示了静态局部变量在函数调用间保持状态的能力。

小结

总结来说,externconststatic这三个函数说明符分别用于指示函数的外部链接、参数的只读属性以及函数的作用域限制,它们都是C语言中用于增强程序设计灵活性和健壮性的有力工具。

参考文献

1,C语言 总结const的用法

相关推荐
嵌入式科普1 小时前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长
A懿轩A1 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
1 9 J2 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
仍然探索未知中3 小时前
C语言经典100例
c语言
爱吃西瓜的小菜鸡4 小时前
【C语言】矩阵乘法
c语言·学习·算法
Stark、5 小时前
【Linux】文件IO--fcntl/lseek/阻塞与非阻塞/文件偏移
linux·运维·服务器·c语言·后端
deja vu水中芭蕾5 小时前
嵌入式C面试
c语言·开发语言
stm 学习ing7 小时前
HDLBits训练3
c语言·经验分享·笔记·算法·fpga·eda·verilog hdl
CSND74011 小时前
Ubuntu vi(vim)编辑器配置一键补全main函数
linux·c语言·ubuntu·编辑器·vim
Crazy learner12 小时前
C 和 C++ 动态库的跨语言调用原理
c语言·c++