C/C++编程基本功

C/C++编程基本功

C++其内容精深博大,任何一块都信手拈来者不多,究其精者更不多,不论何其原因,最重要一点就是其基本功之不扎实,对基础性东西不加以精深研究。我也是一样,经过几轮经典的面试,让我痛改以前的不扎实的作风,以此来磨砺自己。

 

一.内存管理篇

  

一个由C/C++编译的程序占用的内存分为以下几个部分:

1. 代码区  (Code section)

2. 数据区  (Data section)

3.       (Stack)

4.       (Heap)

 

解释说明:

 

1.数据区:

有人说数据区分全局区,静态区,文字常量区. 这些应该来说是细分数据区,其实这些被细分的区在OS里面还是被愿意称作为数据区。这里面存放的变量的值及占用的空间始终伴贯穿着整个程序的生命周期,直到程序结束后由系统收回。

     

         下面给出一个程序例子,我们进行汇编之后可以看出变量所在的内存区域。

#include<string.h>

  
  
   
    
  
  
struct Employee
{
    char firstname[32];
    char lastname[32];
    unsigned char age;
    unsigned int salary;
};

  
  
   
    
  
  
struct Employee architect = {"Gil","Bates",45,100000};
struct Employee ceo = {"Reed","Almer",42,95000};
struct Employee drone;

  
  
   
    
  
  
void main()
{
    strcpy(drone.firstname,"bill");
    strcpy(drone.lastname,"blunden");
    drone.age=35;
    drone.salary=(int) (3.5);
    return;
}
    
    

 

下面是VS.Net 2005汇编产生的代码:

.file "f:/Project/MyProject/Sample5/Sample5.cpp"

.global      ?drone@@3UEmployee@@A                            ; drone

.global      ?architect@@3UEmployee@@A                ; architect

.global      ?ceo@@3UEmployee@@A                        ; ceo

.bss

.local ?drone@@3UEmployee@@A,72                ; drone

.rdata

 

$SG8630:

.ascii       "bill/000"

.space     3

 

$SG8631:

.ascii       "blunden/000"

.data

 

?architect@@3UEmployee@@A:                        ; architect

.ascii       "Gil/000"

.space     28

.ascii       "Bates/000"

.space     26

.byte       0x2d

.space     3

.word      0x 186a 0

 

?ceo@@3UEmployee@@A:                               ; ceo

.ascii       "Reed/000"

.space     27

.ascii       "Almer/000"

.space     26

.byte       0x 2a

.space     3

.word      0x17318

; Function compile flags: /Odtp

; File f:/project/myproject/sample5/sample5.cpp

.text

.global      ?main@@$$HYAHXZ                                ; main

?main@@$$HYAHXZ:                                ; main

;       .proc.def D:I()

 

; Function Header:

; max stack depth = 2

; function size = 58 bytes

; local varsig tk = 0x0

; Exception Information:

; 0 handlers, each consisting of filtered handlers

 

 

;       .proc.beg

 

; 20   :     strcpy(drone.firstname,"bill");

 

ldsflda            ?drone@@3UEmployee@@A

ldsflda            $SG8630

call         ?strcpy@@$$J0YAPADPADPBD@Z

pop        

 

; 21   :     strcpy(drone.lastname,"blunden");

 

ldsflda            ?drone@@3UEmployee@@A

ldc.i4.s    32           ; i32 0x20

add        

ldsflda            $SG8631

call         ?strcpy@@$$J0YAPADPADPBD@Z

pop        

 

; 22   :     drone.age=35;

 

ldsflda            ?drone@@3UEmployee@@A

ldc.i4.s    64           ; i32 0x40

add        

ldc.i4.s    35           ; u8 0x23

stind.i1   

 

; 23   :     drone.salary=(int) (3.5);

 

ldsflda            ?drone@@3UEmployee@@A

ldc.i4.s    68           ; i32 0x44

add        

ldc.i.3            3            ; u32 0x3

stind.i4   

 

; 24   :     return;

; 25   : }

 

ldc.i.0            0            ; i32 0x0

ret         

 .end ?main@@$$HYAHXZ                               ; main

;       .proc.end.i4

_TEXT    ENDS

PUBLIC   __mep@?main@@$$HYAHXZ

PUBLIC   _main

;       COMDAT __mep@?main@@$$HYAHXZ

data  SEGMENT

__mep@?main@@$$HYAHXZ TOKEN 0A 000009

; Function compile flags: /Odtp

data  ENDS

;       COMDAT _main

_TEXT    SEGMENT

_main       PROC                                        ; COMDAT

jmp  DWORD PTR __mep@?main@@$$HYAHXZ

_main       ENDP

_TEXT    ENDS

END

 

以上我们就可以清楚的知道数据区存储的是全局变量和本地变量,想想看其实汇编其实也不是蛮难的吗J

 

 

2.代码区

       存放函数体的二进制代码.

 

下面是我引用《Memory Management: Algorithms and Implementation》一书上面的例子,我发现很有趣。

/* --codedata.c-- */

  
  
   
    
  
  
#include<stdio.h>

  
  
   
    
  
  
void code()
{
    /*
    on Intel, each instruction is 4 bytes:
    encoded as 0x66 0xb8 0x07 0x00
    */
    _asm MOV AX,0x07
    _asm MOV AX,0x07
    _asm MOV AX,0x07
    _asm MOV AX,0x07
    /* 16 bytes total */
    return;
}

  
  
   
    
  
  
void main()
{
    char *cptr;  
    short reg;

  
  
   
    
  
  
    code();
    _asm MOV reg,AX
    printf("reg=%d/n",reg);

  
  
   
    
  
  
    cptr = (char*)code;
     
     
    cptr[0]='d'; cptr[1]='a';cptr[2]='t';cptr[3]='a';
    
    
    cptr[4]=(char)0;
    printf("cptr[]=%s/n",cptr);
    return;
}

 

代码有意思的一部分就是把代码区变为数据区(红色标注部分),OS有规定代码区只有被访问权限,没有写的权限。下面是在windows下面执行时发出的警告信息。

 

(图形1-1

 

3.栈

   栈是是向低地址扩张的先进后出的数据结构,是一块续的内存区域。每一个栈都有一个栈指针(如图1-2),用来存储栈中最后一项元素的低地址。当新元素被加进栈中,栈指针就会相应的减少,这时的栈指针指向指新元素的第一个字节的地址。

              (图形1-2)

 

/* sample2.cpp */

int main()

{     

        int i=0;   // i在栈上

        int sum = 0;  // sum在栈上

        for(i=0; i<100; i++)

               sum+=i;

        printf(“%d”,sum);

}

 

4.

是向高地址扩展的数据结构,是不连续的内存区域.

(未完,待续)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值