news 2026/10/13 7:07:56

C语言sizeof与strlen区别详解:底层原理、数组指针陷阱与笔试真题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言sizeof与strlen区别详解:底层原理、数组指针陷阱与笔试真题

先问你一道送分题:char s[] = "hello";那么sizeof(s)和strlen(s)分别是多少?

答案是6和5。可别小看这一题,据这些年我面试新人、帮网友改代码的经验,能在五分钟内把这两个东西讲清楚的人,连三分之一都不到。很多人字符串处理写得飞起,一问sizeof到底算的是哪块内存、strlen为什么需要头文件、数组名传进函数后为什么就“变了”,立刻卡壳。

这篇文章我就把sizeof和strlen的底层原理、使用场景、笔试高频陷阱一次性讲透,再带你把网上流传的经典真题和易错选项逐题拆解一遍。内容覆盖数组、指针、字符串字面量、结构体对齐、动态内存申请这些 C 语言基础核心知识点。适合三类人看:刚学完 C 语法想补基础入门知识的同学;准备校招笔试、需要刷sizeof和strlen相关习题的应届生;还有工作几年但遇到类似题目依然凭感觉猜答案的在职工程师。

建议你找个能敲代码的环境,边看边跑一遍,印象会深得多。

1. 先分清身份:一个是运算符,一个是库函数

1.1 sizeof 是关键字,不是函数,也不需要头文件

很多初学 C 的朋友被网上的写法误导,以为sizeof是库函数,还要问“sizeof 函数需要头文件吗”。这里我明确告诉你:sizeof在 C 语言里是关键字,是运算符,不是函数。

它长得像函数,是因为我们习惯写成sizeof(类型)或sizeof(变量),括号看起来像函数调用。但 C 标准规定sizeof是单目运算符,优先级和++、-这类符号相同。对普通变量操作时,括号甚至可以不写,比如:

int x = 10; printf("%zu\n", sizeof x); // 不写括号也能编译

我在真实项目代码里见过有人写sizeof x,语法上合法,但我个人不建议你在工程里这样写,可读性太差。笔试如果碰到这种写法,你要能看懂,它和sizeof(x)等价。

既然是关键字,它就不需要任何头文件。这点一定要记牢:sizeof是编译器认识的符号,不是运行时从某个库里调出来的函数。

sizeof的核心运作机制是编译期求值。编译器在编译阶段就能算出结果,生成的可执行代码里,sizeof(x)已经被替换成了一个整数常量。所以它不消耗运行时间,也不执行括号里的表达式。下一章我会用sizeof(i++)这个经典例子给你看它到底有多“懒”。

1.2 strlen 是标准库函数,必须包含 <string.h>

strlen就完全是另一回事了。它是 C 标准库里的函数,原型长这样:

size_t strlen(const char *s);

使用它之前必须包含头文件:

#include <string.h>

strlen的工作原理可以理解为:从你传给它的指针地址开始,一个字节一个字节地往下读,直到遇到第一个'\0'为止,然后把走过的字节个数返回给你。它属于 C 语言字符串函数家族,跟strcpy、strcmp、strcat这些是同一批成员,都在<string.h>里。

这里要引出第一个重要区分:sizeof问的是“这块内存占了多大地方”,strlen问的是“这个字符串到结束符为止有多长”。一个是地盘的大小,一个是内容的长度。

1.3 一张对照表说清本质区别

把两者最关键的区别拉成一张表,建议你直接存下来:

对比项sizeofstrlen
本质运算符 / 关键字C 标准库函数
头文件不需要需要<string.h>
求值时机编译期运行期
参数类型名或变量名以'\0'结尾的字符串指针
返回值对象或类型占用的字节数到第一个'\0'之前的字符个数
是否包含'\0'如果是字符数组,包含不包含
能否作用于未分配初始化的内存可以,只算类型大小不能,会越界读到不确定的字节
对数组名的处理数组名在 sizeof 中保留“整个数组”信息数组名作为参数时退化为指针

这张表只看可能还有点抽象,后面每一章我都配了具体代码示例,把表的每一行对应到真实场景里去理解。

