C/C++基础::sizeof() 与 sizeof(string)
2016-02-25 16:05
525 查看
sizeof(string 对象) ≠ string 对象的
也即:
sizeof():对象在内存中所占空间的真实大小
strlen():遇第一个
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() 是否是一个函数?答案是否定的,
在编译阶段已被翻译为:
这里有一个著名的陷阱:
输出不是预期的4,3而是4,1,可见
所以,结论就是:
不可在
结论:对函数使用sizeof,在编译阶段会被函数返回值的类型取代,同样,虽然调用的动作,函数并不会被真正执行;
.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)=6 std::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\0 std::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,因此被认为是int cout<<sizeof(f2())<<endl; // f2()返回值为double,因此被认为是double cout<<sizeof(f3())<<endl; // 错误!无法对void类型使用sizeof cout<<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++11]_[初级]_[shared_ptr的使用场景]
- [C++11]_[初级]_[shared_ptr的简单使用]
- C++ 拆分字符串
- C++设计模式之工厂模式
- 面试题六 C/C++面试秘笈 之约瑟夫问题的解答--程序员面试题
- C++的运算符重载
- c++模板元编程
- 面试题五 C/C++面试秘笈 之链表的正向排序--程序员面试题
- 请问在VC++2010中如何连接用Access2010创建好的accdb数据库?
- [c++]string中删除相同字符
- C语言 链表的使用(链表的增删查改,链表逆转,链表排序)
- C++ template —— tuple(十三)
- 面试题四 C/C++面试秘笈 之判断链表是否存在环形链表问题-程序员面试题
- c++服务端用webservices【gsoap】做服务端与java后台对接信息的测试工具
- C++虚继承的概念
- 面试题三 C/C++面试秘笈 查找单链表的中间元素 --程序员面试题
- c语言入门之项目4.3——利用for循环求1-1/2*2+1/2*2*2...-1/2*2*2*2到2的8次方
- winodws平台C++共享内存实现
- C++基础知识易错点总结(2)
- C语言知识整理(二)