sizeof(string)的问题(很经典)

今天看到一个代码,刚开始没有看明白,代码如下:

<span style="font-size:14px;">#include<iostream>
#include<string>
using namespace std;
void main()
{
string a="www.ok2002.com";
string b=" study C++ program";
a.append(b,0,sizeof(b)+2);
cout<<a<<" "<<sizeof(b)<<endl;
}</span>

结果显示:sizeof(b)=16

当string=“C++"时,sizeof(b)=16

所以最好这样写:

a.append(b,0,b.size());

原因分析:

关于sizeof(string),那本面试宝典书上写着sizeof(string)=4;当时很纳闷,难道分配4个字节大小的内存给string吗?查阅了相关资料得出结论:string的实现在各库中可能有所不同,但是在同一库中相同一点是,无论你的string里放多长的字符串,它的sizeof()都是固定的,字符串所占的空间是从堆中动态分配的,与sizeof()无关。

sizeof(string)=4可能是最典型的实现之一,不过也有sizeof()为12、32字节的库实现。 但是VC6.0测试后sizeof(string)=16.还是跟编译器有关

bool数据类型与int类型一样,占用内存的字节数都是与编译系统相关的,它在不同的编译系统占用的字节数有所不同,在VC++6.0中,它占用的字节数是1个字节

sizeof bool=1;

什么是sizeof

首先看一下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可以,所以sizeof不是函数。网上有人说sizeof是一元操作符,但是我并不这么认为,因为sizeof更像一个特殊的宏,它是在编译阶段求值的。举个例子:

cout<<sizeof(int)<<endl; // 32位机上int长度为4

cout<<sizeof(1==2)<<endl; // == 操作符返回bool类型,相当于 cout<<sizeof(bool)<<endl;

在编译阶段已经被翻译为:

cout<<4<<endl;

cout<<1<<endl;

这里有个陷阱,看下面的程序:

int a = 0;

cout<<sizeof(a=3)<<endl;

cout<<a<<endl;

输出为什么是4,0而不是期望中的4,3???就在于sizeof在编译阶段处理的特性。由于sizeof不能被编译成机器码,所以sizeof作用范围内,也就是()里面的内容也不能被编译,而是被替换成类型。=操作符返回左操作数的类型,所以a=3相当于int,而代码也被替换为:

int a = 0;

cout<<4<<endl;

cout<<a<<endl;

所以,sizeof是不可能支持链式表达式的,这也是和一元操作符不一样的地方。

结论:不要把sizeof当成函数,也不要看作一元操作符,把他当成一个特殊的编译预处理。

时间: 2024-08-26 02:03:29

sizeof(string)的问题(很经典)的相关文章

从sizeof(string)到引用计数的漫游

前言: 说是漫游,其实就是扯,一点一点的扯. 话说之前参加华为的德州扑克比赛,我用C++解析消息的时候碰到一个小问题,就是定长收消息的时候出错,在Linux下调了很久很久,终于发现,sizeof(string)不是string的size,而是string类型的大小.当然,用string.size()就可以轻松解决了,而作品也在昨晚提交了,不过,交的是python的.我的C++程序,送给了两支队伍,让他们去参赛,可惜,白眼狼. 既然有闲暇时间了,那么就要深究一下,sizeof(string)是个什

C++中sizeof(string)

上代码: // test_max.cpp : 定义控制台应用程序的入口点. #include "stdafx.h" #include <iostream> #include <string> using namespace std; int main(void) { string strArr1[]={"Cjc ","is ","a "}; string *pStrArr1=new string[2];

很经典的mysql的幻读解释

http://blog.sina.com.cn/s/blog_499740cb0100ugs7.html 上述链接很经典的解释了mysql的mvcc为什么是部分解决了幻读的问题. 同时我需要理解的是,在业务逻辑中,事务是可以分散在业务代码里面的,并不是说一条语句写出.比如,我们启动了一个事务,start transaction.先获取数据库中的数据,然后在业务中判断该条件是否符合自己的业务逻辑,如果是的话,那么就可以插入一部分数据.但是这个时候可能也有别的数据插入进来了,产生了冲突,导致当前的数

很经典的C++知识

Overload和Override的区别,Overload方法是否可以改变返回值类型? 答:Overload是重载的意思,Override是覆盖的意思,也就是重写. (1)重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同),重载发生在同一个类中. (2)重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给

hdu3534,个人认为很经典的树形dp

题目大意为,求一个树的直径(最长路),以及直径的数量 朴素的dp只能找出某点开始的最长路径,但这个最长路径却不一定是树的直径,本弱先开始就想简单了,一直wa 直到我看了某位大牛的题解... 按照那位大牛的思路,我们来考虑直径的构成: 情况1:由某叶子节点出发产生的最长路径直接构成 情况2:由某有多个儿子的节点出发产生的两条长路径组成,这其中,又可以分为两条长路径长度相等与否两种情况 所以 在dp的时候,我们需要记录每个节点出发产生的最长路径和次长路径,以及他们的数量,数量的统计也是非常麻烦 详细

【转】博弈问题及SG函数(真的很经典)

博弈问题若你想仔细学习博弈论,我强烈推荐加利福尼亚大学的Thomas S. Ferguson教授精心撰写并免费提供的这份教材,它使我受益太多.(如果你的英文水平不足以阅读它,我只能说,恐怕你还没到需要看“博弈论”的时候.) Nim游戏是博弈论中最经典的模型(之一?),它又有着十分简单的规则和无比优美的结论,由这个游戏开始了解博弈论恐怕是最合适不过了. Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatorial Games”

Asp.net中GridView使用详解(很全,很经典)

http://blog.csdn.net/hello_world_wusu/article/details/4052844 Asp.net中GridView使用详解 效果图参考:http://hi.baidu.com/hello%5Fworld%5Fws/album/asp%2Enet中以gv开头的图片 l         GridView无代码分页排序 l         GridView选中,编辑,取消,删除 l         GridView正反双向排序 l         GridVi

ZOJ2599:Graduated Lexicographical Ordering(很经典的数位DP)

Consider integer numbers from 1 to n. Let us call the sum of digits of an integer number its weight. Denote the weight of the number x as w(x). Now let us order the numbers using so called graduated lexicographical ordering, or shorter grlex ordering

sizeof string

? 1 2 3 4 5 char a[] = "hello"; string s = "hello"; cout<<sizeof(a)<<endl; cout<<sizeof(s)<<endl; cout<<sizeof(s.c_str())<<endl; 输出为 ? 1 2 3 6 32 4 最后一个c_str返回的是char*,所有指针的长度都为4.sizeof(s)为什么为32? 查了一下