用一个生活类比帮助记忆:sizeof相当于看房产证上的建筑面积,厕所、阳台、墙体全给你算进去;strlen相当于拿着卷尺从大门口往里量,走到第一堵墙('\0')就停下,只算这段可见路径的长度。所以同一个字符数组"hello",sizeof报的是 6 平米的完整结构,strlen量出来的是 5 米的可见路长,剩下 1 平米是藏在墙后的终止符。

2. 字符串与数组:最容易踩的 sizeof 坑

2.1 数组名和指针变量,sizeof 结果差远了

这道题是笔试绝对的高频题:

char s[] = "hello"; char *p = "hello"; printf("%zu %zu\n", sizeof(s), sizeof(p)); printf("%zu %zu\n", strlen(s), strlen(p));

在 64 位环境下,输出结果是:

6 8 5 5

如果你答错成6 5,说明你把p的sizeof结果当成了字符串长度。这就是最大的坑:s是数组,p是指针变量,两者类型完全不同。

对于数组s,sizeof(s)取的是整块数组内存的大小。"hello"在 C 语言里是一个char[6]类型,除了h、e、l、l、o五个字母外,末尾还自动补了一个'\0',所以整块数组占 6 个字节。这里的6是“整个容器的体积”,不是“容器里有效内容的长度”。

对于指针p,它只是一个保存地址的变量。64 位系统上地址宽度是 8 字节,所以sizeof(p)是 8。指针本身不关心你指向的内容是谁、有多长,它只负责存一个地址。你把p指向"hello"也好,指向"hello world"也好,sizeof(p)都是 8,因为指针变量所占的字节数与它指向什么东西毫无关系。

strlen就不同了,它接收参数时只看指针指向的内容,从p指向的地址开始找'\0',找到'o'后面的终止符,返回 5。所以strlen(p)结果和strlen(s)一样,都是 5。

记住这一点:sizeof作用于数组名时,还算你整块地盘;sizeof作用于指针时,只算你用来存地址的那个小格子。两者不要混为一谈。

2.2 函数传参后,数组名“退化”为指针

现在做一道更高频的笔试/面试改编题:

void foo(char s[]) { printf("%zu\n", sizeof(s)); } int main() { char s[100] = "hello"; foo(s); return 0; }

函数内部sizeof(s)输出多少?答案是 8(64 位环境),不是 100。

这就是 C 语言里著名的“数组参数退化”规则。虽然函数签名写的是char s[],看着像数组,但在 C 语言中,函数形参里的数组声明会被编译器自动调整为指针,等价于void foo(char *s)。所以在函数内部,s只是一个指针变量,sizeof(s)也就变成了指针的大小。

这个知识点会直接牵出一个笔试题高频解法错误:很多同学喜欢在函数内部写sizeof(arr) / sizeof(arr[0])来求数组元素个数,比如:

