一.本质区别 ------------------------- One example
#define PATH_TMP '12345'
------------------------------------------------------------------------------------------------------------------------ 一、sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。 它并不是函数。 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(max) --若此时变量max定义为int max(); sizeof(char_v) --若此时char_v定义为char char_v[MAX]且MAX未知, sizeof(void) 以上都是不正确形式。 三、sizeof的结果(以下结果都是在Linux v2.6 gcc v4获取) sizeof操作符的结果类型是size_t 它在头文件中定义为: typedef unsigned int size_t; 该类型保证能容纳实现所建立的最大对象的字节大小. 1、ANSI C正式规定字符类型为1字节。 sizeof(char) = 1; sizeof(unsigned char) = 1; sizeof(signed char) = 1; 2、其他类型在ANSI C中没有具体规定,大小依赖于实现。 sizeof(int) = 4; sizeof(unsigned int) = 4; sizeof(short int) = 2; sizeof(unsigned short) = 2; sizeof(long int) = 4; sizeof(unsigned long) = 4; sizeof(float) = 4; sizeof(double) = 8; sizeof(long double) = 12; 3、当操作数是指针时,sizeof依赖于编译器。 Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。 一般Unix/Linux的指针字节数为4。 例如: char *p; //Linux中 sizeof(p) = 4; 4、当操作数具有数组类型时,其结果是数组的总字节数。 例如: char a[5]; int b[5]; sizeof(a) = 5; sizeof(b) = 20; 5、当操作数是具体的字符串或者数值时,会根据具体的类型进行相应转化。 例如: sizeof(8) = 4; //自动转化为int类型 sizeof(8.8) = 8; //自动转化为double类型,注意,不是float类型 sizeof('ab') = 3 //自动转化为数组类型, //长度是4,不是3,因为加上了最后的'\n'符 //有资料说,会自动转化为指针类型(Linux为4) //可能和操作系统与编译器有关系 6、当操作数是联合类型时,sizeof是其最大字节成员的字节数。 当操作数是结构类型时,sizeof是其成员类型的总字节数,包括补充字节在内。 还是让我们拿例子来说话: union u{ //对union来说 char c; double d; }u; sizeof(u) = max(sizeof(c),sizeof(d)) = sizeof(1,8) = 8; struct a{ //对struct来说 char b; double x; }a; 在Linux上: sizeof(a) = 12; 而一般sizeof(char) + sizeof(double) = 9; 这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。 但如果全对齐的话,sizeof(a) = 16, 这是因为b被放到偏移量为0的地址,占1个字节; 在存放x时,double类型长度为8,需要放到能被8整除的偏移量上,这时候需要补7个空字节, 达到8个,这时候偏移量为8,放上x后长度为16。 在此例中,所有的结构成员都要放在被4整除的地址(Linux的存放方式),这里补3个字节,所以为12。 7、当操作数是函数中的数组形参或函数类型的形参: sizeof给出其指针的大小,Linux中值为4。 四、sizeof与其他操作符的关系 sizeof的优先级为2级,比/、%等3级运算符优先级高。 它可以与其他操作符一起组成表达式: 例如: int i = 10; i * sizeof(int); 五、sizeof的主要用途 1、主要用途是与存储分配和I/O系统那样的例程进行通信。 例如: void *malloc(size_t size); size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream); 2、另一个的主要用途是计算数组中元素的个数。 例如: void *memset(void *s, int c, sizeof(s));
----------------------------------------------- sizeof和strlen的区别 例1:char ss[100]=”0123456789”; Sizeof(ss)结果为100,ss表示在内存中预分配的大小,100*1; Strlent(ss)结果为10,它的内部实现是用一个循环计算字符串的长度,直到”\0”为止。 例2:int ss[100]=”0123456789”; Sizeof(ss)结果为400,ss表示在内存中的大小,100*4; Strlen(ss)错误,strlen的参数只能是char*,且必须是以”\0”结尾的。 总结sizeof和strlen的区别 ⒈sizeof操作符的结果类型是size_t,它在头文件中的typedef为unsigned int 类型。该类型保证能容纳实现所建立的最大对象的字节大小。 ⒉sizeof是运算符,strlen是函数。 ⒊sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以”\0”结尾的。sizeof还可以用函数做参数,比如: short f(); printf(“%d\n”,sizeof(f())); 输出的结果是sizeof(short),即2。 ⒋数组做sizeof的参数不退化,传递给strlen就退化为指针。 ⒌大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量的长度。这就是sizeof(x)可以用来定义数组位数的原因。 char str[20]=”0123456789”; int a=strlen(satr); //a=10; int b=sizeof(str); //b=20; ⒍strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型占内存的大小。 ⒎sizeof后如果是类型必须加括号,如果是变量名可以不加括号。这是因为sizeof是个操作符而不是函数。 ⒏当使用一个结构类型或变量时,sizeof返回实际的大小。当使用一静态的空间数组时,sizeof返回全部数组的尺寸。Sizeof操作符不能返回被动态分配的数组或外部的数组的尺寸。 ⒐数组作为参数传给函数时传得是指针而不是数组,传递的是数组的首地址。在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小,如果想在函数内知道数组的大小需要在函数里面用memcpy将数组复制出来,长度由另一个形参传禁区。 ⒑计算结构变量的大小就必须讨论数据对其问题。 ⒒sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小数据的数据类型,如未知存储大小的数组类型,未知内容的结构或联合类型,void类型等。
Sizeof的使用场合 首先要明确sizeof不是函数,也不是一元运算符,它是个类似宏定义的特殊关键字,sizeof()。括号内的内容在编译过程中是不被编译的,而是被替代类型,如int a=8; sizeof(a)。在编译过程中,不管a的值是什么,知识被替换成类型sizeof(int),结果为4。如果sizeof(a=6)呢?也是一样地转换成a的类型,但是要注意,因为a=6是不被编译的,所以执行sizeof(a=6)后,a的值还是8,是不变的。 ① sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如: void *malloc(sizex_t size), size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream) ② 用它可以看看某种类型的对象在内存中所占的单元。例如: void * memset(void * s, int c, sizeof(s)) ③在动态分配一对象时,可以让系统知道要分配多少内存。 ④便于一些类型的扩充。在Windows中有很多结构类型就有一个专门的字段用来存放该类型的字节大小。 ⑤由于操作数的字节数在实现时可能出现变化,建议在涉及操作数字节大小时用sizeof代替常量计算。 ⑥如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。
结论: ① unsigned影响的知识最高位bit的意义(正/负),数据长度是不会被改变的,所以: sizeof(unsigned int) == sizeof(int); ② 自定义类型的sizeof取值等同于它的类型原形。如: typedef short WORD; sizeof(short) == sizeof(WORD); ③ 对函数使用sizeof,在编译阶段会被函数返回值的类型取代。如: int f1() {return 0;} cout<> ④ 只要是指针,大小就是4。如: cout<> ⑤数组的大小是各维数的乘积×数组元素的大小。 |
|