</pre><pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
/*
strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描
,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值。
sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。
strlen与sizeof的区别:
strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个'\0',如果你只定义没有给它赋初值,这个结果是不定的,它会从aa首地址一直找下去,直到遇到'\0'停止。
char aa[10];cout<<strlen(aa)<<endl; //结果是不定的
char aa[10]={'\0'}; cout<<strlen(aa)<<endl; //结果为0
char aa[10]="jun"; cout<<strlen(aa)<<endl; //结果为3
而sizeof()返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen是函数。
sizeof(aa) 返回10
int a[10]; sizeof(a) 返回40
1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。
该类型保证能容纳实现所建立的最大对象的字节大小。
2.sizeof是操作符(关键字),strlen是函数。
3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。
sizeof还可以用函数做参数,比如:
short f();
printf("%d\n", sizeof(f()));
输出的结果是sizeof(short),即2。
4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
5.大部分编译程序 在编译的时候就把sizeof计算过了是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因
char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小,
当适用一静态地空间数组, sizeof 归还全部数组的尺寸。
sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,
如:
fun(char [8])
fun(char [])
都等价于 fun(char *)
在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小
如果想在函数内知道数组的大小, 需要这样做:
进入函数后用memcpy拷贝出来,长度由另一个形参传进去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}
我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度
看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚:
char str[20]="0123456789";
int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。
int b=sizeof(str); //而b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。
上面是对静态数组处理的结果,如果是对指针,结果就不一样了
char* ss = "0123456789";
sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针,sizeof 获得的是一个指针的之所占的空间,应该是
长整型的,所以是4
sizeof(*ss) 结果 1 ===》*ss是第一个字符 其实就是获得了字符串的第一位'0' 所占的内存空间,是char类
型的,占了 1 位
strlen(ss)= 10 >>>> 如果要获得这个字符串的长度,则一定要使用 strlen
sizeof返回对象所占用的字节大小. //正确
strlen返回字符个数. //正确
在使用sizeof时,有一个很特别的情况,就是数组名到指针蜕变,
char Array[3] = {'0'};
sizeof(Array) == 3;
char *p = Array;
sizeof(p) == 1;//sizeof(p)结果为4
在传递一个数组名到一个函数中时,它会完全退化为一个指针
例子 :
char* ss = “0123456789”;
sizeof(ss);结果为4,ss为一个指向char型的指针
sizeof(*ss);结果为1,*ss是第一个字符
char ss[ ] = "0123456789";
sizeof(ss);结果为11,ss是数组,计算到"\0"位置,因此是10+1=11
sizeof(*ss);结果为1,*ss是第一个字符
char ss[100] = "0123456789";
sizeof(ss);结果为100,ss表示在内存中预分配的大小,100*1
strlen(ss);结果为10,它的内部实现是用一个循环计算字符串的长度,直到“\0”,为止(不包括\0)
int ss[100] = "0123456789";
sizeof(ss);结果为400,ss表示在内存中的大小,100*4
strlen(ss);错误,strlen的参数只能是char *,且必须是以\0结尾
下面给出 strlen和strcpy函数的实现原型
*/
int mystrlen(const char *s)
{
//定义一个字符串变量 用于保存形参传入的字符串
const char *sc;
/*将传入的参数复制给sc 下面开始操作sc字符串
1.因为字符串的结束符为‘\0’,所以以此判断字符串的结尾,设置了for循环的结束条件
2.当满足循环条件时 ,令指针地址自加 这样指针就指向了字符串中的下一个字符
3.当指针指向字符串结尾时,即‘\0’时,循环条件不满足,循环终止,跳出for循环
*/
for (sc = s; *sc != '\0'; ++sc);
//由于此时指针变量s存储的是字符串中首字符的地址 故用 sc - c 即得到此字符串的字符长度
return sc - s;
}
/*
分析一个函数先从函数的参数和返回值入手
参数列表:共有连个形参 ,全是字符串类型
返回值: 返回值类型字符串类型
函数功能: 传入两个字符串,并将src字符串的内容复制到dest字符串中 ,并且最后返回dest字符串内容
*/
char *mystrcpy(char *dest, const char *src)
{
//定义一个字符串变量,并存储dest字符串的起始地址
char *tmp = dest;
/*
while判断语句中条件过于复杂,将(*dest++ = *src++)拆解如下:
因为是后置自加,所以先取值,在自加
*dest = *src;(关于此语句的个人理解:指针运算符* 如果在赋值运算符的左边表示取地址,如果在赋值运算符的右面表示取值。所以就是将src指向的地址内的值赋给dest指向的地址)
dest = dest + 1;
src = src + 1;
*/
while ((*dest++ = *src++) != '\0');
//返回指针变量储存的地址 ,即:dest字符串的地址
return tmp;
}
int main(){
char* str = "abcd";
int count = 0;
char* dest = new char[strlen(str) + 1];
mystrcpy(dest,str);
count = mystrlen(dest);
printf("dest字符串为:%s \n",dest);
printf("字符串的长度:%d \n", count);
}
strlen与strcpy函数实现的浅谈及辨析sizeof运算符与strlen函数的区别
最新推荐文章于 2022-10-23 19:54:44 发布