strlen 是一个函数,它用来计算指定字符串 str 的长度,但不包括结束字符(即 null 字符),也正因为 strlen 是一个函数,所以需要进行一次函数调用。其原型如下面的代码所示:
size_t strlen(char const* str);
sizeof是运算符,可以以类型、函数、做参数 。strlen是函数,只能以char*(字符串)做参数。而且,要想得到的结果正确必须包含 ‘\0’(通过strlen的实现得知)。
#include "iostream"
using namespace std;
int main()
{
char str[20] = "hello world";
char *s = (char *)malloc(20);
strcpy(s, str);
cout << "strlen(str)======" << strlen(str) << endl;
cout << "sizeof(str)======" << sizeof(str) << endl;
cout << "strlen(s)======" << strlen(s) << endl;
cout << "sizeof(s)======" << sizeof(s) << endl;
free(s);
system("pause");
return EXIT_SUCCESS;
}
输出:
strlen(str)======11
sizeof(str)======20
strlen(s)======11
sizeof(s)======4
其他
char* s = "0123456789";
sizeof(s); //结果 4 ===》s是指向字符串常量的字符指针
sizeof(*s); //结果 1 ===》*s是第一个字符
strlen(s); //结果 10 ===》有10个字符,strlen是个函数内部实现是用一个循环计算到\0为止之前
strlen(*s); //结果 10 ===》错误
char s[] = "0123456789";
sizeof(s); //结果 11 ===》s是数组,计算到\0位置,因此是10+1
strlen(s); //结果 10 ===》有10个字符,strlen是个函数内部实现是用一个循环计算到\0为止之前
sizeof(*s); //结果 1 ===》*s是第一个字符
char s[100] = "0123456789";
sizeof(s); //结果是100 ===》s表示在内存中的大小 100×1
strlen(s); //结果是10 ===》strlen是个函数内部实现是用一个循环计算到\0为止之前
int s[100] = "0123456789";
sizeof(s); //结果 400 ===》s表示再内存中的大小 100×4
strlen(s); //错误 ===》strlen的参数只能是char* 且必须是以‘\0‘结尾的
char q[]="abc";
char p[]="a\n";
sizeof(q),sizeof(p),strlen(q),strlen(p);\\结果是 4 3 3 2
char p[] = {'a','b','c','d','e','f','g','h'};
char q[] = {'a','b','c','d,'\0','e','f','g'};
sizeof(p); //结果是8 ===》p表示在内存中的大小 8×1
strlen(p); //为一个随机值,结果与编译器有关,不同编译器结果一般不同
sizeof(q); //结果是8 ===》p表示在内存中的大小 8×1
strlen(q); //结果为4 ===》存在'\0',遇到'\0'计算停止。
结构体
struct Stu
{
int i;
int j;
char k;
};
Stu stu;
printf("%d\n",sizeof(Stu)); //结果 12 ===》内存补齐
printf("%d\n",sizeof(stu));; //结果 12 ===》内存补齐
这个例子是结构体的内存对齐所导致的,计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C语言在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便,如有不理解的可以看看另外关于一篇内存对齐的博客。