C/C++基础::sizeof() 与 sizeof(string)
来源:互联网 发布:c语言产生0 9的随机数 编辑:程序博客网 时间:2024/05/01 13:53
sizeof(string 对象) ≠ string 对象的
.size()
成员函数(.size()与.length()
不作区别,返回 string 的字符个数)
string
的实现在各库中可能有所不同,但在同一个库中相同的一点是,无论string
里存放了多长的字符串,它们的sizeof()
都是固定的(举个不太恰当的例子,就好比,int a;
无论int变量a
取多大的值,sizeof(a)
总为4),字符串所占的空间是从堆中动态分配的,与sizeof()
无关;
sizeof(string) == 4
可能是最为典型的实现之一,不过也有sizeof()
为 12,32 字节的库,同时也与编译器有关,在windows 32位操作系统下, 使用vs2013编译器测试,sizeof(string) == 28
。
char buf[] = "hello"; // buf真正指向的是"hello\0",\0也独占一个字节std::cout << sizeof(buf) << std::endl; // 实际所占的内存空间的大小,5+1(\0)=6std::cout << strlen(buf) << std::endl; // strlen 的头文件在 <string.h> // <string> 也有其实现 // 该函数遇 `\0` 结束std::string str = buf; // 支持参数为char*的单参构造std::cout << buf.size() << std::endl; // == 5,不将`\0`计算在内 // 等价于 buf.length()std::cout << sizeof(std::string) << std::endl; // == 28,库及编译器的缘故std::cout << sizeof(buf) << std::endl; // 与字符串自身的长度无关
sizeof()、strlen() 与 \0 的关系
char buf[] = "he\0llo";std::cout << sizeof(buf) << std::endl; // 实际所占内存空间的大小,与`\0`的位置无关, // 但会在字符串的末尾自动加上`\0`,也即 he\0llo\0std::cout << strlen(buf) << std::endl; // 遇第一个\0结束统计
也即:
sizeof():对象在内存中所占空间的真实大小
strlen():遇第一个
\0
结束大小的统计,也即不视\0
后的字符为当前字符串的内容,事实上,也确实如此;
std::cout << buf << std::endl; // he // 字符串的赋值以`\0`为结束
sizeof 何人?
msdn 给出如下的定义:
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.
return 让我们联想,sizeof() 是否是一个函数?答案是否定的,sizeof(object)
可以执行,sizeof object
也是可以执行的(但仅限于变量或者对象,类型不支持该操作,也即sizeof int
,就会报错,加()
是永远正确的操作),显然不满足于C语言对函数的要求。有人说 sizeof 是一元操作符,事实也并非如此,sizeof 更像是一个特殊的宏,在编译阶段求值;
cout << sizeof (int) << endl; // 32位机,int 占4个字节cout << sizeof (1==2) << endl; // sizeof(bool)
在编译阶段已被翻译为:
cout << 4 << endl;cout << 1 << endl;
这里有一个著名的陷阱:
int a = 1;cout << sizeof(a = 3) << endl;cout << a << endl;
输出不是预期的4,3而是4,1,可见 a
的初始值并未被改变,也即a=3
并未被真正执行。原因正在于,sizeof()
的编译阶段处理的特性了。由于sizeof
不能被翻译成机器码,所以sizeof
的作用范围内,也就是()
里面的表达式(expression)不能被编译,而是被替换为类型,赋值操作符(=)返回左操作数的类型,所以 a=3在sizeof()看来就相当于int
,而代码也被替换为:
int a = 1;cout << 4 << std::endl;cout << a << std::endl;
所以,结论就是:
不可在
sizeof
作用于一个表达式(sizeof(++a)),在sizeof()看来,该表达式最后等效于一个类型,表达式不会被编译,更不会被执行;
sizeof 操作函数类型
int f1(){return 0;};double f2(){return 0.0;}void f3(){}cout<<sizeof(f1())<<endl; // f1()返回值为int,因此被认为是intcout<<sizeof(f2())<<endl; // f2()返回值为double,因此被认为是doublecout<<sizeof(f3())<<endl; // 错误!无法对void类型使用sizeofcout<<sizeof(f1)<<endl; // 错误!无法对函数指针使用sizeof cout<<sizeof*f2<<endl; // *f2,和f2()等价, //因为可以看作object,所以括号不是必要的。被认为是double
结论:对函数使用sizeof,在编译阶段会被函数返回值的类型取代,同样,虽然调用的动作,函数并不会被真正执行;
int foo(){ std::cout << "foo()" << std::endl;}int main(int, char**){ std::cout << sizeof(foo()) << std::endl; // 只输出为 4 // "foo()":不会被输出 return 0;}
References
[1] sizeof和sizeof(string)的问题
- C/C++基础::sizeof() 与 sizeof(string)
- C++--memset与sizeof
- C sizeof() 与 strlen()
- C sizeof 与 strlen()
- C语言sizeof(struct)与sizeof(union)
- C语言基础之sizeof
- sizeof.c
- C SIZEOF
- c++-sizeof
- c sizeof
- 【C++】sizeof
- C sizeof
- c sizeof
- C 语言--sizeof与typedef
- C/C++基础之 sizeof 与 strlen的讨论
- C++string str="abc";sizeof(str)
- C/C++:sizeof数组与指针
- 【C/C++】:sizeof详解
- Java发送电子邮件
- List实体集合更改任意Model中某一个字段的值,其他Model值也一起变了,引用类型和值类型的问题
- maven web项目的几种部署方式和常见的出错方式的解决
- [C++11]_[初级]_[shared_ptr的使用场景]
- CodeForces 626 A. Robot Sequence(水~)
- C/C++基础::sizeof() 与 sizeof(string)
- 文件合成器
- LeetCode 30 - Substring with Concatenation of All Words
- iOS initWithFrame:frame] 与 [UIButton buttonWithType] 对比
- 第三方框架
- 空悲切
- Android 三种跨界面的通讯方式
- css滚动条样式制定 jscrollpane
- android中用户头像设置的一点心得——关于bitmap被回收的问题