先看看sizeof()

一、sizeof的概念

sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。其实可以简单的理解sizeof是征对"类型"的。

二、sizeof的使用方法

1、用于数据类型
sizeof使用形式:sizeof(type) 数据类型必须用括号括住。如sizeof(int)。

2、用于变量

sizeof使用形式:sizeof(var_name)或sizeof var_name

变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。

注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。

三、sizeof的结果

sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。

1、若操作数具有类型char、unsigned char或signed char,其结果等于1。因为 ANSI C正式规定字符类型为1字节。

2、int、unsigned int 、short int(short)、unsigned short 、long int(long) 、unsigned long 、float、double、long double类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。

3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。

4、当操作数具有数组类型时,其结果是数组的总字节数,特别要注意字符串数组,如:

Char str[]=“123456” sizeof(str)=7。

5、联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。

让我们看如下结构:

struct {char b; double x;} a;

在某些机器上sizeof(a)=16,而一般sizeof(char)+ sizeof(double)=9。

这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。

6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小

即:int func(char p[100])

{ sizeof(p) = 4; }

C/C++中不能传数组,只能传指针,所以任何数组都会隐式转成指针形式进行操作,所以"类型"还是指针。

7.sizeof是运算符 当编译器编译时 会自动运算这个变量的大小的 并使用它的大小代替sizeof的值如

int len = sizeof(int);编译时 编译器计算出int的大小 大小为4 所以把上面这句变成

int len = 4

四、sizeof与其他操作符的关系

sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。如i*sizeof(int);其中i为int类型变量。

五、sizeof的主要用途

1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:
void *malloc(size_t size),
size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。
2、sizeof的另一个的主要用途是计算数组中元素的个数。例如:
void *memset(void *s,int c,sizeof(s))。

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

如:int *p=(int *)malloc(sizeof(int)*10);

4.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。

5.如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。

六、建议

由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用ziseof来代替常量计算。

下面我们来看看strlen()

一、strlen是函数

strlen只能用char*做参数,且必须是以''/0''结尾的。Strlen将返回它的长度,不包括‘/0’。

二、由几个例子说开去。

第一个例子:
char* ss = "0123456789";
sizeof(ss) 结果 4 ===>ss是指向字符串常量的字符指针
sizeof(*ss) 结果 1 ===>*ss是第一个字符

char ss[] = "0123456789";
sizeof(ss) 结果 11 ===>ss是数组,计算到/0位置,因此是10+1
sizeof(*ss) 结果 1 ===>*ss是第一个字符

char ss[100] = "0123456789";
sizeof(ss) 结果是100 ===> ss表示在内存中的大小 100×1
strlen(ss) 结果是10 ===> strlen是个函数内部实现是用一个循环计算到/0为止之前

int ss[100] = "0123456789";
sizeof(ss) 结果 400 ===>ss表示再内存中的大小 100×4
strlen(ss) 错误 ===>strlen的参数只能是char* 且必须是以''/0''结尾的

char q[]="abc";
char p[]="a/n";
sizeof(q),sizeof(p),strlen(q),strlen(p);
结果是 4 3 3 2

第二个例子:
class X{
int i;
int j;
char k;
};

X x;
cout<<sizeof(X)<<endl; 结果 12 ===>内存补齐
cout<<sizeof(x)<<endl; 结果 12 同上
(详细可见另篇文章:由朗讯的一道笔试题想到的!)

第三个例子:

数组用作参数传递,见上面6

列出几个重要的区别:

1.sizeof是算符,strlen是函数。

2.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''/0''结尾的。

sizeof还可以用函数做参数,比如:
short f();
printf("%d/n", sizeof(f()));
输出的结果是sizeof(short),即2。

3.strlen计算的是字符串的长度,sizeof计算的是变量使用的内存大小,不受里面存储的内容改变

4.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。

5.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。

6.当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof归还全部数组的尺寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸 。

6.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:

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 的时候,通常是计算字符串数组的长度

