sizeof与strlen()的用法与区别 |
您所在的位置:网站首页 › 计算sizeof表达式和strlen表达式的值 › sizeof与strlen()的用法与区别 |
sizeof
是在汇编里面就存在的一个指令,可以直接返回要判断的变量所占的内存大小(字节数),这是在编译器(编译阶段)就确定的。 返回值类型是size_t,该类型保证能容纳可以建立的最大对象的字节大小,在头文件 stddef.h 中定义。这是一个依赖编译系统的值,32位系统一般为: typedef unsigned int size_t; ,64位系统一般为: typedef unsigned long size_t; 。 sizeof的两种形式 sizeof(type_name); //sizeof(类型); sizeof object; //sizeof 对象; 对类型和对象求值 int i; sizeof(i); //ok sizeof i; //ok sizeof(int); //ok sizeof int; //errorsizeof计算对象的大小也是转换成对对象类型的计算,也就是说,同种类型的不同对象其sizeof值都是一致的。 对表达式求值编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。如: sizeof(2); //2的类型为int,所以等价于sizeof(int); sizeof(2 + 3.14); //3.14的类型为double,2也会被提升成double类型,所以等价于sizeof(double); 对函数调用求值sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用,我们来看一个完整的例子: char foo() { printf("foo()hasbeencalled.\n"); return 'a'; } int main() { size_tsz = sizeof(foo()); //foo()的返回值类型为char,所以sz = sizeof(char),foo()并不会被调用 printf("sizeof(foo()) = %d\n", sz); } 错误示例C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算sizeof值,即下面这些写法都是错误的: sizeof(foo); //error void foo2(){} sizeof(foo2()); //error struct S { unsigned int f1:1; unsigned int f2:5; unsigned int f3:12; }; sizeof(S.f1); //error sizeof的常量性sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用,如: char ary[sizeof(int) * 10]; //ok而C99标准规定sizeof也可以在运行时刻进行计算,如下面的程序在Dev-C++中可以正确执行: int n; n = 10; //n动态赋值 char ary[n]; //C99也支持数组的动态定义 printf("%d\n", sizeof(ary)); //ok.输出10 但在没有完全实现C99标准的编译器中就行不通了,上面的代码在VC6中就通不过编译。 所以我们最好还是认为sizeof是在编译期执行的,这样不会带来错误,让程序的可移植性强些。 sizeof之指针变量 vs. 数组变量sizeof()的变量如果是指针char *,则返回指针本身的大小;如果是数组char [],返回的是数组空间的大小。 指针变量在32位计算机中,一个指针变量的返回值通常是4(以字节为单位),在64位系统中指针变量的sizeof通常为8。 示例: char *pc = "abc"; int *pi; string *ps; char **ppc = &pc; void(*pf)(); //函数指针 sizeof(pc); //结果为4 sizeof(pi); //结果为4 sizeof(ps); //结果为4 sizeof(ppc); //结果为4 sizeof(pf); //结果为4指针变量的sizeof值与指针所指的对象没有任何关系,所有的指针变量所占内存大小相等。 数组变量 数组的sizeof值等于数组所占用的内存字节数,如: char a1[] = "abc"; int a2[3]; sizeof(a1); // 结果为4,字符末尾还存在一个'\0'结束符 sizeof(a2); // 结果为3 * 4 = 12(依赖于int的大小) 求数组长度(个数) int c1 = sizeof(a1) / sizeof(char); //总长度/单个元素的长度 char型 int c2 = sizeof(a2) / sizeof(a2[0]); //总长度/第一个元素的长度 int型 易错点!函数形参列表里的数组本质是指针!!! 注意:在C++里,参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小。如果想在函数内知道数组的大小, 必须增加一个形参,将长度传进去。 示例: void foo3(char a3[3]) { int c3=sizeof(a3); //c3 = ? } void foo4(char a4[]) { int c4=sizeof(a4); //c4 = ? }这里函数参数a3已不再是数组类型,而是蜕变成指针,相当于char* a3。试想:当我们调用函数foo3时,程序会在栈上分配一个大小为3的数组吗?不会!数组是“传址”的,调用者只需将实参的地址传递过去,所以a3自然为指针类型char*,c3的值也就为4。 结构体的sizeof待补充。。。 从栈看sizeof 其实理解 sizeof 只需要抓住一个要点:栈。 程序存储分布有三个区域:栈、静态和动态。能够从代码直接操作的对象,包括任何类型的变量、指针,都是在栈上的;动态和静态存储区是靠栈上的所有指针间接操作的。 sizeof 操作符,计算的是对象在栈上的投影体积,记住这点很多东西都很清楚了。 char const *static_string = "Hello"; //sizeof(static_string)是sizeof一个指针,所以在32bit system是4 char stack_string[] = "Hello"; //sizeof(stack_string)是sizeof一个数组,所以是6*sizeof(char) char*string = new char[6]; strncpy(string,"Hello",6"); //sizeof(string)是sizeof一个指针,所以还是4。 //和第一个不同的是,这个指针指向了动态存储区而不是静态存储区。 不管指针指向的内容在什么地方,sizeof 得到的都是指针的栈大小。 sizof与引用 C++ 中对引用的处理比较特殊。sizeof一个引用得到的结果是sizeof一个被引用的对象的大小。 示例: struct test { int a, b, c, d, e, f, g, h; }; int main() { test &r = new test; cout |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |