文章目录
- [一,`extern` 函数说明符](#一,
extern
函数说明符) - [二,`const` 函数参数说明符](#二,
const
函数参数说明符) - [三,`static` 函数说明符](#三,
static
函数说明符) - 小结
- 参考文献
在C语言编程中,函数是执行特定任务的代码块。
为了更好地控制函数的行为和属性,C语言提供了一系列的与函数相关的关键字,如extern
、const
和static
。
这些说明符能够影响函数的链接属性、常量性以及存储方式,从而帮助程序员更精确地管理程序的结构和资源。
一,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 = #
}
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 = #
}
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,展示了静态局部变量在函数调用间保持状态的能力。
小结
总结来说,extern
、const
和static
这三个函数说明符分别用于指示函数的外部链接、参数的只读属性以及函数的作用域限制,它们都是C语言中用于增强程序设计灵活性和健壮性的有力工具。