今天看到一个小小的算法,交换两个数却不引入中间变量,想了下没什么思路。看了答案是这样:
int a, b;
a = a + b;
b = a - b;
a = a - b;
感觉还是挺有想法的,借此也引起我对语言的重新审视。考虑到年后去学校应该要参加招聘,可能要对以前所学进行全面的复习。当然第一步就是对编程语言的了解,简单翻了下《C++ Primer》(4th Edition)(手头只有这版的,只是用作复习),看到一些边边角角的语言特性都忘得差不多了。打算最近重新看一遍,把一些拾漏补缺的东西分享到这里来。所以接下来的一些列博客可能主要会是一些语言方面的特性。
这一系列的博客命名为《C++拾遗》,并非完整的C++内容,只要是看到书上的已经忘了的内容,可能会涉及一些细枝末节的东西。不会面面俱到,主要以Tips的形式写作。至于顺序,就按照第四版书上,按照基本语言,容器和算法,类和数据抽象,面向对象和泛型,高级主题几部分进行。
本文为本系列博文第一篇,介绍C++语言中的变量和基本类型。
基本内置类型
- 字符类型有两种:char和wchar_t。前者的类型通常是单个机器字节(Byte),后者则用于扩展字符集,比如汉字和日文,即某些不能用单个char表示的字符。
- 关于整型的赋值:对象的类型决定对象的取值。当我们试图把一个超出其取值范围的值赋给一个指定类型的对象时,结果会如何?答案是取决于这种类型是signed还是unsigned。对于unsigned类型,编译器必须调整越界值使其满足要求,即对其取值求模,然后取所得值。例如,试图将336存储到8位的unsigned char中,则实际赋值为80.在C++中,把负数赋给unsigned char完全是合法的(有些语言中是非法的。注意到,unsigned char类型对象不为负数)。仍然是求模,例如,把-1赋给8位的unsigned char,结果是255。而对于signed类型,则由编译器决定,当然也可能按照上述方法。
字面值常量
- 通常使用decimal(20),octal(024),hexadecimal(0x14)表示。
- 字符串字面值和宽字符串字面值不能直接相连。即,连接不同类型的行为标准没有定义。程序不应该依赖未定义行为,即使程序能运行。同样的,通常程序不应该依赖机器相关的行为,否则我们称之为不可移植(nonportable)。
变量
- C++作为强静态类型语言,在编译时会作类型检查,编译器必须能识别程序中每个实体的类型。
- 对象是内存中具有类型的区域,无论是内置类型或类类型,无论是可读的或可写的。具体而言,计算左值表达式就会产生对象。
- C++支持两种初始化变量的形式:复制初始化和直接初始化。如下:
int ival(); //direct-initialization
int ival = ; //copy-initialization
注意,初始化不是赋值。初始化指创建变量并给它赋初始值;而赋值则是擦除当前值并用新值代替(关于这点见后续博文)。
- 内置类型变量是否自动初始化取决于变量定义的位置。在函数体外定义的变量都初始化成0,在函数体内定义的内置类型变量不进行自动初始化。
- 关于声明(declaration)和定义(definition)。定义用于为变量分配存储空间,指定初值。变量有且仅有一个定义。声明用于向程序表明变量的类型和名字。定义也是声明。可以通过extern关键字声明变量名而不定义它。声明可以多次。如果声明有初始化式,它可以被当作定义,即使有extern。
const限定符
- 因为const常量定以后不能被修改,所以定义时必须被初始化。
- 与其他变量不同,在全局作用域声明的const变量是定义该对象的文件的局部变量,不能被其他文件访问。通过指定const变量为extern,就可以在整个程序中访问。
//file_1.cc
extern const int bufSize = fcn();
//file_2.cc
extern const int bufSize;
//uses bufSize defined in file_1即,非const变量默认为extern,要是const变量能在其他文件中访问,必须显式指定它为extern。