strlen与strcpy函数实现的浅谈及辨析sizeof运算符与strlen函数的区别

</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);
	
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值