本文共 2101 字,大约阅读时间需要 7 分钟。
sizeof
和strlen
是C语言中的两个核心工具,虽然都与内存有关,但使用场景、作用不同,理解它们的区别对于提升代码编写能力至关重要。本文将深入探讨这两个工具的功能、用法以及适用场景。
sizeof
是一个编译时的关键字,其作用是获取内存中某一块内存区域所占的字节数。它的使用对象包括:
类型:通过typeof
表达式,sizeof
可以返回数据类型所占的字节数。例如:
sizeof(int); // 返回int类型的大小
注意:括号的使用:sizeof
后面如果是类型,必须使用括号,如sizeof(char)
, 否则解析器会将其误解为 sizeof以后的标识符。
变量/数组:sizeof
也可以用来获取变量或数组的内存大小。例如:
int arr[100];sizeof(arr); // 返回整个数组的内存大小,即100个int的总量sizeof(*arr); // 返回一个int的大小arr[50] = 100;sizeof(arr); // 返回的结果仍为100,因为排量没有变化
需要注意的是,数组的传递方式是按值传递,排量是编译时确定的,动态分配的内存大小sizeof
无法测量。
指针:sizeof(ptr)
返回指针所在的内存单元大小。对于32位系统,返回4字节;64位系统,返回8字节。例如:
char *ptr = "hello";sizeof(ptr); // 返回4(如32位系统)
但如果用于获取指针指向的数据大小,需要使用*ptr
,例如:
char *ptr = "hello";sizeof(*ptr); // 返回1(字符类型的大小)
函数的返回类型:sizeof
可以用于测量函数返回值的类型大小,前提是返回值类型不能是void
。例如:
int func_return值返回了int类型;sizeof(func_return值) // 返回4(32位系统)或8(64位系统)
需要注意的是,函数返回值的实际大小在运行时可能根据 optimizations而不同,经常会被编译器优化。
strlen
是一个库函数,运行时使用,功能是计算字符串的实际长度(从非零结尾字符'\0'
的位置开始到'\0'
的距离的总数)。它所在的头文件是<string.h>
,函数原型为:
unsigned int strlen(char *s);
有几个重要的特点:
'\0'
:strlen
的作用是返回从字符串起点到第一个'\0'
之前的字符数。需要注意的是,如果字符串没有'\0'
终止符,strlen
将漫无止境地遍历内存,直到碰到一个无法访问的区域,导致程序崩溃。strlen
函数的实现通常很简单,一般是逐字符递增加指针直到遇到0位。但编译器和解析器通常对字符串常量的处理非常高效。strlen
的参数必须是char *
类型。传递其他类型的指针会导致编译错误。strlen
的作用域依赖:strlen
无法用于测量内存的大小,仅仅测量字符串存储的数据量,但需要注意字符串是否附带了'\0'
终止符。
数组与字符串的区别:
char string[] = ".hello";char *s = "hello\0";
使用strlen
测量数组存储的数值,还是只能看终止符是否到位。
不同的使用场景:
sizeof
,而不是strlen
。strlen
。'\0'
终止符(如动态内存分配),则无法使用strlen
测长度。例1
char str[20] = "0123456789";int a = strlen(str); // a = 10int b = sizeof(str); // b = 20
strlen
测字符串的实际长度,而sizeof
测内存分配的大小,包括导致'\0'
的位置所占的字节数。例2
char *ss = "0123456789";int i = sizeof(ss); // i = 4int j = sizeof(*ss); // j = 1int k = strlen(ss); // k = 10
ss
是位于100号段的指针,sizeof(ss)
测的是指针本身占用的内存大小,而每个字符的大小可以用*ss
测得。例3
char buffer[] = "Hello";int m = strlen(buffer); // m = 5int n = sizeof(buffer); // n = 6
buffer
中的所有字节都已包含0
,使得parseInt
较为直观。char s[] = "abc";int n = sizeof(s); // n = 4?!或者3?
实际上不管内容是多少,s
是数组,其大小是4字节(如果是字典序)。strlen(s)
返回3,但除了终止符之外
转载地址:http://okxxz.baihongyu.com/