《C++ Primer》学习笔记 第二章 变量与基本类型

时间:2021-04-19 15:45:56

/*

/ 声明: 该文章为重读《C++ Primer》的笔记,尤其是本人认为容易忘记的知识点。

/   希望对其他读者也能有点帮助,也希望大家能相互交流提高。

*/

Tips: 在debug中,常用cout<<var; 来查看变量输出值时,需要使用endl操作来刷新输出流,否则无法将变量值实时输出。

基本内置类型

boolcharwchar_tshortint , float, double, long double均为c++内置类型。
在我自己32位机器VS2010下各类型所占字节数如下:
 image《C++ Primer》学习笔记 第二章 变量与基本类型

可见,在32位机器下,int, float型所占字节数相同,double, long double也是相同的。

整型的赋值

当我们试着把一个超出其取值范围的值赋给一个指定类型的对象是,其结果取决于这种类型是signed还是unsigned

unsigned编译器必须调整越界值来使其满足要求。编译器会将该值对unsigned类型的可能取值数求模,然后取所得值。如8位的unsigned char,其取值范围是0-255, 如果将336赋值,得到的结果是336%256=80.

c++中将负数赋值给unsigned char也是合法的,但是负数永远超出其取值范围,因而unsigned char永远不会存储负数。如将-1赋值,得到结果是255,因为-1%256=255.

 signed:由编译器决定其值。很多编译器会以处理unsigned的方式来处理signed。如vs2010中,将336赋值给signed char得到的值也为’P’, 80.

初始化

c++支持的两种初始化方式:复制初始化、直接初始化。

int ival(1024); // direct-initialization

int ival = 1024;  // copy-initialization

c++中初始化不是赋值,初始化是创建变量并给它赋值,而赋值则是擦除对象的当前值并用新值覆盖。在编写复杂类时两者之间有着微妙的差别,记住直接初始化语法更灵活且更高效。

4. extern

extern关键字声明变量名而不定义它。 extern声明不是定义,也不分配存储空间,它说明变量定义在程序的其他地方,变量可以声明多次,但只能定义一次。

extern int i; // declares but not define i

int i;  // declares and define i;

 extern double pi = 3.14  //declare

此时定义了变量,接下来出现的所有定义都将是错误的,但是可以被声明。

如:

extern double pi = 3.14 // ok, definition.

double pi;  // error, redefinition.

extern double pi;  // ok, declares not definition.

extern double pi = 3.14; // error, redefinition.

5. const

const表示常量声明符,因为常量在定义后就不能修改,所以定义时必须初始化!

const std:string str = “aaa”; // ok.

const int i, j = 0;  // error, i is uninitialized const.

const对象默认为文件的局部变量。要使const变量能够在其他文件中访问,必须显示指定为extern. const变量默认为extern

eg: // file_1.cpp

extern const double pi = 3.14.

// file_2.cpp

extern const double pi; //ok

6. 引用

引用(reference)就是对象的另一个名字。引用主要用于函数传参(p52). 引用必须用与该引用同类型的对象初始化。

int ival = 1024;

int &refval = ival; //ok

int &refval; //error, must initialized

int &refval = 1024; //error, initializer must be an object

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

int val = 23;

refval=&val; //error, refval实际上就是ivalint型), 而&val则是取地址,是(int *)型。

refval=val; // ok, 实际上是将val的值赋给ival(引用是个别名!)

 const引用:指向const对象的引用。

const int ival = 1024;

const int &refval = ival; //ok

int &ref2 = ival; // error, nonconst reference to a const object.

因为是const 对象的引用,所有不能修改通过refval来修改ival的值,只能读取其值。将一个非const的引用指向一个const 对象是非法的。

 对于const引用,下面的赋值时合法的:

int i = 42;

const int &r = 42; //ok

const int &r2 = r+1; // ok

 const引用只能绑定到与该引用同类型的对象。const引用则可以绑定到不同但相关的类型的对象或绑定到右值。

double d = 2.5;

const double &r = d;

此时rconst引用,因而r只是只读的,不能通过r来修改d的值。

r++; // error

7 typedef

typedef可以用来定义类型的同义词,常被用于以下三种目的:

1. 为了隐藏特定类型的实现,强调使用类型的目的。

2. 简化复杂类型的定义,使其更易理解。

3. 允许一种类型用于多

4. 个目的,同时使得每次使用该类型的目的明确。

typedef double d;

typedef map<stringstring>task;

8 预处理器proprocess

1. 避免头文件的多重包含

#ifndef FILENAME_H

#define FILENAME_H

// definition of you head file content.

#endif

2. 使用自定义的头文件

#include<iostream>

#include "task.h"

使用<>表示包含的是标准头文件,编译器会在预定的位置来查找,参见查找路径变量及命令行选项来修改。” ”表示自定义的头文件,通常是查找开始于源文件所在的目录。