好了看了上面的讲解和例题,我们来测试几个题:

1.不要上机测试,否则便没有什么意义。

如下程序的输出是什么?(在intel x86(32-bit) platform.)
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
int main( )
{
    char str[10];
    char *p;
memset(str,0x00,sizeof(str));
    p = (char *)malloc(100);
    printf("%d/n",sizeof(p));
    printf("%d/n",sizeof('p'));
    printf("%d/n",strlen(str));
    exit(0);
}

答:4/1/0, 如果不加memset(),第三行就会打出15(随机数),请问这是为什么?

memset函数是初始化分配的内存空间,使用0、0x00都是0即’/0',不同系统当分配一块内存时,这块内存中的内容是未知的,系统只是根据申请者的要求为其化一块内存并不管他原先的内容是什么(有的系统清零),所以你的是随即数15。

2.你能够正确的说出它们的sizeof和strlen的大小吗?

#include <stdio.h>
#include<stdlib.h>
#include<string.h>

int main( )

{

char *str1="absde";
char str2[]="absde";
char str3[8]={'a',};
char str4[8]={'a','b','s','e','f','g','h','j'};

printf("sizeof(str1)=%d/n",sizeof(str1));
printf("sizeof(str2)=%d/n",sizeof(str2));
printf("sizeof(str3)=%d/n",sizeof(str3));
printf("sizeof(str4)=%d/n",sizeof(str4));

printf("strlen(str1)=%d/n",strlen(str1));
printf("strlen(str2)=%d/n",strlen(str2));
printf("strlen(str3)=%d/n",strlen(str3));
printf("strlen(str4)=%d/n",strlen(str4));

exit(0);

}

答:sizeof是计算括号中变量的类型所占的储存空间(不考虑内容);strlen是计算变量值为起点的内存地址到第一个'/0'的距离,以字节为单位,字符串尾部为'/0',0=='/0'(不包括’/0’)。正确答案是:4、6、8、8;5、5、1、9;

3.这个例子可以说明一些问题:

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()在msdn中的定义:

sizeof Operator

sizeof expression

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t.

The expression is either an identifier or a type-cast expression (a type specifier enclosed in parentheses).(sizeof后面跟的表达式(expression)既可以是标志符,也可以是类型转换的表达式(类型的说明包含在))

When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment. When applied to a statically dimensioned array, sizeof returns the size of the entire array. The sizeof operator cannot return the size of dynamically allocated arrays or external arrays.

strlen

Get the length of a string.

Routine Required Header:

strlen <string.h>

size_t strlen( const char *string );

Parameter

string:Null-terminated string

Libraries

All versions of the C run-time libraries.

Return Value

Each of these functions returns the number of characters in string, excluding the terminal NULL. No return value is reserved to indicate an error.

Remarks

Each of these functions returns the number of characters in string, not including the terminating null character. wcslen is a wide-character version of strlen; the argument of

wcslen is a wide-character string. wcslen and strlen behave identically otherwise.

