1.0 strlen与sizeof的比较
- 定义与作用
strlen | sizeof |
---|---|
是 <string.h> 中的库函数,计算字符串的实际长度(直到遇到 \0,但不包括 \0)。 | 是C语言的关键字(运算符),计算变量或类型占用的内存字节数(编译时确定)。 |
只能用于以 \0 结尾的字符串。 | 可用于任何数据类型(基本类型、数组、结构体等)。 |
- 关键区别
区别点 | strlen | sizeof |
---|---|---|
作用对象 | 仅字符串(char* 或字符数组)。 | 任意变量或类型。 |
空字符\0 |
忽略 \0 |
包含 \0 占用的空间(如果存在)。 |
执行时机 | 运行时计算。 | 编译时确定。 |
返回值类型 | size_t(字符串实际字符数)。 | size_t(变量/类型占用的总字节数)。 |
- 典型示例
- 示例1:字符数组
char str[] = "Hello";
printf("strlen: %zu\n", strlen(str)); // 输出 5(不包含 \0)
printf("sizeof: %zu\n", sizeof(str)); // 输出 6(包含 \0,且数组总大小)
- 示例2:指针与动态内存
char *p = "Hello";
char arr[10] = "Hello";
char *dynamic = malloc(100 * sizeof(char));printf("sizeof(p): %zu\n", sizeof(p)); // 输出指针大小(如 8 字节,64位系统)
printf("sizeof(arr): %zu\n", sizeof(arr)); // 输出 10(数组总大小)
printf("sizeof(dynamic): %zu\n", sizeof(dynamic)); // 仍为指针大小(如 8 字节)
- 联系与总结
-
联系:两者均可用于字符数组,但关注点不同:
-
strlen 关注字符串内容的逻辑长度。
-
sizeof 关注变量/类型的物理内存占用。
-
-
总结:
-
需要字符串长度时用 strlen(确保字符串以 \0 结尾)。
-
需要内存大小时用 sizeof(注意数组和指针的差异)。
-
-
核心记忆点:
- strlen 是“数字符”,sizeof 是“量内存”。
2.0 static 介绍
在C语言中,static
是一个重要的关键字,它的作用根据上下文不同而有多种含义。以下是 static
关键字的详细解析:
2.1 修饰局部变量(在函数内部)
void func() {static int count = 0; // 静态局部变量count++;printf("%d\n", count);
}
-
作用:
- 生命周期:变量在程序运行期间一直存在(存储在静态存储区),即使函数退出也不会被销毁。
- 初始化:只初始化一次(默认初始化为0)。
- 作用域:仍只能在函数内部访问。
-
示例:
调用func()
多次,count
的值会持续递增(如第1次调用输出1,第2次输出2)。
2.2 修饰全局变量(在函数外部)
static int global_var = 10; // 静态全局变量void func() {printf("%d\n", global_var);
}
- 作用:
- 作用域限制:将全局变量的作用域限定为当前源文件(
.c
文件),其他文件无法通过extern
引用。 - 避免命名冲突:常用于模块化编程,隐藏全局变量。
- 作用域限制:将全局变量的作用域限定为当前源文件(
2.3 修饰函数
static void private_func() { // 静态函数printf("This is a static function.\n");
}
- 作用:
- 作用域限制:函数只能在当前源文件中调用,其他文件无法访问。
- 隐藏实现:防止其他文件调用内部函数,增强代码封装性。
2.4 核心区别与总结
场景 | 作用 |
---|---|
局部变量 | 延长生命周期,保持值的持久性(不改变作用域)。 |
全局变量 | 限制作用域到当前文件,避免全局污染。 |
函数 | 限制函数作用域到当前文件,实现模块化。 |
2.5 典型应用场景
- 计数器:用静态局部变量统计函数调用次数。
- 单例模式:结合静态变量实现资源单例。
- 模块化设计:隐藏内部变量和函数,只暴露接口。
- 线程安全:静态变量在多线程中需谨慎使用(需加锁)。
2.6 注意事项
- 默认初始化:静态变量(未显式初始化)会被自动初始化为0或
NULL
。 - 不可重入性:静态局部变量可能导致函数不可重入(非线程安全)。
- 内存占用:静态变量始终占用内存,直到程序结束。
2.7一句话总结
static
的三大用途:延长局部变量生命周期、限制全局变量/函数作用域、隐藏实现细节。
核心本质:控制作用域和生命周期。
2.8 特别的
场景 | 是否合法 | 作用 |
---|---|---|
void func(static int param) |
❌ 非法 | 语法错误,存储类说明符不可用于参数声明 |
void func(int arr[static 10]) |
✅ 合法(C99) | 提示编译器 arr 指向至少10个元素的数组 |