C\C++小知识汇总
来源:互联网 发布:淘宝子账号售后权限 编辑:程序博客网 时间:2024/06/08 05:39
类的大小
- 空类(不含成员变量和虚函数):因为对象不可能不占内存,否则这个对象怎么存在,所以C++规定空类对象内存大小为1。
class EC{public:EC(){}~EC(){};void EC1(){printf("EC1\n");}};class EVC{public:EVC(){}~EVC(){};void EVC1(){printf("EVC1\n");}virtual void VEVC1(){printf("EVC1\n");}};int main(int argc, char*argv[]){printf("%d\n", sizeof(EC));printf("%d\n", sizeof(EVC));}
输出结果:14
- 虚类(包含虚函数的类):因为声明虚函数后,类需要管理虚函数,所以创建了虚函数指针,所以类的对象大小还要计算这个虚表指针的大小。
- 普通类:一般考虑像C的结构体那样即可(考虑数据对齐)。
函数调用方式
- _cdecl : C\C++的默认调用方式,函数调用负责管理函数调用堆栈,支持不定参数。
- _stdcall : WINAPI的调用方式,函数本身负责管理函数调用堆栈,不支持不定参数。
- _fastcall : 寄存器方式传参,函数本身负责管理函数调用堆栈,不支持不定参数,VC默认在参数个数小于等于3的情况下使用这种方式。
;--- e:\code\win32\dre\helloworld\main.cpp --------------------------------------#include <stdio.h>int _cdecl Test(int a, int b){009E13A0 push ebp 009E13A1 mov ebp,esp 009E13A3 sub esp,0C0h 009E13A9 push ebx 009E13AA push esi 009E13AB push edi 009E13AC lea edi,[ebp-0C0h] 009E13B2 mov ecx,30h 009E13B7 mov eax,0CCCCCCCCh 009E13BC rep stos dword ptr es:[edi] return a+b;009E13BE mov eax,dword ptr [a] 009E13C1 add eax,dword ptr [b] }009E13C4 pop edi 009E13C5 pop esi 009E13C6 pop ebx 009E13C7 mov esp,ebp 009E13C9 pop ebp 009E13CA ret;无平衡堆栈,这类调用方式不用处理函数堆栈帧;--- 无源文件 -----------------------------------------------------------------------;--- e:\code\win32\dre\helloworld\main.cpp --------------------------------------int _stdcall Test1(int a, int b){009E13F0 push ebp 009E13F1 mov ebp,esp 009E13F3 sub esp,0C0h 009E13F9 push ebx 009E13FA push esi 009E13FB push edi 009E13FC lea edi,[ebp-0C0h] 009E1402 mov ecx,30h 009E1407 mov eax,0CCCCCCCCh 009E140C rep stos dword ptr es:[edi] return a+b;009E140E mov eax,dword ptr [a] 009E1411 add eax,dword ptr [b] }009E1414 pop edi 009E1415 pop esi 009E1416 pop ebx 009E1417 mov esp,ebp 009E1419 pop ebp 009E141A ret 8;平衡堆栈,这类调用方式需要处理函数堆栈帧;--- 无源文件 -----------------------------------------------------------------------;main;{Test(1,2);009E145E push 2 009E1460 push 1 009E1462 call Test (9E100Ah) 009E1467 add esp,8;平衡堆栈,调用者需要处理函数堆栈帧Test1(1,2);009E146A push 2 009E146C push 1 009E146E call Test1 (9E107Dh);无平衡堆栈,被调用者已处理函数堆栈帧;}
静态局部变量初始化
问:C\C++中如何实现静态变量多次调用但是只初始化一次 呢?答:一定有方法的,编程语言能搞定他的!问:到底是啥呢?答:....其实,如果不是看到相关的问题或者资料,这个问题想得人还真不多。其实这个问题实现的方法也简单,弄一个东西记录该静态变量是否初始化即可,编译器的一般做法是选取该变量附近的一个字节来记录该静态变量是否初始化了,但是因为记录该状态只需要一个Bit即可,而一字节有8Bit,所以这个字节可以被其他静态变量共享使用的。static int nSa = a;000C143E mov eax,dword ptr [$S1 (0C713Ch)] ; ===========BEG==============000C1443 and eax,1 000C1446 jne TestStaticVar+3Dh (0C145Dh) 000C1448 mov eax,dword ptr [$S1 (0C713Ch)] 000C144D or eax,1 ; ===========END==============000C1450 mov dword ptr [$S1 (0C713Ch)],eax 000C1455 mov eax,dword ptr [a] 000C1458 mov dword ptr [nSa (0C7138h)],eaxBEG到END部分的代码就是用来判断该静态变量是否已经初始化了的,此处用的是该字节的最低一个BIT
内存对齐
所谓内存对齐,就是为了方便系统寻址,高效地处理数据,它要求成员变量的地址n字节对齐,n字节边界对齐的意思是说,一个成员的地址必须安排在成员的尺寸的整数倍地址上或者是n的整数倍地址上,取它们中的最小值,也就是:min ( sizeof ( member ), n)。n的值可由对齐预处理指令#pragma pack(n)指定,也可根据结构体内最大的基本数据类型的大小确定。
struct __t1{chara;intb;shortc;};sizeof(struct __t1) = 4+4+4 = 12;
调用函数获取数组大小信息
一般而言,如果需要把数组以参数的形式传给其他函数的时候是需要传入数组的长度的,因为被传入的函数比较难(或者说我们不知道)获取数组的长度。但是,实际上我们是可以通过技术手段在被传入的函数里面获取数组的大小的,而不需要额外传入数组的长度。实现的函数如下所示:
template <typename T, int N>void ShowArrayInfo(T (&ppArray)[N]){ printf("size = %ld\n", sizeof(ppArray)); printf("length = %d\n", N);}调用的地方很简单,和往常的方法一致的,比如:long c[13] = {0};ShowArrayInfo(c);
0 0
- c语言小知识汇总
- C\C++小知识汇总
- C的知识汇总
- C/C++ 知识汇总
- Objective-C知识汇总
- c语言知识汇总
- C语言 小知识!~
- C 小知识整理
- c语言 小知识
- C/C++小知识
- c++/java小知识
- 求助 c小知识
- C语言小知识
- C/C++ 小知识
- c语言小知识
- C/C++小知识
- C语言小知识
- C语言小知识
- JS判断手机浏览器
- 基于Intel-x86结构的Linux_SMP系统启动启动过程
- C++第12周(春)项目3 - 摩托车继承自行车和机动车
- activity生命周期 A启动B,B返回A, A,B的全生命周期
- 关于exit函数
- C\C++小知识汇总
- wifi热点中文名走起——wifi共享精灵2014. 4 .25升级日志详解
- 详解FusionChart图表控件点击事件
- Android 跑马灯
- Junit与spring TestContext框架整合
- 决定好好休息一下再回来
- php基础2
- Linux编译安装boost
- 几种相似度计算公式