Bjarne Stroustrup的经典大作:《C++程序设计语言(特别版)》阅读笔记(2)

  第5章 指针、数组和结构
   
   1. 。由于各种标准转换,0可以被用作任意整型、浮点类型、指针、还有指向成员的指针的常量。0的类型将由上下文确定。在典型情况下0被表示为一个适当大小的全零二进制位的模式(但也不必如此)。...... 在C中流行的是用一个NULL表示0指针。由于C++收紧的类型检查规则,采用普通的0而不是一些人建议的NULL宏,带来的问题会更少一些。如果你感到必须定义NULL,请采用
     const  int  NULL=0;
用const限定词是为防止无意地重新定义NULL,并保证NULL可以用到那些要求常量的地方。

   2. 字符串文字量。可以用字符串文字量给一个char*赋值。允许这样做是因为在C和C++原来的定义里,字符串文字量的类型就是char*。允许将字符串文字量赋值给char*保证了成百万行的C和C++程序继续为合法程序。但试图通过这样的指针去修改字符串文字量将是一个错误:
void f()
{
char* p="Plato";
p[4]='o';        //错误:给常量赋值;结果无定义
}
.......
     如果我们希望一个字符串保证能够被修改,那么就必须将有关的字符复制到数组里:
void f()
{
char p[]="Plato";
p[4]='o';       //可以
}

   3. 数组。数组不具有自描述性,因为并不保证与数组一起保存着这个数组的元素个数。这就意味着,如果要遍历一个数组,而该数组并不像字符串那样包含一个结束符,我们就必须以某种方式提供它的元素个数。......请注意,大多数C++实现都不提供对数组范围的检查。这种数组的概念从本质上就是非常低级的,更高级的数组概念可以通过类的方式提供。

   4. 指针和常量。将一个指针的声明用const“预先固定”将使那个对象而不是使这个指针称为常量。要将指针本身而不是被指对象声明为常量,我们必须使用声明运算符*const ,而不能只用简单的const 。.... 定义常量指针的声明运算符是*const . 并没有const* 声明符,所以出现在*之前的const是作为基础类型的一部分。
     ......
     一个某时通过指针访问当做常量的对象,也完全可能在以其他方式访问时被作为变量。对于函数参数而言,这个情况就特别有用。通过将指针参数声明为const ,就禁止了这个函数对被指参数的修改。如,
char* strcpy(char p, const char* q);  //不能修改*q
你可以将一个变量的地址赋给一个到常量的指针,因为这么做不会造成任何伤害。当然,不能将常量的地址赋给一个未加限制的指针,因为这样会允许修改该对象的值了。例如,
void f4()
{
int a=1;
const int c=2;
const int *p1=&c;    //ok
const int *p2=&a;    //ok
int* p3=&c;        //错误:用const int*对int*进行初始化
*p3=7;            //试图修改c的值
}

   5. 引用。当引用的初始式是一个左值时(是一个对象,你可以取得它的地址),其初始化就是非常简单的事情。对“普通”T&的初始式必须是一个类型T的左值。
     对一个const T& 的初始式不必是一个左值,甚至可以不是类型T的;在这种情况下:
     [1].首先,如果需要将应用到T得隐式类型转换。
     [2].而后将结果存入一个类型T的临时变量。
     [3].最后,将此临时变量用做初始式的值。
考虑
     double& dr=1;        //错误:要求左值
     const double& cdr=1;    //ok
对后一个初始化的解释是
     double temp=double(1);    //首先建立一个具有正确值的临时变量
     const double& cdr=temp;    //而后用这个临时变量作为cdr的初始式
这种保存引用初始式的临时变量将一直存在,直到这个引用的作用域结束。
      需要区分对变量的引用和对常量的引用,是因为在变量引用的情况下引进临时量极易出错,对变量的赋值将会变成对于——即将消失的——临时量的赋值。对于常量引用则不会有这类问题,以常量的引用作为函数参数经常是很重要的。

   6. void指针。 一个指向任何对象类型的指针都可以赋值给类型为void*的变量,void*可以赋值给另一个void*,两个void*可以比较相等与否,而且可以显式地将void*转换到另一个类型。...... Void*的最重要用途是需要向函数传递一个指针,而又不能对对象的类型做任何假设。还有就是从函数返回一个无类型的对象。要使用这样的对象,必须通过显式的类型转换。 .....采用void*的函数通常存在于系统中很低的层次里,在那里需要操作某些真实的硬件资源。.....在系统中较高层次上出现void*应该认为是可疑的,它们就像是设计错误的指示器。

你可能感兴趣的:(程序设计)