C++ Primer 读书笔记 Chapter 4 数组和指针
时间:2010-08-17 来源:KurtWang
- 数组定义和初始化
- 维数:必须为整型字面值常量,枚举常量或者常量表达式初始化的整型const对象。非const变量和直到运行阶段才知道的其值的变量不能作为维数(例如const unsigned sz=get_size(),sz虽然是const,但直到运行时刻才知道值,所以sz不能用作维数)。
- 如果没有显式初始化:
- 在函数体外定义的内置类型数组,元素均被初始化为0;
- 在函数体内定义的内置类型数组,无初始化;
- 不管定义在哪里,类类型都会调用默认构造函数进行初始化,如果没有默认构造函数,则必须为该数组的元素提供显式初始化;
- 字符串字面值包含一个额外的\0,char ca[] = “C++”, ca的维度为4, char ca={‘C’, '+’, '+’ } ca维度为3
- 数组不能直接复制和复制;int ia[] = {0,1,2}; int ia2(ia);(错) int ia3[3]; ia3=ia; (错)
- 指针
- 指针声明语句,从右向左阅读。例:int ip, *ip2; ip为int, ip2为int*
- 指针若为0,则表明它不指向任何对象
- 把int值赋给指针是非法的,但允许把数组0或编译时可获得0值的const量赋给指针。int zero=0; const int c_ival=0; int * pi=zero; (错)pi=c_ival; (对)
- 指针和引用比较:
- 引用总是指向某个对象,引用必须在定义时初始化
- 给引用赋值是修改该引用所关联的对象的值,给指针赋值是更改该指针指向的对象
- 指针的差的类型为ptrdiff_t
- 指针下标:只要指针指向数组元素,就可以对他进行下标操作:int *p=&ia[2]; int k=p[-2]; (k是ia[0])
- C++允许计算数组或对象的超出末端的地址,但不允许对此地址进行解引用。计算超出末端位置之后或数组首地址底之前的地址都是不合法的。
- 指针和Const
- 指向const对象的指针:
- const指针:指针本身不能修改
- C风格字符串,标准库函数 #include <cstring> 或 C风格:#include <string.h>
- strlen(s)
- strcmp(s1, s2)
- strcat(s1, s2)
- strcpy(s1, s2)
- strncat(s1, s2, n)
- strncpy(s1, s2, n)
- 创建动态数组:动态分配的对象放在堆(Heap)中。C中用malloc和free,C++用new和delete
- 如果数组元素具有类类型,将使用该类的默认构造函数实现初始化
- 如果数组元素是内置类型,则不会初始化,在数组长度后加一对空圆括号,对数组元素做初始化
- C++不能定义长度为0的数组变量,但可以new动态创建长度为0的数组
- delete [] pia; 如果遗漏了空方括号,则会导致内存泄露(Memory Leak)
- C和C++代码混用:
- string s; const char * str = s.c_str(); (返回char*) 对s的操作可能会改变str,如果需要持续访问str,则应该复制str。
- int int_arr[5] = {1,2,3,4,5}; vector<int> ivec(int_arr, int_arr+5); vector用数组首地址和数组最后一个元素之后的那个地址来初始化一个vector
- 多维数组
int arr[5]={1,2,3,4,5}; int *p = arr; int *p2 = p+5; //合法 int *p3 = p+6; //不合法
const double pi = 3.14; double * ptr = π //错误 const double * ptr = π //正确 *ptr = 42; //错误 double dval = 3.14 ptr = &dval; //正确,可以将非const对象的地址赋给指向const对象的指针
int num = 0; int num2 = 0; int * const cur = # *cur = 1; //正确 cur = &num2; //错误,const指针,指针本身不能被修改
int strlen(const char *str) { assert(str != NULL); int len = 0; while((*str++) != '\0') len++; return len; }
int strcmp(const char *dest, const char *source) { assert((NULL != dest) && (NULL != source)); while (*dest && *source && (*dest == *source)) { dest ++; source ++; } return *dest - *source; /*如果dest > source,则返回值大于0,如果dest = source,则返回值等于0,如果dest < source ,则返回值小于0。*/ }
char* strcat(char *str1,char *str2) { char* tempt = str1; while(*str1!='\0') { str1++; } while(*str2!='\0') { *str1 = *str2; str1++; str2++; } *str1 = '\0'; return tempt; }
char *strcpy(char *strDestination, const char *strSource) { assert(strDestination && strSource); char *strD=strDestination; while ((*strDestination++=*strSource++)!='\0'); return strD; }
int * pia = new int[10]; //未初始化 int * pia2 = new int[10](); //初始化为0
char arr[0]; //错误 char * cp = new char[0]; //正确
int * ip[4]; //array of pointers to int int (*ip)[4]; //pointer to an array of 4 ints
相关阅读 更多 +