首页
社区
课程
招聘
[旧帖] [原创]C语言——基本数据类型和局部变量 0.00雪花
2011-5-27 12:31 3741

[旧帖] [原创]C语言——基本数据类型和局部变量 0.00雪花

2011-5-27 12:31
3741
说明:比较简单,水平也很一般,错误难免,欢迎批评指正,谢谢

C语言之基本数据类型变量

基本数据类型
先看下C语言的基本数据类型:
bool        布尔                                1字节
char        字符型                         1字节
int                整型                                4字节
float        浮点型(单精度)                4字节
double        浮点型(双精度)                8字节

        数据类型是用来描述对应表示的数据的相关属性,如:大小(在内存中占几字节),数值表示的形式(0,1,有符号是没…)。
        看下各种数据类型的具体表示,这里不得不提到一个东西,就是变量。
        先看示例代码:
int _tmain(int argc, _TCHAR* argv[])
{    
    //bool
    bool isTest = true;
    //char
    char cChar  = 'T';
    //int
    int nNum    = 0x123;
    //float(double)
    float fValue = 1.2f;
    //double
    double dfValue = 1.2;

    return 0;
}


    
[B]//bool[/B]bool isTest = true;

表示真假2种状态,非0为真即true,0为假即false
bool型的值只有true和false,内存中值为1和0,实际上除了为0的情况是false,其他都为true,比如下面的情况。
    isTest = 123;
    isTest = 0.2;
    isTest = 'a';
内存中占用1字节,值都为1既是true。
0x001DFCF3  01 cc cc cc cc 48 fd 1d 00 b8 25 09 01 01 00 00

   
[B] //char[/B]
char cChar  = 'T';

ASCII码是0-255,用1字节就可以表示,实际表示是1字节范围内的所有整型数值
在内存的表现形式如下,占1字节,16进制表示
0x001DFCE7  54 cc cc cc cc cc cc cc cc cc cc cc 01 cc cc cc  T
表示的数据性质呈现一个环形的特性,一直+++或一直---总能回到原点,就跟地球是圆的一样(貌似没人说是方的了)
    //char型
    char cChar  = 0x4;
    for (; ; ++cChar)   //增加方向0x5,0x6,0x7--->
    {
        printf("%02X\r\n", cChar);
        if (cChar == 0x3)
        {
            printf("我又回来啦!\r\n");
            break;
        }
}

输出结果:
FFFFFFFE
FFFFFFFF
00
01
02
03
我又回来啦!
char cChar  = 0x4;    unsigned char cChar  = 0x4;(无符号)
FD
FE
FF
00
01
02
03
我又回来啦!

[B] //int[/B]
int nNum    = 0x123;

表示4字节的整型数值,在内存中如下表示
0x001DFCD8 23 01 00 00 cc cc cc cc cc cc cc cc cc cc cc 54
这里采用小端(小尾)的存储方式,也就是地位在低地址,高位在高地址
0x00000123  从低到高地址为0x1DFCD8-0x1DFCDB对应存放 23 01 00 00
另外一种是大端(大尾)的存储方式,主要是就高低位方向相反,看下示例
在不同的硬件环境下对数据的处理会存在差异,内存中数据主要就是大小尾的问题。
比如数值0x12
在小尾存储方式的内存为12 00 00 00,->小尾读(0x12), 大尾读(0x12000000)
而在大尾方式下为                  00 00 00 12  ->小尾读(0x12000000), 大尾读(0x12)

   
 [B]//float(double)[/B
]float fValue = 1.2f;
0x001DFCB4  [COLOR="red"]9a 99 99 3f[/COLOR] cc cc cc cc cc cc cc cc 02 00 00 00
   [B] //double[/B]
double dfValue = 1.2;
0x001DFCA4  [COLOR="red"]33 33 33 33 33 33 f3 3f [/COLOR]cc cc cc cc cc cc cc cc  

        单精度为4字节,双精度为8字节,在内存中的表示方式是通过IEEE编码后的形式。
        大概的编码形式为:[指数位][指数][小数位]

直接操作栈地址       
看下代码中的数值在内存中的分布情况:
int _tmain(int argc, _TCHAR* argv[])
{    
    int nNum1    = 0x1;
    int nNum2    = 0x2;
    int nNum3    = 0x3;
    int nNum4    = 0x4;
    int nNum5    = 0x5;

    return 0;
}

变量对应的地址和内存中值  (每次值都不太一样,说明下先)
+		&nNum1		0x0016f748	int *
+		&nNum2		0x0016f73c	int *
+		&nNum3		0x0016f730	int *
+		&nNum4		0x0016f724	int *
+		&nNum5		0x0016f718	int *
		&nNum1-&nNum5 	12	unsigned long
0x0021F874  05 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F880  04 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F88C  03 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F898  02 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F8A4  01 00 00 00 cc cc cc cc fc f8 21 00  ....??????!.

说明:
局部变量是放在栈中,栈就是一块内存,栈的特性是先进后出,跟正常穿衣脱衣顺序类似,这里只要了解下即可。
1+2 的计算,其实就是拿对应内存的值来做加法运算
    nNum5 = [COLOR="red"]*(int*)0x0021F8A4 + *(int*)0x0021F898  [/COLOR];
     这里主要了解下就好,其实是指针的操作 *(类型*)内存地址 ->操作指定地址按指定类型使用
00CC1041  mov         eax,dword ptr ds:[0021F8A4h] 
00CC1046  add         eax,dword ptr ds:[21F898h] 
00CC104C  mov         dword ptr [nNum5],eax

