sizeof操作符
如果我们希望在数组列表中动态添加新的字符串,sizeof操作符可以帮助我们。
sizeof操作符产生size_t类型的整数值,给出其操作数占用的字节数量,其中size_t是由标准库定义的类型。
int dice(0); cout << sizeof dice; //输出值为4,因为dice被声明为int类型,所以要占用4个字节 char* pstr[] = {"Hello", "World!"}; cout<<(sizeof pstr)<<endl; //输出值为8,sizeof应用于数组名称本身时,将产生整个数组占用的字节数量,但不能获得任何文本字符串的内存占用情况 cout<<(sizeof pstr[0])<<endl; //输出值为4,pstr[0]是一个指向字符数组的指针,因此只占用4个字节 cout<<(sizeof pstr)/(sizeof pstr[0])<<endl; //输出值为2
常量指针和指向常量的指针
区分以下三种与const、、指针即指针指向的对象有关的情形::
- 指向常量对象的指针
- 指向某个对象的常量指针
- 指向常量对象的常量指针
在第一种情况中,我们不能修改被指向的常量对象,但可以使指针指向其他对象:
const char* pstring("Some text");
在第二种情况中,我们不能修改指针中存储的地址,但可以修改指针指向的对象:
char* const pstring("Some text");
在第三种情况中,指针和被指向的对象都被定义为常量,因此都不能被修改:
const char* const pstring("Some text");
当然,这三种情况适用于指向所有类型的指针。一般来说,为了正确解释更复杂的类型,只需要从右向左读它们。例如,类型const char*是一个指向字符的指针,且这些字符是const。类型char* const是一个const指针,且指针指向字符。
指针和数组
我们可以用指针执行算术操作。在算术方面,我们仅限于加、减运算,但还可以比较指针值,从而产生逻辑结果。指针算术隐式地认为指针指向某个数组,而算术运算是在指针包含的地址上进行的。
double* pdata(nullptr); double data[5]; pdata = &data[2];
pdata + 1将是数组data中第四个元素data[3]的地址,因此可以通过以下语句使指针pdata指向元素data[3]:
pdata += 1;
指针算术运算产生的地址范围可以从数组第一个元素的地址到最后一个元素之后的第一个地址,如果超出这个范围,则指针的行为是不确定的。
当处理数组元素时,可以像使用指针一样使用数组名称,但是不能与使用指针一样使用数组名。表达式data++绝对是非法的,因为不能修改数组名表示的地址。
long data[5]; //可以将元素data[3]写成 *(data + 2),这种符号是普遍存在的
使用指针处理多维数组相对复杂一点,多维数组的指针形式如下:
double beans[3][4]; double* pbeans; pbeans=&beans[0][0]; //将指针设置为数组中第一个元素的地址,元素的类型是double pbeans=beans[0]; // 将指针设置为数组中第一行的地址 beans[i][j] //使用带两个索引值的数组名 *(*(beans + i) + j) //使用指针形式的数组名