int sum_of_array(int arr[]) { size_t n = sizeof(arr) / sizeof(arr[0]); // 错!arr 是指针 ... }

这里sizeof(arr)是指针大小,sizeof(arr[0])是 int 大小,两个一除在 64 位 Linux 下是 2,根本不是数组元素个数。正确做法是:数组定义在哪个作用域,就在哪个作用域用sizeof算大小;函数内部要拿数组长度,必须通过参数显式传进来。

2.3 字符串字面量的隐藏字符与转义陷阱

再看一个细节:sizeof("hello")为什么是 6?因为字符串字面量在 C 语言中的类型是char[6],它真实地包含末尾的'\0'。strlen("hello")扫到'o'之后的'\0'停下,所以返回 5。

这个差异放在转义字符上会更隐蔽,笔试也爱考。举个例子:

char s[] = "a\tb\n"; printf("%zu %zu\n", sizeof(s), strlen(s));

很多人看到\t和\n,以为这是两个字符,于是猜是 6。实际上\t和\n在 C 语言源码里是转义序列,分别表示一个制表符和一个换行符,每个只占 1 个字符。整个字符串内容是:'a'、'\t'、'b'、'\n'、'\0',一共 5 个字节。所以sizeof(s)输出 5,strlen(s)输出 4。

还有更恶心的:

char s[] = "\0hello"; printf("%zu %zu\n", sizeof(s), strlen(s));

字符串字面量"\0hello"实际存储的字符序列是:'\0'、'h'、'e'、'l'、'l'、'o'、'\0',共 7 个字节。所以sizeof(s)是 7;而strlen(s)从头开始数,第一个字节就是'\0',直接返回 0。

这类题考的其实不是你能不能背出答案,而是你有没有意识到'\0'是真实存在于内存中的一个字节,sizeof会把它的位置也算进数组体积,而strlen见到它就立刻收工。

2.4 实际场景:fgets 读完的字符串怎么安全地取长度

字符串长度计算最常见的工程场景,就是读取一行用户输入后判断内容。比如网上流传的“字符串逆序”练习题,很多同学在 PTA 和翁恺老师的练习里都遇到过,正确思路就是先用strlen拿到输入长度,再做首尾交换。

用fgets读入字符串时,缓冲区里通常会带一个换行符,需要先处理掉:

#include <stdio.h> #include <string.h> int main(void) { char s[101]; if (fgets(s, sizeof(s), stdin) == NULL) { return 1; } size_t len = strlen(s); if (len > 0 && s[len - 1] == '\n') { s[len - 1] = '\0'; len--; } // 字符串逆序 for (size_t i = 0; i < len / 2; i++) { char tmp = s[i]; s[i] = s[len - 1 - i]; s[len - 1 - i] = tmp; } printf("%s\n", s); return 0; }

注意这里我用sizeof(s)作为fgets的最大读取长度参数,这恰好是sizeof在工程中最经典的正向应用:在数组定义作用域里,用sizeof(s)得到缓冲区真实容量,防止越界写。但因为数组传参给函数后会退化为指针,所以如果你把fgets封装到另一个函数里,就必须把容量作为独立参数传进去,绝不能在函数内部再用sizeof。

3. 进阶陷阱:表达式求值、二维数组、结构体对齐

3.1 经典送命题:sizeof(i++) 到底加不加

来看一道能把不少人打懵的题目:

int i = 0; printf("%zu %d\n", sizeof(i++), i);

输出是什么?答案是4 0。

很多人想都不想就答4 1,因为他们以为sizeof(i++)会执行i++,让i变成 1。但sizeof的运算发生在编译期,它只需要知道i++这个表达式的类型是int,就能算出结果是 4 个字节,根本不需要在运行时把这个表达式真正执行一遍。

因此i的值不会变,还是 0。编译器连生成i++的指令都省了,直接把4当常量写进程序。这个题目是验证“sizeof 是编译期运算符”的最强证据。

顺便提醒一句,C 语言标准里有一条例外:当sizeof作用于变长数组(VLA)时,因为数组长度要运行时才知道,sizeof确实会在运行时求值。但这不是入门笔试的重点,大多数题目不会涉及,你只需要知道有这么个例外存在即可,答题时默认按编译期处理。

3.2 二维数组的 sizeof 分解:一层一层剥开

二维数组的sizeof是笔试的难点,但只要你记住一条原则就不怕:sizeof里没有“退化”这回事,数组名是什么类型就是什么类型。

看例子:

int b[3][4];

整个数组b的类型是int[3][4],共 12 个 int 元素,64 位 Linux 下 int 是 4 字节,所以:

sizeof(b) // 3 * 4 * 4 = 48 sizeof(b[0]) // b[0] 是第一行,类型是 int[4],大小 16 sizeof(b[0][0]) // 单个元素 int,大小 4

再组合一下:

sizeof(b) / sizeof(b[0]) // 48 / 16 = 3,得到行数 sizeof(b[0]) / sizeof(b[0][0]) // 16 / 4 = 4,得到列数

这里面隐藏着一个高频考点:b[0]在绝大多数表达式里作为数组名会退化成int *,比如你写func(b[0])传进去的是首元素地址。但在sizeof里,b[0]依然保留第一行数组的类型int[4],所以sizeof(b[0])才能算出 16。你要是用sizeof(&b[0]),那又不一样了,&b[0]是数组指针,大小是 8(64 位),因为它是指针。分清“数组名本身用于 sizeof”和“对数组名取地址后的类型”,是二维数组题型的核心。

3.3 结构体字节对齐:为什么不是简单相加

sizeof作用在结构体上时,很多人以为把成员大小加起来就行,于是就有了下面的经典笔试题:

struct A { char c1; int x; char c2; };

直觉答案:1 + 4 + 1 = 6。实际在默认对齐规则下,输出通常是12。

原因是在这个结构体里,int x要求按 4 字节对齐,所以c1占完第 0 字节后,1、2、3 三个字节被编译器填充成空隙,x从第 4 字节开始放,占 4、5、6、7 字节,然后c2放在第 8 字节。整个结构体的大小还要对齐到成员中最大对齐数的整数倍,这里是 4 的倍数,所以尾部还要补到 12 字节。

如果把成员顺序调换:

struct B { char c1; char c2; int x; };

结果是 8:c1和c2各自占 1 字节,连续放完后,x从第 4 字节开始,整体大小 8。

笔试里这种变式考得非常多,因为它不仅考sizeof,还考你对内存对齐机制的掌握程度。我建议你计算结构体大小时分三步走:

  1. 找出对齐要求最大的成员,决定整体对齐边界;
  2. 按声明顺序给每个成员分配起始位置,注意是否要“对齐到该成员大小整数倍”;
  3. 成员放完后再把整个大小补到“最大对齐数整数倍”。

这个知识在嵌入式领域尤其重要,因为很多硬件工程师是在用结构体映射通信协议帧结构。偏移量一旦算错,接收方解出的字段就会错位。所以遇到“硬件工程师笔试题”里出现结构体大小计算,请务必用这套流程,而不是简单相加。

3.4 malloc 出来的缓冲区,千万别一上来就 strlen

再看一道跟内存管理相关的坑题:

char *p = (char *)malloc(20); printf("%zu\n", strlen(p));

这段代码属于未定义行为。malloc(20)只申请了一块 20 字节的未初始化内存,里面是什么没人知道。strlen(p)从这块内存的起始地址一路找'\0',可能在 3 个字节后碰到,也可能在 19 个字节后碰到,甚至可能直接撞出越界区域才碰到。结果完全不可预测,甚至可能因为越界访问触发崩溃。

正确做法是先给缓冲区内容做初始化,再调strlen:

char *p = (char *)malloc(20); if (p == NULL) { return 1; } p[0] = '\0'; // 先把它变成空字符串 strcpy(p, "hello"); size_t len = strlen(p); // 此时才安全 free(p);

顺便聊一个网上经常出现的写法:prt=(char*)malloc(10.2*1024*sizeof(char))这类代码。它的本意是申请大概 10.2 KB 的字符空间。但实际工程里我们不建议把容量写成一个带小数的浮点表达式,10.2 * 1024在 C 里会先按浮点数算出 10444.8,再转成整数做参数,中间可能发生截断,代码表达意图也不清晰。直接写成整数容量更安全:

char *prt = (char *)malloc(10 * 1024); // 10 KB,去掉 sizeof(char) 完全没问题 char *prt2 = (char *)malloc(10445); // 或者直接严格写成整数

sizeof(char)在 C 标准里恒等于 1,乘上去只是形式上的冗余,不是错误,但别被这类写法绕进去。另外在 C 语言里malloc返回的void *可以隐式转换为任意对象指针类型,不需要强转;但在 C++ 里必须强转。很多教材示例喜欢写(char *)malloc(...),这不算错,不过你最好知道原因,免得被问到时候支支吾吾。

4. 经典笔试题实战:答案和坑位一条条过

这一章我把网上流传比较广的sizeof/strlen笔试题整理成一组高频列表,每一题给出结论、解析和易错点。题目不算难,但非常典型。

4.1 高频题组:逐个拆解

题 1:

char s[] = "hello"; printf("%zu %zu\n", sizeof(s), strlen(s));

输出:6 5。s是数组,sizeof 把'\0'算进去;strlen 数到终止符前停下。

题 2:

char *p = "hello"; printf("%zu %zu\n", sizeof(p), strlen(p));

输出:8 5(64 位环境)。sizeof 算的是指针变量大小,strlen 算的是字符串内容长度。

题 3:

char s[20] = "hello"; printf("%zu %zu\n", sizeof(s), strlen(s));

输出:20 5。数组容量是 20,不管你实际放了多少内容;strlen 拿到的是有效字符数量。

题 4:

void foo(char s[]) { printf("%zu\n", sizeof(s)); } char str[100] = "hello"; foo(str);

输出:8(64 位环境)。数组形参退化为指针,sizeof 结果与实参数组容量无关。

题 5:

int a[10]; printf("%zu\n", sizeof(a) / sizeof(a[0]));

输出:10。这是sizeof最正统的求数组元素个数用法,只能用在数组定义作用域内。

题 6:

char s[] = {'h', 'e', 'l', 'l', 'o'}; printf("%zu %zu\n", sizeof(s), strlen(s));

输出:sizeof(s)是 5,strlen(s)是未定义行为。这里一定要瞪大眼睛:s是用字符列表初始化的数组,并没有自动补'\0'。strlen 会从第 5 字节继续向后读,直到碰到某个碰巧为 0 的内存字节,结果不可预测。这个题目是区分“懂原理”和“背答案”的试金石。

题 7:

int i = 0; printf("%zu %d\n", sizeof(i++), i);

输出:4 0。sizeof是编译期运算符,不执行副作用。

题 8:

struct A { char c1; int x; char c2; }; printf("%zu\n", sizeof(struct A));

输出:常见环境为12。按成员对齐规则分配并补齐,不能简单相加。

题 9:

int b[3][4]; printf("%zu %zu %zu\n", sizeof(b), sizeof(b[0]), sizeof(b[0][0]));

输出:48 16 4(64 位 Linux)。注意b[0]在 sizeof 里保持第一行数组类型。

4.2 笔试答题速查表

为了方便你考试前快速过一遍,我把常见场景整理成一张速查表:

代码场景sizeof 结果strlen 结果
char s[] = "hello"65
char s[20] = "hello"205
char *p = "hello"8(64 位指针)5
char s[] = {'a','b','c'}3未定义行为
char s[] = "\0hello"70
int a[10]40不可用
struct{char c; int x;}8 取决于对齐规则不可用

最后强调一句:表里的指针大小、int 大小、结构体对齐结果都与平台相关。考试时如果题目没有特别说明,一般默认按主流 64 位平台作答;如果题干写了 32 位环境,指针大小就要改成 4。很多人在答案里写“sizeof(p) = 8”却不说明平台,容易和面试官产生歧义。你答题时主动补一句“64 位下是 8”,反而显得基本功扎实。

5. 动手实测:用 VSCode + GCC 搭一个验证环境

5.1 环境准备与第一个测试程序

网上关于“vscode 配置 c 语言环境”的帖子很多,实际可以很简单。你需要两样东西:

  1. 一个 C 编译器,推荐 GCC。Windows 上可以装 MinGW-w64,macOS 上可以用clang(它是默认编译器,命令略有不同但兼容),Linux 上直接sudo apt install gcc即可。
  2. VSCode 的 C/C++ 扩展,由微软发布的那个ms-vscode.cpptools。它负责智能提示、语法高亮和调试。

简单到可以在终端直接编译运行,不一定非要折腾 IDE 配置。写完代码存成main.c,然后在终端执行:

gcc main.c -o main && ./main

如果只是想验证sizeof/strlen的各种输出,把测试代码写好,敲这一条命令就够了。VSCode 对于这类小程序的意义,主要是查看函数定义、类型信息比较方便,调试时还能用图形界面断点。

下面这个程序几乎覆盖了上面所有考点:

#include <stdio.h> #include <string.h> #include <stddef.h> struct Test { char c1; int x; char c2; }; void foo(char s[]) { printf("in foo: sizeof(s)=%zu\n", sizeof(s)); } int main(void) { char s1[] = "hello"; char *p1 = "hello"; char s2[20] = "hello"; char s3[] = {'h', 'e', 'l', 'l', 'o'}; char s4[] = "\0hello"; char s5[] = "a\tb\n"; int a[10]; int b[3][4]; int i = 0; printf("sizeof(s1)=%zu, strlen(s1)=%zu\n", sizeof(s1), strlen(s1)); printf("sizeof(p1)=%zu, strlen(p1)=%zu\n", sizeof(p1), strlen(p1)); printf("sizeof(s2)=%zu, strlen(s2)=%zu\n", sizeof(s2), strlen(s2)); printf("sizeof(s3)=%zu, strlen(s3)=%zu <-- 注意 s3 没有 '\\0'\n", sizeof(s3), strlen(s3)); printf("sizeof(s4)=%zu, strlen(s4)=%zu\n", sizeof(s4), strlen(s4)); printf("sizeof(s5)=%zu, strlen(s5)=%zu\n", sizeof(s5), strlen(s5)); printf("sizeof(a)=%zu, 元素个数=%zu\n", sizeof(a), sizeof(a) / sizeof(a[0])); printf("sizeof(b)=%zu, sizeof(b[0])=%zu, sizeof(b[0][0])=%zu\n", sizeof(b), sizeof(b[0]), sizeof(b[0][0])); printf("sizeof(i++)=%zu, i=%d\n", sizeof(i++), i); printf("struct Test size=%zu\n", sizeof(struct Test)); char buf[100] = "hello"; foo(buf); return 0; }

因为strlen(s3)是未定义行为,不同编译器可能给出不同结果,甚至可能崩溃。你运行后会发现它基本能返回一个看起来“正常”的数字,比如 6 或 7,那是因为所在内存区域恰好有零字节。千万别把这个结果当成标准答案,它只是运气好而已。

5.2 打印 size_t 的格式符踩坑

上面代码里我用的是%zu,这是 C99 标准专门为size_t提供的格式占位符。sizeof和strlen的返回值类型都是size_t,在 64 位系统上它是 8 字节无符号整数。

很多同学习惯写%d,在 64 位平台上编译可能会报警告,因为%d期望一个int,而size_t是unsigned long,这个不匹配属于未定义行为。轻则输出错误,重则栈上参数读取异常。如果你用的编译器比较老,不支持%zu,可以手动强转:

printf("%lu\n", (unsigned long)sizeof(s)); printf("%llu\n", (unsigned long long)sizeof(s));

推荐写%zu,既干净又不丢信息。考试如果出到打印题,默认环境通常支持,放心用。

5.3 调试技巧:用调试器看 sizeof 干扰结果

还有一种更直观的验证方法,直接进调试器看。VSCode 里配上调试器后,在printf那行打断点,鼠标悬停在sizeof(s1)上,调试插件可能会显示6。如果你把s1传进foo函数再中断,会看到形参s的类型已经被推理成指针。

命令行选手可以这样:

gcc -g main.c -o main gdb ./main break main print sizeof(s1)

用 GDB 打印sizeof(s1),输出$1 = 6。再下一行打印strlen(s1),输出$2 = 5。亲眼看到这些数字可比死背表格有说服力得多。

6. 面试官视角:这类题到底在考什么

6.1 结构化答题话术

面试时如果被问到“说下 sizeof 和 strlen 的区别”,我不建议你上来就背列表。比较讨巧的回答方式是分三层展开:

第一层说身份:sizeof是运算符、关键字,编译期求值,不需要头文件;strlen是函数,运行期执行,需要<string.h>。

第二层说语义:sizeof计算对象或类型占用的内存字节数,不在乎里面存的是什么;strlen计算以'\0'结尾的字符串中有效字符个数,碰不到终止符就永远不知道什么时候停。

第三层举例子:比如char s[] = "hello",sizeof(s)是 6,strlen(s)是 5;但换成char *p = "hello",sizeof(p)在 64 位环境下是 8,strlen(p)还是 5。这个例子能同时说明“数组和指针的区别”“sizeof 对数组名保留整体类型”“strlen 只关心指向内容”三个知识点。

这样回答逻辑清晰,面试官基本没法再追问到你卡壳。

6.2 常见误区快查

把容易错的认知整理成一个误区表,考前最后瞄一眼:

常见误区正确理解
sizeof 是函数,要加头文件sizeof 是关键字,不需要头文件
sizeof 返回字符串长度sizeof 返回内存占用字节数,与字符串长度无关
strlen 会计算数组全部内容strlen 只计算到'\0'前的内容,数组中没有'\0'就会越界
数组传入函数后还能用 sizeof 求大小数组形参退化为指针,sizeof 只能拿到指针大小
sizeof(i++) 会执行自增sizeof 在编译期求值,不执行表达式副作用
结构体大小等于成员大小之和要考虑内存对齐、填充字节、尾部补齐
结果在 32 位和 64 位平台完全一样指针大小、部分数据类型大小、结构体对齐结果会随平台变化

6.3 最后一个小技巧:先看类型,再看结束符

我个人在实际面试和辅导中积累的经验是,所有关于sizeof和strlen的题目,都可以用十个字概括解题步骤:“先看类型,再看结束符。”

看到sizeof,先问自己这个操作数是什么类型:是数组名、指针、结构体,还是普通变量?类型确定后,sizeof的本质就是返回这个类型的字节数。看到strlen,先问这个内存区域是不是真的以'\0'结尾:数组初始化方式决定了它是否隐藏着终止符,指针指向的字符串是否合法。只要这两个问题有答案,题目基本就不会错。

我当时学这个知识点时,也经历过“背了三天题,换个新题又错”的阶段。后来把所有情况写成一个printf全家桶程序,在本地跑了一遍,亲眼看到输出结果,才真正把这些知识点内化。所以在这里也建议你花一个晚上把上面清单敲一遍、跑一遍、故意猜错几回。踩过坑的印象,永远比死记硬背深刻得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 7:07:52

bert-base-chinese中文NLP模型加载与微调实战指南

简介&#xff1a;这份资源是针对中文场景优化的BERT预训练模型权重包&#xff0c;面向深度学习与自然语言处理领域的开发者、研究者和学生&#xff0c;可用来完成中文文本分类、情感分析、问答、翻译等任务&#xff0c;尤其适合需要离线加载大模型进行微调或验证算法效果的学习…

作者头像 李华
网站建设 2026/10/13 7:05:47

毛坯房装修的正确流程是什么?

现在温度越来越低&#xff0c;虽然不适合动工&#xff0c;可以趁着淡季活动多、优惠大、工程少&#xff0c;尽快定下装修公司、设计方案和需要定制的装修材料&#xff0c;不仅省钱&#xff0c;还不耽误工期。1&#xff09;装修的准备工作&#xff0c;2&#xff09;毛坯房装修的…

作者头像 李华
网站建设 2026/10/13 7:05:46

AI做PPT终于不丑了!开源gpt-image2-ppt-skills让你自动生成PPT

AI做PPT终于不丑了&#xff01;开源gpt-image2-ppt-skills让你自动生成PPT 大家好&#xff0c;我是星哥。 最近后台有不少朋友跟我吐槽&#xff1a;“星哥&#xff0c;现在市面上的 AI 做 PPT 工具&#xff0c;怎么做出来的东西都那么‘AI味’啊&#xff1f;” 说实话&#…

作者头像 李华
网站建设 2026/10/13 7:05:44

OpenSpec:轻量级AI工程规范管理框架

强烈推荐&#xff1a;AI编程巴士网站&#xff1a;稳定纯净的ClaudeCode套餐供应 (https://code.ai80.vip/home) 前言 在《SDD规范驱动开发&#xff1a;AI时代的软件工程新范式》一文中&#xff0c;我们详细介绍了SDD&#xff08;Spec-Driven Development&#xff0c;规范驱动…

作者头像 李华