《C++ Primer 3rd edition》读书笔记 - 第二篇 基本语言
2005-06-30 14:46
417 查看
char short int 和long 称为整值类型(integral type), 整值类型可以有符号,也可以无符号。
在有符号类型中,最左边的位是符号位,余下的位代表数值。在无符号类型中,所有的位都表示数值。如果符号位被置为1, 数值被解释成负数,如果是0 ,则为正数。
一个8位有符号的char ,可以代表从-128 到127 的数值。而一个无符号的char, 则表示0 到255 范围内的数值。
在整型文字常量前面加一个0, 该值将被解释成一个八进制数。而在前面加一个0x 或0X,则会使一个整型文字常量被解释成十六进制数。
每种内置数据类型都支持一种特殊的构造函数语法,可将对象初始化为0, 例如:
// 设置ival 为0 dval 为0.0
int ival = int();
double dval = double();
为清楚起见,最好写成 string *ps; 而不是 string* ps;也就是让*和变量名连在一起。
void*表明相关的值是个地址,但该地址的对象类型不知道。我们不能够操作空类型指针所指向的对象,只能传送该地址值,或将它与其他地址值作比较。
一般地,我们用指针的算术运算来遍历C 风格的字符串,每次指针增加1, 直到到达终止空字符为止。例如:while ( *st++ ) { ... }
我们可以将一个C 风格的字符串赋给一个string 对象
string s1;
const char *pc = "a character array";
s1 = pc; // ok
但是反向的转换不能自动执行。为实现这种转换,必须显式地调用名为c_str()的操作(注意c_str()返回的是const char *):
const char *str = s1.c_str(); // ok
引用的所有操作实际上都被应用在它所指的对象身上,包括取地址操作符。例如:
refVal += 2; //将refVal 指向的对象ival 加2
类似地,如下语句
int ii = refVal; //把与 ival 相关联的值赋给 ii 而
int *pi = &refVal; //用ival 的地址初始化pi
const 引用可以用不同类型的对象初始化(只要能从一种类型转换到另一种类型)即可,也可以是不可寻址的值,如文字常量。例如:
double dval = 3.14159;
// 仅对于const 引用才是合法的
const int &ir = 1024;
const int &ir2 = dval;
const double &dr = dval + 1.0;
同样的初始化,对于非const 引用是不合法的,将导致编译错误。
指向 const int 的引用:我们的引用不是指向一个常量,而是指向一个非常量指针,指针指向一个const 对象。正确的定义如下:
const int ival = 1024;
// ok: 这是可以被编译器接受的
const int *const &pi_ref = &ival;
可以将vector 初始化为一个已有数组的全部或一部分,只需指定希望被用来初始化vector 的数组的开始地址,以及数组最末元素的下一位置来实现。例如:
vector< int > ivec( ia, ia+6 ); // 把ia 的6 个元素拷贝到ivec 中
或者:
vector< int > ivec( &ia[ 2 ], &ia[ 5 ] ); // 拷贝3 个元素ia[2], ia[3], ia[4]
下面是一个几乎所有人刚开始时都会答错的问题,错误在于将typedef 当作宏扩展。已知下面的typedef:
typedef char *cstring;
在以下声明中cstr 的类型是什么
extern const cstring cstr;
第一个回答差不多都是
const char *cstr
即指向const 字符的指针,但是这是不正确的。const 修饰cstr 的类型,cstr 是一个指针。因此这个定义声明了cstr 是一个指向字符的const 指针:
char *const cstr;
当sizeof 操作符应用在数组上时,它返回整个数组的字节长度。
应用在指针类型上的sizeof 操作符,返回的是包含该类型地址所需的内存长度。
sizeof 操作符应用在char 类型上时,在所有的C++实现中结果都是1
在 if 语句的 init-statement 中可以定义多个对象,但只能出现一个声明语句。因此,所有对象都必须是相同的类型。例如:
for ( int ival = 0, *pi = &ia, &ri = val; ival< size; ++ival, ++pi, ++ri )
// ...
容器对象也可以用由一对iterator 标记的起始元素和末元素后一位置(也就是说,下述代码的svec.end()不被copy)之间的拷贝来初始化:
vector<string> svec;
// ...
// 用svec 的全部元素初始化svec2
vector<string> svec2( svec.begin(), svec.end() );
除了一对iterator 之外,两个指向内置数组的指针也可以被用作元素范围标记器(range marker)。例如,假设我们有下列string对象的数组
#include <string>
string words[4] = {"stately", "plump", "buck", "mulligan"};
我们可以通过传递数组words的首元素指针和末元素后一位置的指针来初始化string vector
vector< string > vwords( words, words+4 );
第二个指针被用作终止条件,它指向的对象(通常指向容器或者数组中最后一个元素后面的位置上)不包含在要被拷贝或遍历的元素之中。
iterator的+符号,不能用在list中。list中需要next来访问下一个元素
a
在有符号类型中,最左边的位是符号位,余下的位代表数值。在无符号类型中,所有的位都表示数值。如果符号位被置为1, 数值被解释成负数,如果是0 ,则为正数。
一个8位有符号的char ,可以代表从-128 到127 的数值。而一个无符号的char, 则表示0 到255 范围内的数值。
在整型文字常量前面加一个0, 该值将被解释成一个八进制数。而在前面加一个0x 或0X,则会使一个整型文字常量被解释成十六进制数。
每种内置数据类型都支持一种特殊的构造函数语法,可将对象初始化为0, 例如:
// 设置ival 为0 dval 为0.0
int ival = int();
double dval = double();
为清楚起见,最好写成 string *ps; 而不是 string* ps;也就是让*和变量名连在一起。
void*表明相关的值是个地址,但该地址的对象类型不知道。我们不能够操作空类型指针所指向的对象,只能传送该地址值,或将它与其他地址值作比较。
一般地,我们用指针的算术运算来遍历C 风格的字符串,每次指针增加1, 直到到达终止空字符为止。例如:while ( *st++ ) { ... }
我们可以将一个C 风格的字符串赋给一个string 对象
string s1;
const char *pc = "a character array";
s1 = pc; // ok
但是反向的转换不能自动执行。为实现这种转换,必须显式地调用名为c_str()的操作(注意c_str()返回的是const char *):
const char *str = s1.c_str(); // ok
引用的所有操作实际上都被应用在它所指的对象身上,包括取地址操作符。例如:
refVal += 2; //将refVal 指向的对象ival 加2
类似地,如下语句
int ii = refVal; //把与 ival 相关联的值赋给 ii 而
int *pi = &refVal; //用ival 的地址初始化pi
const 引用可以用不同类型的对象初始化(只要能从一种类型转换到另一种类型)即可,也可以是不可寻址的值,如文字常量。例如:
double dval = 3.14159;
// 仅对于const 引用才是合法的
const int &ir = 1024;
const int &ir2 = dval;
const double &dr = dval + 1.0;
同样的初始化,对于非const 引用是不合法的,将导致编译错误。
指向 const int 的引用:我们的引用不是指向一个常量,而是指向一个非常量指针,指针指向一个const 对象。正确的定义如下:
const int ival = 1024;
// ok: 这是可以被编译器接受的
const int *const &pi_ref = &ival;
可以将vector 初始化为一个已有数组的全部或一部分,只需指定希望被用来初始化vector 的数组的开始地址,以及数组最末元素的下一位置来实现。例如:
vector< int > ivec( ia, ia+6 ); // 把ia 的6 个元素拷贝到ivec 中
或者:
vector< int > ivec( &ia[ 2 ], &ia[ 5 ] ); // 拷贝3 个元素ia[2], ia[3], ia[4]
下面是一个几乎所有人刚开始时都会答错的问题,错误在于将typedef 当作宏扩展。已知下面的typedef:
typedef char *cstring;
在以下声明中cstr 的类型是什么
extern const cstring cstr;
第一个回答差不多都是
const char *cstr
即指向const 字符的指针,但是这是不正确的。const 修饰cstr 的类型,cstr 是一个指针。因此这个定义声明了cstr 是一个指向字符的const 指针:
char *const cstr;
当sizeof 操作符应用在数组上时,它返回整个数组的字节长度。
应用在指针类型上的sizeof 操作符,返回的是包含该类型地址所需的内存长度。
sizeof 操作符应用在char 类型上时,在所有的C++实现中结果都是1
在 if 语句的 init-statement 中可以定义多个对象,但只能出现一个声明语句。因此,所有对象都必须是相同的类型。例如:
for ( int ival = 0, *pi = &ia, &ri = val; ival< size; ++ival, ++pi, ++ri )
// ...
容器对象也可以用由一对iterator 标记的起始元素和末元素后一位置(也就是说,下述代码的svec.end()不被copy)之间的拷贝来初始化:
vector<string> svec;
// ...
// 用svec 的全部元素初始化svec2
vector<string> svec2( svec.begin(), svec.end() );
除了一对iterator 之外,两个指向内置数组的指针也可以被用作元素范围标记器(range marker)。例如,假设我们有下列string对象的数组
#include <string>
string words[4] = {"stately", "plump", "buck", "mulligan"};
我们可以通过传递数组words的首元素指针和末元素后一位置的指针来初始化string vector
vector< string > vwords( words, words+4 );
第二个指针被用作终止条件,它指向的对象(通常指向容器或者数组中最后一个元素后面的位置上)不包含在要被拷贝或遍历的元素之中。
iterator的+符号,不能用在list中。list中需要next来访问下一个元素
a
相关文章推荐
- C++ Primer 3rd Edition 读书笔记 [01] 读书计划
- 《C++ Primer 3rd edition》读书笔记 - 第一篇 C++概述
- C++ Primer (3RD) 重读笔记——基本语言
- c++ primer -- 基本语言(6)
- 《C++ Primer》读书笔记-第二章 02 基本内置类型
- 《Professional Javascript For Web Developers 3rd Edition》读书笔记:javascript闭包中的this对象
- 读书笔记:C++ primer 5th edition--chapter13.拷贝控制
- 【C++ Primer】基本语言
- 读书笔记:C++ primer 5th edition--chapter 3.字符串,向量,数组
- C++ Primer 学习笔记(2) : 基本语言2
- C++ Primer 3rd Edition 中文完美版.pdf
- 读书笔记:C++ primer 5th edition--chapter16.模板与泛型编程
- 读书笔记:C++ primer 5th edition--chapter 6.函数
- 读书笔记:C++ primer 5th edition--chapter7.类
- 《C++ Primer》读书笔记(二)-变量和基本类型
- Linux Kernel Development 3rd Edition 读书笔记(4)
- c++ primer -- 基本语言(7)
- 《C++ Primer》---第一部分:基本语言
- 《C++ Primer 4th Edition》读书笔记 - Chapter1 Getting Started
- 《C++ Primer 4th Edition》读书笔记 - Part I: The Basics