C/C++学习笔记9:sizeof总结

关于sizeof的总结在”size家族“这一章节中也提到了,但是笔者从学习的过程中来看,这是一个非常重要的知识点,那么笔者就单独拿出来再总结一下:sizeof到底有什么奇妙之处,用到的这么频繁呢?

首先我们要了解sizeof它的本质用处在什么地方?

sizeof的作用是:返回一个对象或者类型的长度。说白了就是计算长度的。

问题1:sizeof与strlen的区别是什么?

分析:在比较二者区别之前,首先来看看strlen的作用是什么?

strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值。

区别:

(1)sizeof操作符的结果类型是size_t,实际上就是unsigned int 类型,因为在头文件中有typedef unsigned int size_t

(2)sizeof是运算符,strlen是函数

(3)sizeof可以用类型做参数,strlen只能用char*做参数(可参考strlen的函数原型),且必须以”\0“结尾的,sizeof还可以用函数做参数。

----->strlen函数原型:extern unsigned int strlen(char *s),所以说strlen只能用char *做参数

e.g.1:char *ss = "0123456789"

sizeof(ss)结果是4,因为指针的长度就是4

sizeof(*ss),*ss指的是第一个字符,所以结果是1


e.g.2:char ss[]="0123456789"

sizeof(ss),ss是数组,计算到"\0"的位置,因此是11

sizeof(*ss),结果是1,*ss指的是第一个字符


e.g.3: char ss[100]="0123456789"

sizeof(ss)结果为100,因为在内存中预分配了大小

strlen(ss),结果为10,它内部的实现是用一个循环计算字符长度。直到”\0“over


e.g.4:int ss[100] = "0123456789"

sizeof(ss)的结果是400

strlen(ss)的结果是错误,因为strlen参数智能是char *


e.g.5

class X

{

int i;

int j;

char k;

};

X x;

cout <<sizeof(X)<<endl;

cout <<sizeof(x)<<endl;

结果都是12,理由是内存补齐。




(4)数组做sizeof的参数不退化,传递给strlen就退化为指针

(5)大部分编译程序在运行的时候就把sizeof计算过了,是类型或变量的长度。这就是sizeof(x)可以用来定义数组维数的原因,但是strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型所占内存的大小。

(6)sizeof后如果是类型必须加括号,如果是变量名可以不加括号。这是因为sizeof是操作符不是函数。

(7)当使用一个结构类型或者变量时,sizeof返回实际大小。当使用一静态的空间数组时,sizeof返回全部数组的尺寸。sizeof操作符不能返回被动态分配的数组或外部的数组的尺寸。

——>关于数组的长度计算问题:

e.g.2:char ss[]="0123456789"

sizeof(ss),ss是数组,计算到"\0"的位置,因此是11

sizeof(*ss),结果是1,*ss指的是第一个字符


(8)数组作为参数传给函数传的是指针而不是数组,传递的是数组的首地址

(9)计算结构变量的大小就必须讨论数据对齐的问题。

———>关于内存补齐的问题可以参考:http://blog.csdn.net/gzbaishabi/article/details/38520959

(10)sizeof操作符不能用于函数类型、不完全类型或位字段。


问题2:sizeof、strlen以及length()的区别。

上面已经说了sizeof、strlen的区别,那么length又有什么用呢?

length是计算针对字符串而言的,C语言的库函数中并没有,只是存在于C++的string类中。

length是数组变量的元素个数,是个数,每一个不一定刚好一个字节

具体的用法可参考:

#include <string.h>
#include <iostream>
using namespace std;
int fun(char num[])//传递过来是一个指针
{
	
	//int n=strlen(num);
	int n=sizeof(num);//数组作为参数传递过来的是指针,是首地址,所以此处应该是4
	printf("%d\n",n);//4
	char *p=num;
	int j=strlen(p);
	int g=strlen(num);
	printf("%d\n",j);//13
	printf("%d\n",g);//13
	
	
	if(13==n){
		if((*p==8)&&(*(p+1)==6))
			while(*p!='\0'){
				if(*p>='0'&&*p<='9')
					p++;
				else return 2;
				if(*p='0')
					return 0;}
				else return 3;
	}
	else return 1;
}

int main()
{
	char num[]="87139a3887671";//字符串长度为13
	//char num[13];
	//scanf("%s",num);
	//char num[13];
	//gets(num);
	int m=sizeof(num);
	int j=strlen(num);
	
	printf("%d\n",m);//14
	printf("%d\n",j);//13
	int k;
	k=fun(num);
	cout << k <<endl;
	return 0;
}


问题3:sizeof具体用在什么地方?

(1)sizeof的一个主要用途是:与存储分配和I/O系统那样的例程进行通信。

e.g.1:

void *malloc(size_t size) ;

size_t fread (void *ptr,size_t size,size_t nmemb,FILE *stream);

其实就是利用sizeof获取了长度,在把长度运用到对文件的操作上去。

(2)用它可以查看某种类型的对象在内存中所占的单元字节。

e.g.2:

void *meset(void *s,int c,sizeof(s))

说明:注意meset函数的意义。作用是在一段内存块中填充某个给定的值,它是对较大的结构体数组进行清零操作的一种最快方法。sizeof(s)获取了s的长度,并全部用c代替,同时返回给s。若把c全部改成了0,即可达到了清零的作用。

(3)在动态分配一对象的时,可以让系统知道要分配多少内存。

(4)便于一些类型的扩充。在windows中有很多结构类型就有一个专用的字段来存放类型的字节大小。

(5)由于操作室的字节数在实现时可能出现变化,建议在涉及操作数字节大小时用sizeof代替常量计算。
(6)如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值