1.在C语言中char型占一个字节的存储空间,一个字节是8个bit。如果这8个bit按无符号整数,取值范围是0~255,如果按有符号整数,取值范围是-128~127。C语言规定了signed和unsigned两个关键字,unsigned char型表示无符号数,signed char型表示有符号数。
因此这里的主要问题是,如果使用不带signed或unsigned关键字的char型究竟是无符号数还是有符号数呢?C标准规定这是Implementation Defined,也就是说由编译器自己定义实现。编译器可以定义char型是无符号的,也可以定义char型是有符号的,比如x86平台的gcc定义char型是有符号的。当然其它平台的其它编译器也可以定义为无符号型。
因此:
char tmp;
if(tmp<0){...}
else{...}
这样的代码,如果从将char定义为有符号的平台移植到将char定义为无符号类型的平台,tmp<0是永远无法成立的。所以,会出现移植问题。
2.
class C
{
public:
C();
void fn1();
void fn2();
protected:
int a;
int b;
}
C c;
sizeof(c)计算的应该是其中的数据成员的大小。函数属于代码,存放在代码区而不是数据区,所有对象都共享一份代码,但拥有自己独自的数据。对于有继承和多态关系的C++类对象中的数据成员分布,可以参考书中我书中C++一章,里面有专门论述,也可以参考<effective c++>和<more effective c++>。也就是说,拥有多态关系的C++类对象,还拥有一份或多份指向虚函数表的指针或者虚基类的指针。因此计算对象的大小的时候,还必须加上指针占的空间。
下面的例子,你可以在VC6里面编译运行,实验一下每个类对象的大小,你就明白了。
class A
{
public:
A();
void fn1();
void fn2();
protected:
int a;
int b;
};
A::A()
{
a = 0;
b = 0;
}
class B:public A
{
public:
B();
void fn3();
void fn4();
private:
int c;
};
B::B():A()
{
c = 0;
}
//C,D引入了虚函数,因此计算对象大小时,需要算上指向vtable的指针大小
class C
{
public:
C();
virtual void fn1();
void fn2();
protected:
int a;
int b;
};
C::C()
{
a = 0;
b = 0;
}
void C::fn1()
{
return;
}
class D:public C
{
public:
D();
virtual void fn1();
void fn3();
void fn4();
private:
int c;
};
void D::fn1()
{
printf("hello\n");
return;
}
D::D():C()
{
c = 0;
}
int main(int argc, char* argv[])
{
C c;
D d;
printf("Hello World!:sizeof(A):%d, sizeof(B):%d, sizeof(c):%d, sizeof(d):%d\n",
sizeof(A), sizeof(B),sizeof(c), sizeof(d));
return 0;
}