1、ex4_22:
const char *cp = "hello";
int cnt;
while (cp) { ++cnt; ++cp; }
while (*cp) { ++cnt; ++cp; }
解释两个循环的不同
我的理解是第一个循环是判断cp指针是否为空作为循环条件的,而++cp的操作并不会让cp为空,所以循环会持续进行,直到出错(也许会是个大错误,因为都不知道会访问到内存的何处)。第二个循环是判断*cp这个字符是否为空,而随着++cp的操作,cp最终会指向"\0"而结束循环。(PS:Lippman出的题也有点小bug,整数没有初始化)
2、电子书中的一处错误:
Section 4.3中的Initializing a Dynamically Allocated Array的一个例子:
int *pia2 = new int[10] (); // array of 10 uninitialized ints
注释应该是// array of 10 initialized ints
3、常数动态分配数组必须被初始化:
const int *pci_ok = new const int[100]();
但是感觉由于必须初始化,而初始化后却又改变不了其数值,没有什么实际用途。
4、int* p = new int[n];使用这样的方式可以得到一个在运行时得到数组range的动态数组,n可以为0,但是我们并不能直接声明一个range为0的静态数组,同时,这样的动态数组指针p不能被解引用(dereference),p为一个合法的、非零指针
5、就如effective c++中所说的,有new就必须有delete,用delete [] pia;的方式来收拾动态数组占用的内存。如果没有[],编译不会出错,但是,会在运行的时候,程序可能崩溃,同时造成了内存泄露。
6、 int dimension = strlen(errorTxt) + 1;
char *errMsg = new char[dimension];
不要忘记,strlen返回的是字符串不包括"\0"的长度,而动态分配空间的时候,必须考虑进去,所以要+1
7、一般情况来说,string的效率要比C-style的string高,所以,作者推荐,如果不为兼容性考虑,首选string
8、处于兼容c的考虑,c++很容易将C-style的字符串转为string,但是直接反向转换就不可,可以通过这种方式:
const char *str = st2.c_str();
注意一点,const,c_str()返回的是const,所以这样得到的只能读,不能改变。如果要很好的使用,最好将返回的const字符串拷贝一份再使用
9、可以使用数组来初始化一个vector:
const size_t arr_size = 6;
int int_arr[arr_size] = {0, 1, 2, 3, 4, 5};
// ivec has 6 elements: each a copy of the corresponding element in int_arr
vector<int> ivec(int_arr, int_arr + arr_size);
要注意的是,这里的构造函数两个参数都是指针,在上面的例子中,分别指向数组的第一个元素以及最后一个元素。但是范围是第一个指针指向的元素以及第二个指针指向的元素的前一个元素。(共六个)
vector<int> ivec(int_arr + 1, int_arr + 4);
则表示使用数组的第二个元素到第五个元素的前一个对vector进行初始化。(总共三个元素)
10、
int *ip[4]; // array of pointers to int
有四个元素的指针数组,指向int
int (*ip)[4]; // pointer to an array of 4 ints
指向一个4个元素的int数组的指针
so confuse...
11、
typedef int int_array[4];
int_array *ip = ia;
使用typedef可以增加可读性,不过对typedef了解不多,形式有点怪怪的。总觉得这样才对:
typedef int[4] int_array;(纯属我的想法,错误的!)
第四章结束(要加油了,太慢了)
---end--- next: Chapter 5 Expression time:05-9-25 1:12am