格式
数据类型 变量名;
【理解】:
- 数据类型的部分一般会用到数据类型关键字来表示,比如:int 、 double
- 变量名部分要求遵循用户标识符的规范。
- 任何的定义变量形式,都是先找标识符,然后把标识符和分号去除后,剩下的部分就是数据类型。
C
int a;//变量名是a,类型为int
double b;//变量名是b,类型为double
char c[5];//变量名是c,类型为char [5]
int d[3][4];//变量名是d,类型为int [3][4]
int *e;//变量名是e,类型为int *
int **f;//变量名是f,类型为int **
int * (*g)(double, int (*)(char));//变量名是g,类型为int * (*)(double, int (*)(char))
分配空间
C语言中,当定义变量语句被执行后,操作系统将会给变量分配空间。
分配的空间大小由定义时采用的数据类型决定,每种数据类型对应的空间占用情况遵循规则:
1.如果是基本数据类型,占用固定空间,这个由C语言官方规定的。
2.如果是构造数据类型,则与构造方式有关。
3.如果是指针类型,占用4Byte(编译环境是32位) 或 8Byte(编译环境64位)。

总结:
1.定义变量后,操作系统会为变量分配空间,空间大小与数据类型有关。
2.操作变量的本质,是操作变量在内存中对应的一段空间。变量名相当于一种代号,能帮助访问到内存中的一段空间。
3.变量的空间最迟会在程序运行结束时,自动回收其空间。
计算变量/数据类型的空间占用
采用 sizeof( ) 来计算变量占用空间大小,或某种数据类型占用的空间大小。
sizeof( )构成的表达式结果是一个整数。
用法:在sizeof( ) 的括号中填入已定义的变量名或某种数据类型。

Sizeof,是一个运算符,计算所占空间的大小。(包含\0)
Strlen 是一个函数,计算字符串所占的大小(不包含\0)
strlen和Sizeof的区别
在C语言中,strlen和sizeof都可以用于计算字符串相关的长度,但它们的工作原理和用途有本质区别。
strlen 函数
工作原理
strlen是一个库函数,通过 遍历内存直到遇到空字符'\0' 来计算字符串长度。
c
#include <string.h>
size_t strlen(const char *str);
实现原理:
c
// strlen的简化实现
size_t my_strlen(const char *str) {
size_t len = 0;
while (*str != '\0') {
len++;
str++;
}
return len;
}
特点
- 运行时计算:需要遍历整个字符串
- 不包含空字符:返回的是有效字符的个数
- 需要头文件 :
#include <string.h> - 时间复杂度:O(n)
示例
c
char str[] = "hello";
printf("strlen: %zu\n", strlen(str)); // 输出:5
char *ptr = "world";
printf("strlen: %zu\n", strlen(ptr)); // 输出:5
sizeof 运算符
工作原理
sizeof是一个编译时运算符,计算变量或类型在内存中占用的字节数。
c
sizeof(expression) 或 sizeof(type)
特点
- 编译时计算:在编译阶段就确定结果
- 包含空字符:对于字符数组,包含整个数组大小,包括'\0'
- 不需要头文件:是C语言关键字
- 时间复杂度:O(1)
示例
c
char str[] = "hello";
printf("sizeof: %zu\n", sizeof(str)); // 输出:6(包含'\0')
char *ptr = "world";
printf("sizeof: %zu\n", sizeof(ptr)); // 输出:4或8(指针大小)
关键区别对比
| 特性 | strlen | sizeof |
|---|---|---|
| 类型 | 库函数 | 运算符 |
| 计算时机 | 运行时 | 编译时 |
| 包含空字符 | 否 | 是(对数组) |
| 参数类型 | 只接受字符串 | 任何类型 |
| 指针参数 | 计算字符串长度 | 返回指针大小 |
| 数组参数 | 计算字符串长度 | 返回数组总大小 |
详细示例分析
c
#include <stdio.h>
#include <string.h>
int main() {
// 情况1:字符数组
char str1[] = "hello";
printf("str1 - strlen: %zu, sizeof: %zu\n", strlen(str1), sizeof(str1));
// 输出:str1 - strlen: 5, sizeof: 6
// 情况2:字符指针
char *str2 = "hello";
printf("str2 - strlen: %zu, sizeof: %zu\n", strlen(str2), sizeof(str2));
// 输出:str2 - strlen: 5, sizeof: 8(64位系统)
// 情况3:显式指定数组大小
char str3[20] = "hello";
printf("str3 - strlen: %zu, sizeof: %zu\n", strlen(str3), sizeof(str3));
// 输出:str3 - strlen: 5, sizeof: 20
// 情况4:没有空字符的字符数组
char str4[] = {'h', 'e', 'l', 'l', 'o'};
printf("str4 - strlen: %zu, sizeof: %zu\n", strlen(str4), sizeof(str4));
// strlen结果未定义!sizeof输出:5
return 0;
}
常见陷阱
陷阱1:混淆指针和数组
c
char *str = "hello";
// strlen(str) = 5
// sizeof(str) = 4或8(指针大小)
陷阱2:没有空字符的数组
c
char bad_str[] = {'h', 'e', 'l', 'l', 'o'};
// strlen(bad_str) 行为未定义,可能一直读取直到遇到随机'\0'
陷阱3:函数参数中的数组退化为指针
c
void func(char arr[]) {
// sizeof(arr) 返回指针大小,不是数组大小
printf("sizeof in func: %zu\n", sizeof(arr));
}
使用建议
- 计算字符串长度 :使用
strlen - 计算内存分配大小 :使用
sizeof - 处理字符数组 :注意
sizeof包含空字符 - 处理字符指针 :
sizeof返回的是指针大小
c
// 正确用法
char buffer[100];
strcpy(buffer, "hello");
int string_length = strlen(buffer); // 5
int buffer_size = sizeof(buffer); // 100
int remaining_space = buffer_size - string_length - 1; // 94