深入理解 C/C++ 结构体 <7>:Struct 中的函数和函数指针 By Long Luo
在系列之三 大话结构体之三:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白… ,我们在文章的结尾留了一个悬念:
我们了解到C语言规范是struct
里面是不能有函数体的,但是在应用中假如struct
中没有函数的话,我们会遇到很多问题,第一数据往往是依附于函数来进行操作的;其二是我们需要用C来实现面向对象的思想。
比如下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct FuncInside
{
int mA;
void func()
{
printf("Hello, function inside!\n");
}
};
void main(void)
{
struct FuncInside f;
f.mA = 99;
f.func();
getchar();
}
编译会提示:1
1>e:\learn\vs\struct\struct\funcpointer.c(7) : error C2032: “func”: 函数不能是 struct“FuncInside” 的成员
那么这个问题应该如何解决呢?
一刹那,一句话在脑海中闪现,“指针是C语言的精华。”
啊哈,灵机一动!
深入理解 C/C++ 结构体 <6>:struct中0元素数组的意义在哪里? By Long Luo
上一回 大话结构体之六:无即是有,没有成员变量的Struct(结构体) ,我们在文章的结尾留了一个悬念:
—为什么0元素数组在class
和struct
结构体之外定义就是错误的,而在class
和struct
中定义就是Okay的,那么结构体中的0元素数组意义何在?
打个通俗的比喻,比如一个部门,有部门经理、PM、以及数量众多的苦逼程序猿们,某天部门接到一个项目,于是乎,拉出一个PM及数量未知的程序猿们,开工了:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct Department
{
int Manager;
int PM;
int ProgrammerNo[0];
};
int main(void)
{
Department *pt = NULL;
int Num = 5;
pt = (Department *)malloc(sizeof(Department) + sizeof(int) * Num);
pt->ProgrammerNo[0] = 006;
pt->ProgrammerNo[1] = 99;
getchar();
return 0;
}
做一个项目,程序猿的数量是变化的,因此我们也就知道
struct
中0元素数组意义就是可以作数量未知的扩展,所以也称为flexible arrays。
通过系列之五和之六,我们了解了0元素数组的意义。在下一篇中我们将试图揭开struct
最复杂和最难的部分:Struct中的函数和函数指针。
不要走开,后面更精彩!
- Updated by Long Luo at 2016-6-11 04:42:01 @Shenzhen, China.
深入理解 C/C++ 结构体 <5>:无即是有,没有成员变量的Struct(结构体) By Long Luo
在上一篇 大话结构体之五:以空间换时间,Struct(结构体)中的成员对齐之道(下) 中,我们学习了struct
的内存对齐的前世今生。
在开始本篇之前,想问大家一个问题:
---0是什么?
---呵呵,就是没有呗!
---那好,这5块钱拿去,就当抵我上次向你借的500块钱。
---什么?这哪和哪啊!这不一样
---可是你自己说的, 0就是“没有”。
---我说不清,反正不行,你必须还我500.
0是什么? 起什么作用呢? 为什么500 ≠ 5?
这节我们来讨论0的作用。
例如,500块钱,它后面0起到了什么作用呢?
500 的0,表示十和个位“没有”。虽说“没有”,但这个0却不能省略。因为如果省略了0,一件500块的衣服,你只给5块,小心遭到暴打。
那原因是什么呢?
在按位计数法中,数位具有很重要的意义。即使十位的数“没有”,也不能不写数字。这时就轮到0出场了,即0
的作用就是占位。换言之,0占着一个位置以保证数位高于它的数字不会产生错位。
正因为有了表示“没有”的0,数值才能正确地表现出来。可以说在按位计数法中0是不可或缺的。
打住,这和我们讲的struct
有什么关系?
当然有关系了,请问下面这段代码输出的是什么呢?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using namespace std;
struct NoMember
{
};
int main(void)
{
cout<<"The size of the struct NoMem is:"<<endl;
cout<<sizeof(NoMember)<<endl;
getchar();
return 0;
}
—是0呢? —还是1?2?3?
想必大部分人还是说不出来的,那我们先看看输出结果:
深入理解 C/C++ 结构体 <4>:以空间换时间,结构体中的成员对齐之道 By Long Luo
在开始今天的文章之前,请先看下面一道面试题:
问题: 阅读下面一段代码并回答题目之后的问题:1
2
3
4
5
struct ALIGN
{
int mA;
int mB;
};
请问在 32 位系统下 sizeof(ALIGN)
的结果是多少?
当然这道题目是难不到广大程序员同学们滴!
在 32 位机器上 int 类型占 4 个字节,Struct ALIGN 里面有 2 个 int 型变量,那么总共就是 8 个字节喽!
Bingo!在这个例子中,sizeof(ALIGN)
的结果的确是 8 。
下面,我们把代码修改一下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct ALIGN
{
int mA;
int mB;
};
struct ALIGN1
{
int mA;
short mB;
};
int main()
{
cout<<sizeof(short)<<endl;
cout<<sizeof(ALIGN1)<<endl;
getchar();
return 0;
}
请问输出是多少?
深入理解 C/C++ 结构体 <3>:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白... By Long Luo
之前一篇 深入理解 C/C++ 结构体 <2>:Structure 的声明、定义、初始化 ,我们已经了解了C++中Struct的定义方法和C中有点不一样,而且增加了一种新的类型—Class。从C++的名字我们就可以知道,C++是从C进化而来,“++”就是在C的基础上加了一些东西:面向对象的东西。
虽然C++作为一种面向对象语言,要区别于面向过程的C语言,但是在设计时,一个很重要的原则是C++必须向前兼容C,必须是C的超集。这样一来就可以带来好多好处:
第一个嘛,首先呢,C++就可以站在C这个巨人的肩膀上,大量过去用C编写的程序可以不加修改地在C++环境下使用; 第二,把很多C程序员忽悠进C++这个大坑里,为C++之崛起而加班,上了贼船可就由不得你了XD …….
也正是因为这个原因,C++中保留了Struct结构类型,并使得Struct的功能更强大,不仅仅是简单继承C的结构体,而且扩充了Struct,使得它也具有类的特点,那么在C++中,Class和Struct到底有什么区别呢?
Talk is cheap, show me the Code!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using namespace std;
struct S1
{
char mA;
int mB;
};
class C2
{
char mA;
int mB;
};
int main(void)
{
S1 a;
C2 b;
cout<<sizeof(a)<<&a<<endl;
cout<<sizeof(b)<<&b<<endl;
getchar();
return 0;
}
上面这段代码非常简单,分别定义了一个 Struct 类型和 Class 类型,并输出其大小和地址,我们先看看输出结果:
从结果我们可以看出,没啥区别啊!
且慢,再看下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using namespace std;
struct S1
{
char mA;
int mB;
};
class C1
{
char mA;
int mB;
};
struct S2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
class C2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
int main(void)
{
S1 a;
C1 b;
S2 c;
C2 d;
cout<<sizeof(S1)<<"\t"<<&a<<endl;
cout<<sizeof(C1)<<"\t"<<&b<<endl;
c.foo();
d.foo();
getchar();
return 0;
}
编译,结果报错了,如下所示:
0%
By Long Luo
在系列之三 大话结构体之三:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白… ,我们在文章的结尾留了一个悬念:
我们了解到C语言规范是struct
里面是不能有函数体的,但是在应用中假如struct
中没有函数的话,我们会遇到很多问题,第一数据往往是依附于函数来进行操作的;其二是我们需要用C来实现面向对象的思想。
比如下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct FuncInside
{
int mA;
void func()
{
printf("Hello, function inside!\n");
}
};
void main(void)
{
struct FuncInside f;
f.mA = 99;
f.func();
getchar();
}
编译会提示:1
1>e:\learn\vs\struct\struct\funcpointer.c(7) : error C2032: “func”: 函数不能是 struct“FuncInside” 的成员
那么这个问题应该如何解决呢?
一刹那,一句话在脑海中闪现,“指针是C语言的精华。”
啊哈,灵机一动!
深入理解 C/C++ 结构体 <6>:struct中0元素数组的意义在哪里? By Long Luo
上一回 大话结构体之六:无即是有,没有成员变量的Struct(结构体) ,我们在文章的结尾留了一个悬念:
—为什么0元素数组在class
和struct
结构体之外定义就是错误的,而在class
和struct
中定义就是Okay的,那么结构体中的0元素数组意义何在?
打个通俗的比喻,比如一个部门,有部门经理、PM、以及数量众多的苦逼程序猿们,某天部门接到一个项目,于是乎,拉出一个PM及数量未知的程序猿们,开工了:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct Department
{
int Manager;
int PM;
int ProgrammerNo[0];
};
int main(void)
{
Department *pt = NULL;
int Num = 5;
pt = (Department *)malloc(sizeof(Department) + sizeof(int) * Num);
pt->ProgrammerNo[0] = 006;
pt->ProgrammerNo[1] = 99;
getchar();
return 0;
}
做一个项目,程序猿的数量是变化的,因此我们也就知道
struct
中0元素数组意义就是可以作数量未知的扩展,所以也称为flexible arrays。
通过系列之五和之六,我们了解了0元素数组的意义。在下一篇中我们将试图揭开struct
最复杂和最难的部分:Struct中的函数和函数指针。
不要走开,后面更精彩!
- Updated by Long Luo at 2016-6-11 04:42:01 @Shenzhen, China.
深入理解 C/C++ 结构体 <5>:无即是有,没有成员变量的Struct(结构体) By Long Luo
在上一篇 大话结构体之五:以空间换时间,Struct(结构体)中的成员对齐之道(下) 中,我们学习了struct
的内存对齐的前世今生。
在开始本篇之前,想问大家一个问题:
---0是什么?
---呵呵,就是没有呗!
---那好,这5块钱拿去,就当抵我上次向你借的500块钱。
---什么?这哪和哪啊!这不一样
---可是你自己说的, 0就是“没有”。
---我说不清,反正不行,你必须还我500.
0是什么? 起什么作用呢? 为什么500 ≠ 5?
这节我们来讨论0的作用。
例如,500块钱,它后面0起到了什么作用呢?
500 的0,表示十和个位“没有”。虽说“没有”,但这个0却不能省略。因为如果省略了0,一件500块的衣服,你只给5块,小心遭到暴打。
那原因是什么呢?
在按位计数法中,数位具有很重要的意义。即使十位的数“没有”,也不能不写数字。这时就轮到0出场了,即0
的作用就是占位。换言之,0占着一个位置以保证数位高于它的数字不会产生错位。
正因为有了表示“没有”的0,数值才能正确地表现出来。可以说在按位计数法中0是不可或缺的。
打住,这和我们讲的struct
有什么关系?
当然有关系了,请问下面这段代码输出的是什么呢?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using namespace std;
struct NoMember
{
};
int main(void)
{
cout<<"The size of the struct NoMem is:"<<endl;
cout<<sizeof(NoMember)<<endl;
getchar();
return 0;
}
—是0呢? —还是1?2?3?
想必大部分人还是说不出来的,那我们先看看输出结果:
深入理解 C/C++ 结构体 <4>:以空间换时间,结构体中的成员对齐之道 By Long Luo
在开始今天的文章之前,请先看下面一道面试题:
问题: 阅读下面一段代码并回答题目之后的问题:1
2
3
4
5
struct ALIGN
{
int mA;
int mB;
};
请问在 32 位系统下 sizeof(ALIGN)
的结果是多少?
当然这道题目是难不到广大程序员同学们滴!
在 32 位机器上 int 类型占 4 个字节,Struct ALIGN 里面有 2 个 int 型变量,那么总共就是 8 个字节喽!
Bingo!在这个例子中,sizeof(ALIGN)
的结果的确是 8 。
下面,我们把代码修改一下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct ALIGN
{
int mA;
int mB;
};
struct ALIGN1
{
int mA;
short mB;
};
int main()
{
cout<<sizeof(short)<<endl;
cout<<sizeof(ALIGN1)<<endl;
getchar();
return 0;
}
请问输出是多少?
深入理解 C/C++ 结构体 <3>:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白... By Long Luo
之前一篇 深入理解 C/C++ 结构体 <2>:Structure 的声明、定义、初始化 ,我们已经了解了C++中Struct的定义方法和C中有点不一样,而且增加了一种新的类型—Class。从C++的名字我们就可以知道,C++是从C进化而来,“++”就是在C的基础上加了一些东西:面向对象的东西。
虽然C++作为一种面向对象语言,要区别于面向过程的C语言,但是在设计时,一个很重要的原则是C++必须向前兼容C,必须是C的超集。这样一来就可以带来好多好处:
第一个嘛,首先呢,C++就可以站在C这个巨人的肩膀上,大量过去用C编写的程序可以不加修改地在C++环境下使用; 第二,把很多C程序员忽悠进C++这个大坑里,为C++之崛起而加班,上了贼船可就由不得你了XD …….
也正是因为这个原因,C++中保留了Struct结构类型,并使得Struct的功能更强大,不仅仅是简单继承C的结构体,而且扩充了Struct,使得它也具有类的特点,那么在C++中,Class和Struct到底有什么区别呢?
Talk is cheap, show me the Code!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using namespace std;
struct S1
{
char mA;
int mB;
};
class C2
{
char mA;
int mB;
};
int main(void)
{
S1 a;
C2 b;
cout<<sizeof(a)<<&a<<endl;
cout<<sizeof(b)<<&b<<endl;
getchar();
return 0;
}
上面这段代码非常简单,分别定义了一个 Struct 类型和 Class 类型,并输出其大小和地址,我们先看看输出结果:
从结果我们可以看出,没啥区别啊!
且慢,再看下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using namespace std;
struct S1
{
char mA;
int mB;
};
class C1
{
char mA;
int mB;
};
struct S2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
class C2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
int main(void)
{
S1 a;
C1 b;
S2 c;
C2 d;
cout<<sizeof(S1)<<"\t"<<&a<<endl;
cout<<sizeof(C1)<<"\t"<<&b<<endl;
c.foo();
d.foo();
getchar();
return 0;
}
编译,结果报错了,如下所示:
0%
By Long Luo
上一回 大话结构体之六:无即是有,没有成员变量的Struct(结构体) ,我们在文章的结尾留了一个悬念:
—为什么0元素数组在class
和struct
结构体之外定义就是错误的,而在class
和struct
中定义就是Okay的,那么结构体中的0元素数组意义何在?
打个通俗的比喻,比如一个部门,有部门经理、PM、以及数量众多的苦逼程序猿们,某天部门接到一个项目,于是乎,拉出一个PM及数量未知的程序猿们,开工了:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct Department
{
int Manager;
int PM;
int ProgrammerNo[0];
};
int main(void)
{
Department *pt = NULL;
int Num = 5;
pt = (Department *)malloc(sizeof(Department) + sizeof(int) * Num);
pt->ProgrammerNo[0] = 006;
pt->ProgrammerNo[1] = 99;
getchar();
return 0;
}
做一个项目,程序猿的数量是变化的,因此我们也就知道
struct
中0元素数组意义就是可以作数量未知的扩展,所以也称为flexible arrays。
通过系列之五和之六,我们了解了0元素数组的意义。在下一篇中我们将试图揭开struct
最复杂和最难的部分:Struct中的函数和函数指针。
不要走开,后面更精彩!
- Updated by Long Luo at 2016-6-11 04:42:01 @Shenzhen, China.
深入理解 C/C++ 结构体 <5>:无即是有,没有成员变量的Struct(结构体) By Long Luo
在上一篇 大话结构体之五:以空间换时间,Struct(结构体)中的成员对齐之道(下) 中,我们学习了struct
的内存对齐的前世今生。
在开始本篇之前,想问大家一个问题:
---0是什么?
---呵呵,就是没有呗!
---那好,这5块钱拿去,就当抵我上次向你借的500块钱。
---什么?这哪和哪啊!这不一样
---可是你自己说的, 0就是“没有”。
---我说不清,反正不行,你必须还我500.
0是什么? 起什么作用呢? 为什么500 ≠ 5?
这节我们来讨论0的作用。
例如,500块钱,它后面0起到了什么作用呢?
500 的0,表示十和个位“没有”。虽说“没有”,但这个0却不能省略。因为如果省略了0,一件500块的衣服,你只给5块,小心遭到暴打。
那原因是什么呢?
在按位计数法中,数位具有很重要的意义。即使十位的数“没有”,也不能不写数字。这时就轮到0出场了,即0
的作用就是占位。换言之,0占着一个位置以保证数位高于它的数字不会产生错位。
正因为有了表示“没有”的0,数值才能正确地表现出来。可以说在按位计数法中0是不可或缺的。
打住,这和我们讲的struct
有什么关系?
当然有关系了,请问下面这段代码输出的是什么呢?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using namespace std;
struct NoMember
{
};
int main(void)
{
cout<<"The size of the struct NoMem is:"<<endl;
cout<<sizeof(NoMember)<<endl;
getchar();
return 0;
}
—是0呢? —还是1?2?3?
想必大部分人还是说不出来的,那我们先看看输出结果:
深入理解 C/C++ 结构体 <4>:以空间换时间,结构体中的成员对齐之道 By Long Luo
在开始今天的文章之前,请先看下面一道面试题:
问题: 阅读下面一段代码并回答题目之后的问题:1
2
3
4
5
struct ALIGN
{
int mA;
int mB;
};
请问在 32 位系统下 sizeof(ALIGN)
的结果是多少?
当然这道题目是难不到广大程序员同学们滴!
在 32 位机器上 int 类型占 4 个字节,Struct ALIGN 里面有 2 个 int 型变量,那么总共就是 8 个字节喽!
Bingo!在这个例子中,sizeof(ALIGN)
的结果的确是 8 。
下面,我们把代码修改一下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct ALIGN
{
int mA;
int mB;
};
struct ALIGN1
{
int mA;
short mB;
};
int main()
{
cout<<sizeof(short)<<endl;
cout<<sizeof(ALIGN1)<<endl;
getchar();
return 0;
}
请问输出是多少?
深入理解 C/C++ 结构体 <3>:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白... By Long Luo
之前一篇 深入理解 C/C++ 结构体 <2>:Structure 的声明、定义、初始化 ,我们已经了解了C++中Struct的定义方法和C中有点不一样,而且增加了一种新的类型—Class。从C++的名字我们就可以知道,C++是从C进化而来,“++”就是在C的基础上加了一些东西:面向对象的东西。
虽然C++作为一种面向对象语言,要区别于面向过程的C语言,但是在设计时,一个很重要的原则是C++必须向前兼容C,必须是C的超集。这样一来就可以带来好多好处:
第一个嘛,首先呢,C++就可以站在C这个巨人的肩膀上,大量过去用C编写的程序可以不加修改地在C++环境下使用; 第二,把很多C程序员忽悠进C++这个大坑里,为C++之崛起而加班,上了贼船可就由不得你了XD …….
也正是因为这个原因,C++中保留了Struct结构类型,并使得Struct的功能更强大,不仅仅是简单继承C的结构体,而且扩充了Struct,使得它也具有类的特点,那么在C++中,Class和Struct到底有什么区别呢?
Talk is cheap, show me the Code!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using namespace std;
struct S1
{
char mA;
int mB;
};
class C2
{
char mA;
int mB;
};
int main(void)
{
S1 a;
C2 b;
cout<<sizeof(a)<<&a<<endl;
cout<<sizeof(b)<<&b<<endl;
getchar();
return 0;
}
上面这段代码非常简单,分别定义了一个 Struct 类型和 Class 类型,并输出其大小和地址,我们先看看输出结果:
从结果我们可以看出,没啥区别啊!
且慢,再看下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using namespace std;
struct S1
{
char mA;
int mB;
};
class C1
{
char mA;
int mB;
};
struct S2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
class C2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
int main(void)
{
S1 a;
C1 b;
S2 c;
C2 d;
cout<<sizeof(S1)<<"\t"<<&a<<endl;
cout<<sizeof(C1)<<"\t"<<&b<<endl;
c.foo();
d.foo();
getchar();
return 0;
}
编译,结果报错了,如下所示:
0%
By Long Luo
在上一篇 大话结构体之五:以空间换时间,Struct(结构体)中的成员对齐之道(下) 中,我们学习了struct
的内存对齐的前世今生。
在开始本篇之前,想问大家一个问题:
---0是什么?
---呵呵,就是没有呗!
---那好,这5块钱拿去,就当抵我上次向你借的500块钱。
---什么?这哪和哪啊!这不一样
---可是你自己说的, 0就是“没有”。
---我说不清,反正不行,你必须还我500.
0是什么? 起什么作用呢? 为什么500 ≠ 5?
这节我们来讨论0的作用。
例如,500块钱,它后面0起到了什么作用呢?
500 的0,表示十和个位“没有”。虽说“没有”,但这个0却不能省略。因为如果省略了0,一件500块的衣服,你只给5块,小心遭到暴打。
那原因是什么呢?
在按位计数法中,数位具有很重要的意义。即使十位的数“没有”,也不能不写数字。这时就轮到0出场了,即0
的作用就是占位。换言之,0占着一个位置以保证数位高于它的数字不会产生错位。
正因为有了表示“没有”的0,数值才能正确地表现出来。可以说在按位计数法中0是不可或缺的。
打住,这和我们讲的struct
有什么关系?
当然有关系了,请问下面这段代码输出的是什么呢?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using namespace std;
struct NoMember
{
};
int main(void)
{
cout<<"The size of the struct NoMem is:"<<endl;
cout<<sizeof(NoMember)<<endl;
getchar();
return 0;
}
—是0呢? —还是1?2?3?
想必大部分人还是说不出来的,那我们先看看输出结果:
深入理解 C/C++ 结构体 <4>:以空间换时间,结构体中的成员对齐之道 By Long Luo
在开始今天的文章之前,请先看下面一道面试题:
问题: 阅读下面一段代码并回答题目之后的问题:1
2
3
4
5
struct ALIGN
{
int mA;
int mB;
};
请问在 32 位系统下 sizeof(ALIGN)
的结果是多少?
当然这道题目是难不到广大程序员同学们滴!
在 32 位机器上 int 类型占 4 个字节,Struct ALIGN 里面有 2 个 int 型变量,那么总共就是 8 个字节喽!
Bingo!在这个例子中,sizeof(ALIGN)
的结果的确是 8 。
下面,我们把代码修改一下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct ALIGN
{
int mA;
int mB;
};
struct ALIGN1
{
int mA;
short mB;
};
int main()
{
cout<<sizeof(short)<<endl;
cout<<sizeof(ALIGN1)<<endl;
getchar();
return 0;
}
请问输出是多少?
深入理解 C/C++ 结构体 <3>:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白... By Long Luo
之前一篇 深入理解 C/C++ 结构体 <2>:Structure 的声明、定义、初始化 ,我们已经了解了C++中Struct的定义方法和C中有点不一样,而且增加了一种新的类型—Class。从C++的名字我们就可以知道,C++是从C进化而来,“++”就是在C的基础上加了一些东西:面向对象的东西。
虽然C++作为一种面向对象语言,要区别于面向过程的C语言,但是在设计时,一个很重要的原则是C++必须向前兼容C,必须是C的超集。这样一来就可以带来好多好处:
第一个嘛,首先呢,C++就可以站在C这个巨人的肩膀上,大量过去用C编写的程序可以不加修改地在C++环境下使用; 第二,把很多C程序员忽悠进C++这个大坑里,为C++之崛起而加班,上了贼船可就由不得你了XD …….
也正是因为这个原因,C++中保留了Struct结构类型,并使得Struct的功能更强大,不仅仅是简单继承C的结构体,而且扩充了Struct,使得它也具有类的特点,那么在C++中,Class和Struct到底有什么区别呢?
Talk is cheap, show me the Code!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using namespace std;
struct S1
{
char mA;
int mB;
};
class C2
{
char mA;
int mB;
};
int main(void)
{
S1 a;
C2 b;
cout<<sizeof(a)<<&a<<endl;
cout<<sizeof(b)<<&b<<endl;
getchar();
return 0;
}
上面这段代码非常简单,分别定义了一个 Struct 类型和 Class 类型,并输出其大小和地址,我们先看看输出结果:
从结果我们可以看出,没啥区别啊!
且慢,再看下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using namespace std;
struct S1
{
char mA;
int mB;
};
class C1
{
char mA;
int mB;
};
struct S2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
class C2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
int main(void)
{
S1 a;
C1 b;
S2 c;
C2 d;
cout<<sizeof(S1)<<"\t"<<&a<<endl;
cout<<sizeof(C1)<<"\t"<<&b<<endl;
c.foo();
d.foo();
getchar();
return 0;
}
编译,结果报错了,如下所示:
0%
By Long Luo
在开始今天的文章之前,请先看下面一道面试题:
问题: 阅读下面一段代码并回答题目之后的问题:1
2
3
4
5struct ALIGN
{
int mA;
int mB;
};
请问在 32 位系统下 sizeof(ALIGN)
的结果是多少?
当然这道题目是难不到广大程序员同学们滴!
在 32 位机器上 int 类型占 4 个字节,Struct ALIGN 里面有 2 个 int 型变量,那么总共就是 8 个字节喽!
Bingo!在这个例子中,sizeof(ALIGN)
的结果的确是 8 。
下面,我们把代码修改一下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;
struct ALIGN
{
int mA;
int mB;
};
struct ALIGN1
{
int mA;
short mB;
};
int main()
{
cout<<sizeof(short)<<endl;
cout<<sizeof(ALIGN1)<<endl;
getchar();
return 0;
}
请问输出是多少?
深入理解 C/C++ 结构体 <3>:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白... By Long Luo
之前一篇 深入理解 C/C++ 结构体 <2>:Structure 的声明、定义、初始化 ,我们已经了解了C++中Struct的定义方法和C中有点不一样,而且增加了一种新的类型—Class。从C++的名字我们就可以知道,C++是从C进化而来,“++”就是在C的基础上加了一些东西:面向对象的东西。
虽然C++作为一种面向对象语言,要区别于面向过程的C语言,但是在设计时,一个很重要的原则是C++必须向前兼容C,必须是C的超集。这样一来就可以带来好多好处:
第一个嘛,首先呢,C++就可以站在C这个巨人的肩膀上,大量过去用C编写的程序可以不加修改地在C++环境下使用; 第二,把很多C程序员忽悠进C++这个大坑里,为C++之崛起而加班,上了贼船可就由不得你了XD …….
也正是因为这个原因,C++中保留了Struct结构类型,并使得Struct的功能更强大,不仅仅是简单继承C的结构体,而且扩充了Struct,使得它也具有类的特点,那么在C++中,Class和Struct到底有什么区别呢?
Talk is cheap, show me the Code!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using namespace std;
struct S1
{
char mA;
int mB;
};
class C2
{
char mA;
int mB;
};
int main(void)
{
S1 a;
C2 b;
cout<<sizeof(a)<<&a<<endl;
cout<<sizeof(b)<<&b<<endl;
getchar();
return 0;
}
上面这段代码非常简单,分别定义了一个 Struct 类型和 Class 类型,并输出其大小和地址,我们先看看输出结果:
从结果我们可以看出,没啥区别啊!
且慢,再看下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using namespace std;
struct S1
{
char mA;
int mB;
};
class C1
{
char mA;
int mB;
};
struct S2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
class C2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
int main(void)
{
S1 a;
C1 b;
S2 c;
C2 d;
cout<<sizeof(S1)<<"\t"<<&a<<endl;
cout<<sizeof(C1)<<"\t"<<&b<<endl;
c.foo();
d.foo();
getchar();
return 0;
}
编译,结果报错了,如下所示:
0%
By Long Luo
之前一篇 深入理解 C/C++ 结构体 <2>:Structure 的声明、定义、初始化 ,我们已经了解了C++中Struct的定义方法和C中有点不一样,而且增加了一种新的类型—Class。从C++的名字我们就可以知道,C++是从C进化而来,“++”就是在C的基础上加了一些东西:面向对象的东西。
虽然C++作为一种面向对象语言,要区别于面向过程的C语言,但是在设计时,一个很重要的原则是C++必须向前兼容C,必须是C的超集。这样一来就可以带来好多好处:
第一个嘛,首先呢,C++就可以站在C这个巨人的肩膀上,大量过去用C编写的程序可以不加修改地在C++环境下使用; 第二,把很多C程序员忽悠进C++这个大坑里,为C++之崛起而加班,上了贼船可就由不得你了XD …….
也正是因为这个原因,C++中保留了Struct结构类型,并使得Struct的功能更强大,不仅仅是简单继承C的结构体,而且扩充了Struct,使得它也具有类的特点,那么在C++中,Class和Struct到底有什么区别呢?
Talk is cheap, show me the Code!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using namespace std;
struct S1
{
char mA;
int mB;
};
class C2
{
char mA;
int mB;
};
int main(void)
{
S1 a;
C2 b;
cout<<sizeof(a)<<&a<<endl;
cout<<sizeof(b)<<&b<<endl;
getchar();
return 0;
}
上面这段代码非常简单,分别定义了一个 Struct 类型和 Class 类型,并输出其大小和地址,我们先看看输出结果:
从结果我们可以看出,没啥区别啊!
且慢,再看下面这段代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using namespace std;
struct S1
{
char mA;
int mB;
};
class C1
{
char mA;
int mB;
};
struct S2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
class C2
{
char mA;
int mB;
void foo()
{
cout<<"mA="<<mA<<endl;
cout<<"mB="<<mB<<endl;
}
};
int main(void)
{
S1 a;
C1 b;
S2 c;
C2 d;
cout<<sizeof(S1)<<"\t"<<&a<<endl;
cout<<sizeof(C1)<<"\t"<<&b<<endl;
c.foo();
d.foo();
getchar();
return 0;
}
编译,结果报错了,如下所示: