C++ -- 基本数据类型的表现形式

基本数据类型的表现形式

  • 整数类型
    C++提供的整数类型有三种:int, long, short,在32位系统中,int, long 都占4字节,short占2字节。同时它们又可以分为有符号型与无符号型,在内存中,前者数据由一个符号位 + 数据位组成,而后者全是数据位组成。所以无符号整数类型表示的正数区间比有符号表示的正数区间要大一倍。如以int为例,对于unsigned int的取值范围:0x00000000-0xFFFFFFFF(0-4294967295),而signed int的取值范围:0x80000000-0x7FFFFFFF(-2147483648-2147483647)这里负数区域之所以要比正数区域多一,是因为我们把-0(0x80000000)规定为最小值-2147483648,这样就没有+0与-0区别了,就是0。
    注释:计算机中一般以补码的形式存储数据,规则:正数的补码是其本身,负数的补码是取反加一,符号位不操作。

  • 浮点数类型
    C++提供float与double两种浮点数,一个占4字节一个占8字节。浮点数强转整数会直接丢弃小数部分,而不会进行四舍五入,浮点类型都是有符号的,内存中浮点类型数据是由符号 + 指数 + 尾数组成表示的。

  • 字符和字符串
    字符串是由多个字符按照一定的排列顺序组成的,在C++中,以‘\0’作为字符串结束的标志。每个字符都记录在一张表中,它们各自对应一个唯一的编号,内存中就是保存这个编号来操作对应字符的。字符表中的编号就是我们说的字符编码格式,一般有两种:ASCII和Unicode。ASCII码是用一个字节来表示一个字符,所以总共只能表示255个字符,这对应复杂的字符如中文的表示还是不够的,所以有了占两字节的Unicode码,它用两个字节表示一个字符,总共可以表示65535个字符。

  • 布尔类型
    在C++中,定义0为假,非0为真。使用bool定义的布尔类型变量(值:true,false)在内存中占一个字节。而实际上其他任何类型都可以替代布尔类型。

  • 地址,指针和引用
    地址:就是指在内存中的位置,只有变量才有地址,我们通过’&’来取一个变量的地址。
    指针:就是用来存储地址(首地址)的一个变量,在32位系统中所有指针都占4个字节,而具体的类型只是说明解析的方式,如int *p则是从这个指针保存的地址处开始向后读4个字节作为这个指针指向的值。
    引用:C++中引用被描述为变量的别名,本质上引用其实还是指针,只不过它用于存放地址的内存空间对使用者而言是隐蔽的。它的寻址是通过编译器实现的,不像指针那样是手动寻址。虽然没有指针灵活但比指针更加安全,因此,C++提倡使用引用。

  • 常量
    常量数据在程序运行前就已经存在,编译期间就被编译到可执行的二进制文件中,运行时直接被加载进来。这些数据通常保存在常量区,这个区域没有可写属性。所以常量定义好后不能修改。常量一般包括:普通常量(1,2,3等),const常量(伪常量),#define宏常量,字符串常量,数组名等.
    注释:const int a = 10;这样的常量是伪常量,在内存中表现和一般变量没区别,只是这种常量在编译期间由编译器识别优化,如输出a就会被编译成这样printf(“%d”,10);编译器直接把它替换。而它在内存的值得到其指针还是可以修改的。C++一般鼓励用它来替代宏常量:因为,(1)const有类型检测,而#define是直接字符串替换。(2)const的常量可以控制作用域,而#define一般是全局作用域。

  • 特别说明
    1, c++自己定义好了一套准则,所有编译器都要遵循这个规则,至于编译器底层具体怎么去运行实现它们这个不确定,但最终的结果要遵循这个定好的标准。对于一些未定义的行为,不同的编辑器就可能会有不同的表现。所以很多问题不能只死认VS,不同环境实现可能不同。

    2,从你敲代码,到真正运行起来,一般有预编译,编译,链接,加载,这几步。首先是预编译阶段,主要是对c,cpp或asm等源文件进行整理,主要包括将头文件拷贝到源文件中(#include),将代码中的宏定义替换和条件编译等。然后就是编译阶段,主要将整理好的源文件编译成一个个obj文件。然后这些obj链接得到exe。最后由操作系统加载exe(把这些可执行的二进制代码全部加载进内存),得到进程,即我们程序的运行。

    3,动态链接(dll)与静态链接(lib):(1)首先你能调用一个函数,前提就是它在内存里存在。一般的函数,编译链接之后,在exe里面。操作系统加载exe的时候,分配内存,然后把函数代码放在这块内存,所以你就能直接调用函数了。(2)dll的话,不一样。这是把一些代码跟程序主体分开,编译链接为dll。加载exe的时候,dll可能尚未加载,这时,你想调用的函数不在内存里。你可以手动用LoadLibrary这个函数手动加载dll,然后这个函数就在内存里了,可以取得它的地址,然后就可以调用。但一般编译器会帮我们在使用时自动加载dll,其底层实现无非也是这么操作的。因此,dll的加载其实就类似函数的调用,它能节省内存。(3)lib的话,正好相反,即把lib库拷贝一份到exe里面,这样与一般的编译过程差不多了,可以脱离库使用,类似内联。(4)之所以使用库,主要就是方便复用,节省编译时间,因为这些库都是已经编译好的二进制文件。

    4,应用程序在内存中一般分为几块区域:
    全局数据区:存放全局数据,静态数据等
    代码区:代码存放区域
    栈区:局部变量
    堆区:动态内存

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页