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的用法

相关推荐
小莞尔3 天前
【51单片机】【protues仿真】基于51单片机的篮球计时计分器系统
c语言·stm32·单片机·嵌入式硬件·51单片机
小莞尔3 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
liujing102329293 天前
Day03_刷题niuke20250915
c语言
第七序章3 天前
【C++STL】list的详细用法和底层实现
c语言·c++·自然语言处理·list
l1t3 天前
利用DeepSeek实现服务器客户端模式的DuckDB原型
服务器·c语言·数据库·人工智能·postgresql·协议·duckdb
l1t3 天前
利用美团龙猫用libxml2编写XML转CSV文件C程序
xml·c语言·libxml2·解析器
Gu_shiwww3 天前
数据结构8——双向链表
c语言·数据结构·python·链表·小白初步
你怎么知道我是队长3 天前
C语言---循环结构
c语言·开发语言·算法
程序猿编码3 天前
基于 Linux 内核模块的字符设备 FIFO 驱动设计与实现解析(C/C++代码实现)
linux·c语言·c++·内核模块·fifo·字符设备
mark-puls4 天前
C语言打印爱心
c语言·开发语言·算法