C语言-sizeof()与strlen()的区别【转】的更多相关文章

  1. C语言 - sizeof和strlen的区别

    sizeof和strlen的区别: 1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型. 该类型保证能容纳实现所建立的最大对象的字节大小. 2.s ...

  2. c语言sizeof与strlen的区别

    #include <stdio.h> #include <stdlib.h> #include <string.h> //strlen与sizeof的区别 //st ...

  3. sizeof和strlen的区别和联系总结

    link:http://blog.csdn.net/ghevinn/article/details/9974967    strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头 ...

  4. 我也介绍下sizeof与strlen的区别

    本节我也介绍下sizeof与strlen的区别,很简单,就几条: 1. sizeof是C++中的一个关键字,而strlen是C语言中的一个函数:2. sizeof求的是系统分配的内存总量,而strle ...

  5. sizeof()和 strlen()的区别 --- 个人笔记

    在学习C语言和linux的时候,遇到了一些常见问题.题目,有些很简单,有些容易出错,本人水平有限,未免会出错,今天有时间,就将以前做的笔记,一一拿出来,写写blog. sizeof()和 strlen ...

  6. sizeof和strlen的区别

    一.sizeof    sizeof(...)是运算符,而不是一个函数.    sizeof操作符的结果类型是size_t,在头文件中typedef为unsigned int,其值在编译时即计算好了, ...

  7. Sizeof与Strlen的区别与联系

    转自:http://www.cnblogs.com/carekee/articles/1630789.html 一.sizeof    sizeof(...)是运算符,在头文件中typedef为uns ...

  8. Sizeof与Strlen的区别与联系(转)

    Sizeof与Strlen的区别与联系 一.sizeof     sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型 ...

  9. C++-sizeof和strlen的区别

    一.sizeof    sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型.对象.函数等.    它的功能是:获得保 ...

  10. 【转】Sizeof与Strlen的区别与联系

    原文地址:http://www.cnblogs.com/carekee/articles/1630789.html 1.sizeof  sizeof(...)是运算符,在头文件中typedef为uns ...

随机推荐

  1. 制作Win7(x86)PE ISO文件

    WinPE3.1     —Win7 x86 PE V3.1: waik_supplement_zh-cn.isoDVD: cn_windows_7_professional_with_sp1_x86 ...

  2. android项目中如何加载已有so库 <转>

    1,在项目根目录下建立文件夹libs/armeabi文件夹 2,将so库放入 libs/armeabi文件夹 注意事项: 1,如果采用静态注册的方式请注意C文件中严格按照命名规则 Java_packa ...

  3. Atom 编辑器插件:amWiki 轻文库

    amWiki 是一款基于 Javascript 脚本语言.依赖 Atom 编辑器.使用 Markdown 标记语法的轻量级开源 wiki 文库系统. amWiki 致力于让大家可以更简单.更便捷的建设 ...

  4. 关于java.lang.String理解中的一些难点

    最近温习java的一些基础知识,发现以往对String对象认识上的一些不足.特汇总如下,主要是帮助记忆,如能对其他朋友有些启发,不胜欣喜. String在JVM中内存驻留问题 JVM的常量区(Cons ...

  5. MWC飞控增加声纳定高的方法

    MWC飞控增加声纳定高的方法 2015.12.17 更新:经过2个周末的上机测试,该算法效果很好,在低空超声锁高之后离地高度非常稳定,现在已经成功应用在低空航拍上了. 现状 MWC开源飞控已经很有点年 ...

  6. 慕课网-安卓工程师初养成-4-1 Java条件语句之 if

    来源:http://www.imooc.com/code/1353 生活中,我们经常需要先做判断,然后才决定是否要做某件事情.例如,如果考试成绩大于 90 分,则奖励一个 IPHONE 5S .对于这 ...

  7. Windows 7的100M隐藏分区

    1.Windows 7的100MB的隐藏分区是Windows 7的活动分区,类似于Linux的/boot. 这其实有点类似Linux的做法,Linux在安装过程中可以专门分出一个100MB左右的分区作 ...

  8. ORA-01810: 格式代码出现两次

    今天在修改SQL语句的时候遇到这个小问题,提示的还是比较明显的,当然解决之道我是从百度上摘取的! 错误语句段:AND V.UPLOAD_DATE <=TO_DATE ('2013-11-11 2 ...

  9. html中button的type属性

         接触web开发不久,今天遇到了一个问题,点击button按钮,浏览器没有反应,尝试了自己可以想到的所有办法,还是无果.只得请教他人,才发现是button的type属性搞得怪,原来:     ...

  10. cacti快速安装

    一.cacti概述 1. cacti是用php语言实现的一个软件,它的主要功能是用snmp服务获取数据,然后用rrdtool储存和更新数据,当用户需要查看数据的时候用rrdtool生成图表呈现给用户. ...