您的位置:首页 > 编程语言 > C语言/C++

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

2014-08-12 21:51 375 查看
关于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)计算结构变量的大小就必须讨论数据对齐的问题。

———>关于内存补齐的问题可以参考:/article/9222385.html

(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给出其指针的大小。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: