分享

第一部分 基础语言之一变量和基本类型

 君王之王 2016-02-27

1.1 基本内置类型

C++标准规定的最小,存储空间,但不阻止编译器使用更大空间
       bool                    8bit

       char                    8bit

        wchar_t                   16bit

       short                   16bit

       int                    16bit
       long                    32bit

       float                   6位有效数字

       double                  10位有效数字

       long double               10位有效数字

1.1.1 整型(integral type

              整数、字符和布尔的算数类型合成整型

字符型:charwchar_t(表示扩展字符集,如表示中文等)

整型值:short 半个字长(32为机器为16bit)、int 一个字长、long 2个字长(在32bit机上与int同)

布尔型:bool 表示真值true,表示假值false ;0值算数类型表示false,任何非零值都表示true.

1.带符号和无符号类型

       bool外,整型可以是带符号的(signed)也可以是无符号的(unsigned)

intshortlong默认是带符号的,无符号要指明unsigned

unsigned unsigned int的简写

 

char有三种类型,普通charunsigned char signed char一般编译器用后两者的之一表示普通char类型

2.整型的表示

C++标准未定义signed类型如何有位表示,由编译器自己决定,以unsigned char 8bit)为例,在MS-VS中编译器表示范围:-128~127 

计算机存储整型的补码,最高位为符号位,使用补码其实就是使 +0D -0D ,只占用一个编码即补码都为0000 0000B,这样编码就可以充分利用,1000 0000表示-128,所以编码结构如下:

                          1000 0000  -------------->  -128(空余的补码)

                         1000 0001  -------------->  -127

       负数           ……

                         1111 1110  -------------->  -2

                         1111 1111  -------------->  -1

                         0000 0000  -------------->  0 (+0-0的补码是一样的)

                         0000 0001  -------------->  1

       正数          ……

                         0111 1110  -------------->  126

                         0111 1111  -------------->  127

3.整型的赋值

unsigned赋值溢出,将会取模运算,其实就是高位被截断,直接取低位,signed类型大部分编译器也是这么做,但不能得到保证。

1.1.2 浮点型

一个float用一个字32bit表示,double用两个字64bit表示,long double3个或四个字来表示96bit128bit.类型的取值范围决定了,类型的有效数字。

种类-------符号位-------------指数位----------------尾数位---- 
float---31(1bit)---30-23(8bit)----22-0(23bit) 

double--63(1bit)---62-52(11bit)---51-0(52bit) 

取值范围主要看指数部分: 
float的指数部分有8bit(2^8),由于是有符号型,所以得到对应的指数范围-128~128 

double的指数部分有11bit(2^11),由于是有符号型,所以得到对应的指数范围-1024~1024 

由于float的指数部分对应的指数范围为-127~128(使用余数码表示,而非补码),所以指数取值范围为: 
2^(-127)2^128,约等于1/1.7E38  +3.4E38 

精度(有效数字)主要看尾数位: 
float的尾数位是23bit(8,388,608),对应6~7位十进制数,所以有效数字有的编译器是6位,也有的是7位,表示不了全部的7位有效数字。

1.2 字面值常量

1.2.1  整型字面值规则

20  //decimal  

024  //octal   0开头表示8进制

0x14  //hexadecimal  0x或者0X开头表示16进制

128U 表示无符号、128L表示长整型

1.2.2 浮点字面值规则

3.114F 表示单精度

3.14L  表示扩展精度

1.2.3 布尔和字符字面值规则

字符用单引号,前面加'L’可以得到wchar_t类型

1.2.4 字符串字面值连接

std:cout<< “a multi-line”

                   “string literal”

                   “using concatenation”

             << std::endl;

仅由空格、制表符、换行分开的字符串字面值,可连接成一个新的字符串

1.2.5 浮点字面值规则

std:cout<< “a multi-line”<< st\

d::endl;

相当于同一行代码等价于 std:cout<< “a multi-line”<< std::endl;

要保证 '\’ 为改行最后一个字符,后面不能有注释或空格  

1.3 变量

1.3.1 左值和右值

左值:可以出现在赋值语句的左边或右边

右值:只能出现在赋值语句的右边 

1.3.2 变量名

变量名,由字母数字下划线组成,不能以数字开头,不能使用关键字


1.3.3 初始化
C++ 支持两种初始化变量的形式:
复制初始化和直接初始化。复制初始化语法用等号(=),直接初始化则是把初始化式放在括号中:
int ival(1024); // direct-initialization
int ival = 1024; // copy-initialization

1.3.4 初始化规则
1.内置类型初始化
内置类型变量是否自动初始化取决于变量定义的位置。
在函数体外定义的变量都初始化成 0,
在函数体里定义的内置类型变量不进行自动初始化。除了用作赋值操作符的左操作数,
未初始化变量用作任何其他用途都是没有定义的。未初
始化变量引起的错误难于发现。

2.类类型初始化

如果定义某个类的变量时没有提供初始化式,这个类也可以定义初始化时的

操作。它是通过定义一个特殊的构造函数即默认构造函数来实现的。这个构造函
数之所以被称作默认构造函数,是因为它是“默认”运行的。如果没有提供初始
化式,那么就会使用默认构造函数。不管变量在哪里定义,默认构造函数都会被
使用。

1.3.5 变量定义和声明

在变量使用处定义变量,在头文件中申明全局变量

1.3.6 变量作用域

命名空间作用域  namespace scope

类作用域          class scope
全局作用域      globle scope
局部作用域      local scope
语句作用域   statement scope

C++程序内存空间

1.4 const限定符

1.4.1 定义const对象
const对象再定义时必须初始化,因为定义以后,const对象就不可以再修改
可用于循环的界限等,这样变量名即表明了界限的意义,又可以在多个地方使用

1.4.2 const对象默认为文件的局部变量
同过一个例子来说明:
// file_1.cc
// defines and initializes a const that is accessible to other files
extern const int bufSize = fcn();
// file_2.cc
extern const int bufSize; // uses bufSize from file_1
// uses bufSize defined in file_1
for (int index = 0; index != bufSize; ++index)
本程序中,file_1.cc 通过函数 fcn 的返回值来定义和初始化 bufSize。
而 bufSize 定义为 extern,也就意味着 bufSize 可以在其他的文件中使用。
file_2.cc 中 extern 的声明同样是 extern;这种情况下,extern 标志着
bufSize 是一个声明,所以没有初始化式。
非 const 变量默认为 extern。要使 const 变量能够在其他的
文件中访问,必须地指定它为 extern。

1.5 引用
引用是一种复合类型,通过在变量名前添加“&”符号来定义。
复合类型是指用其他类型定义的类型。
在引用的情况下,每一种引用类型都“关联到”某一其他类型。
不能定义引用类型的引用,但可以定义任何其他类型的引用。

引用必须用与该引用同类型的对象初始化:
int ival = 1024;
int &refVal = ival;  // ok: refVal refers to ival
int &refVal2;          // error: a reference must be initialized
int &refVal3 = 10; // error: initializer must be an object

当引用初始化后,只要该引用存在,它就保持绑定到初始化时
指向的对象。不可能将引用绑定到另一个对象。

const引用
const int ival = 1024;
const int &refVal = ival;  // ok: both reference and object are const
int &ref2 = ival;    // error: non const reference to aconst object

const 引用可以初始化为不同类型的对象或者初始化为右值:
int i = 42;
// legal for const references only
const int &r = 42;
const int &r2 = r + i;
同样的初始化对于非 const 引用却是不合法的,而且会导致编译时错误。

观察将引用绑定到不同的类型时所发生的事情,最容易理解上述行为。假如我们
编写
double dval = 3.14;
const int &ri = dval;
编译器会把这些代码转换成如以下形式的编码:
int temp = dval;               // create temporary int from the double
const int &ri = temp;      // bind ri to that temporary
如果 ri 不是 const,那么可以给 ri 赋一新值。这样做不会修改 dval,
而是修改了 temp。期望对 ri 的赋值会修改 dval 的程序员会发现 dval 并没

1.6  typedef 名字
类型别名,通常被用于以下三种目的
· 为了隐藏特定类型的实现,强调使用类型的目的。
· 简化复杂的类型定义,使其更易理解。
· 允许一种类型用于多个目的,同时使得每次使用该类型的目的明确。
 
1.7 枚举
枚举的定义包括关键字 enum
// input is 0, output is 1, and append is 2
enum open_modes {input, output, append};

可以为一个或多个枚举成员提供初始值,用来初始化枚举成员的值必须是一
个常量表达式。常量表达式是编译器在编译时就能够计算出结果的整型表达式。
整型字面值常量是常量表达式
例如,可以定义下列枚举类型:
// shape is 1, sphere is 2, cylinder is 3, polygon is 4
enum Forms {shape = 1, sphere, cylinder, polygon};

枚举成员值可以是不唯一的。
// point2d is 2, point2w is 3, point3d is 3, point3w is 4
enum Points { point2d = 2, point2w,
point3d = 3, point3w };
不能改变枚举成员的值。枚举成员本身就是一个常量表达式,所以也可用于
需要常量表达式的任何地方。

1.8 类类型
每个类都定义了一个接口和一个实现。接口由使用该类的代码需要执行的操
作组成。实现一般包括该类所需要的数据。实现还包括定义该类需要的但又不供
一般性使用的函数。

用 class 和 struct 关键字定义类的唯一差别在于默认访问
级别:默认情况下,struct 的成员为 public,而 class 的成
员为 private。

1.9 编写自己的头文件
头文件为相关声明提供了一个集中存放的位置。
头文件一般包含类的定义、extern 变量的声明和函数的声明。
对于头文件不应该含有定义这一规则,有三个例外。头文件可以定义类、值
在编译时就已知道的 const 对象和 inline 函数

头文件的正确使用能够带来两个好处:保证所有文件使用给定实体的同一声
明;当声明需要修改时,只有头文件需要更新。

设计头文件还需要注意以下几点:头文件中的声明在逻辑上应该是统一的。
编译头文件需要一定的时间。如果头文件太大,程序员可能不愿意承受包含该头
文件所带来的编译时代价。
为了减少处理头文件的编译时间,有些 C++的实现支持预编译头文件。

当该 const 变量是用常量表达式初始化时,可以保证所有的变量都有相同
的值。但是在实践中,大部分的编译器在编译时都会用相应的常量表达式替换这
些 const 变量的任何使用。所以,在实践中不会有任何存储空间用于存储用常
量表达式初始化的 const 变量。
如果 const 变量不是用常量表达式初始化,那么它就不应该在头文件中定
义。相反,和其他的变量一样,该 const 变量应该在一个源文件中定义并初始
化。应在头文件中为它添加 extern 声明,以使其能被多个文件共享。

1.9.1 预处理器的简单介绍

预处理器变量避免重复包含
可以使用这些设施来预防多次包含同一头文件:
#ifndef SALESITEM_H
#define SALESITEM_H
// Definition of Sales_itemclass and related functions goes here
#endif

使用自定义的头文件
#include 指示接受以下两种形式:
#include <standard_header>
#include "my_file.h"
如果头文件名括在尖括号(< >)里,那么认为该头文件是标准头文件。编译器将会在预定义的位置集查找该头文件,这些预定义的位置可以通过设置查找路径环境变量或者通过命令行选项来修改。使用的查找方法因编译器的不同而差别迥异。建议你咨询同事或者查阅编译器用户指南来获得更多的信息。如果头文件名括在一对引号里,那么认为它是非系统头文件,非系统头文件的查找通常开始于源文件所在的路径。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多