在看下内存
0x0021F874  03 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F880  04 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F88C  03 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F898  02 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0021F8A4  01 00 00 00 cc cc cc cc fc f8 21 00
在来个复杂的运算 (因为VC2008占地址不固定每次都是动态取值,分布还是比较固定的说)
[code](1+2)*3+4   
nNum5 = (*(int*)0x0018fa1c + *(int*)0x0018fa10)* *(int*)0x0018fa04 + *(int*)0x0018f9f8 ;
00FF1041  mov         eax,dword ptr ds:[0018FA1Ch]
00FF1046  add         eax,dword ptr ds:[18FA10h]
00FF104C  imul        eax,dword ptr ds:[18FA04h]
00FF1053  add         eax,dword ptr ds:[18F9F8h]
00FF1059  mov         dword ptr [nNum5],eax
运行后内存 (1+2)*3 + 4 => 3*3+4 => (13)10   (D)16
0x0018F9EC  0d 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0018F9F8  04 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0018FA04  03 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0018FA10  02 00 00 00 cc cc cc cc cc cc cc cc  ....????????
0x0018FA1C  01 00 00 00 cc cc cc cc 74 fa 18 00  ....????t?..
[/code]
再来点有难度
(((1+2*3)^2+3*4-2)*3/2+3-4)*4
这个也没问题,就是地址操作嘛。。。。。。
ZZZ 不过写的也太累了,要是再复杂点,地址成百上千的不用运算,我晕了。

主角闪亮登场”变量,变量名”
变量,字面理解就是会变化的值。
变量名,字面理解就是会变化值的名字,你可以和前面的地址对应起来了嘛?
        变量名要使用字面,_,数字做为名称,数字不能第一个(不然谁搞的清是数字还是变量),不能使用保留字,名字最好能望名知意。
我们再用变量名来做下运算
1+2 =>  nNum1+ nNum2
    nNum5 = nNum1 + nNum2;
00CE1EE1  mov         eax,dword ptr [nNum1] 
00CE1EE4  add         eax,dword ptr [nNum2] 
00CE1EE7  mov         dword ptr [nNum5],eax

和下面的代码其实是一回事,只是在调试时有符号名称,其实操作还是地址及其内容
00CC1041  mov         eax,dword ptr ds:[0021F8A4h] 
00CC1046  add         eax,dword ptr ds:[21F898h] 
00CC104C  mov         dword ptr [nNum5],eax

变量名其实是地址的一个代号名称,高级语言给一个好的助记符来代替地址,在底层实际还是地址操作。在日常生活中也常用,比如电话号码,QQ好友,总要给来个响亮的名字吧。
这个可提供了非常大的便利,从此就脱离的低级趣味了,可以定义一堆喜欢的名字
Int a;
Int aa;
Int aaa;
Int aaaa;
。。。。。。。。。。。。
莫非又穿越了,跟记数字有区别嘛,好的名字成功的开始
变量名的规范,个人习惯仅供参数
bool 型            is_xxx
int型                n_xxxx
char                        cXxxxx
float                fXxxxx
DWORD                dwXxxx
全局                g_类型+名称          g_nNumber
静态                s_类型+名字
成员                m_类型+名字   m_xXxxx
        。。。。。。。。
总结:
1)        数据类型是用来约束所标识的类型的数据特性;
2)        在内存中数据都是16进制补码的形式存在,存在大小端的情况;
3)        浮点数采用IEEE的编码方式保存;
4)        变量名是对对应内存地址的一个别名,高级语言提高的一个友好的描述;
5)        变量名称要能反映数据类型和作用,避免穿越。
6)        内存中的数据和类型关联就有了相应的类型特性,也就是说通过指针方式来重新指定某地址的数据类型,说它是啥就是啥。OY!

有名称代号了就好办事了,9527给哥买张火车票去。哈哈!

说明:水平有限,错误不妥难免,欢迎批评指点,谢谢!

                                                    五边形   2011年5月

下一篇  关于常量链接:
       http://bbs.pediy.com/showthread.php?p=963240#post963240

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞5
打赏
分享
最新回复 (6)
雪    币: 151
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
w陌生人 2011-5-27 13:19
2
0
支持下,祝你早日转正~~~
雪    币: 185
活跃值: (130)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
五边形 1 2011-6-14 23:35
3
0
非常感谢楼上精神鼓励,现在我转正了,后续主题帖应该不会发这里了,终于可以到其他版块发发帖了,不过有需要我还会回来的。
这个主题是上个月的学习计划,把看的东西发出来大家谈论下,结果发现大家都莫多大兴趣。不过非常感谢版主的肯定和鼓励,我抽空在回头把学的东西在整理下。
个人感觉C语言学习的重点:要了解内存组织结构(各种数据类型在内存的分布情况),栈结构(了解函数调用的实现),有了内存结构分布的认识再学习指针,你就会比较有感觉,指针就是内存地址+类型属性。
其他的语法东西就是多看看,没事多写写应该就可以了。
C学完了之后再看asm,也会比较简单,寻址方式(实质就是内存地址的表示方式不同),你有了内存的概念,栈的概念,加上基本的指令使用,再多查查跳转 ,asm也会被你轻松拿下(至少心里有点谱)。
明天要继续战斗, OY'
雪    币: 176
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rvnctu 2011-6-16 00:32
4
0
mark一下,以后学习
雪    币: 345
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jacalhu 2011-6-16 15:14
5
0
学习下。。。
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kelilsh 2011-6-16 16:16
6
0
学习了,顶一个,谢谢,尤其是大端存贮和小端存贮
雪    币: 26
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xxghk 2011-6-16 18:09
7
0
呵呵 这个感觉还不错
游客
登录 | 注册 方可回帖
返回