七、关于c++的复合类型(五)

指针、数组和指针算术

1.指针和数组基本等价的原因在于指针算术和C++内部处理数组的方式

2.C++将数组名解释为地址,而第六时候说过指针变量也是一个地址

在前面讲过int *a = new int [10];,指针指向new分配的内存地址,而数组不是new出来,它有自己的标识(数组名),数组名也被解释为第一个元素的地址。所以可以这样使用指针和数组

int a[3] = {0,1,2};

int *b = a; //由于数组名表示地址,指针指向地址,没问题,而这一句等价于 int *b = &a[0];

然后访问数组元素就由原来的数组访问a[0],a[1],a[2]可以对应有*b,*(b+1),*(b+2)

而需要注意的是

sizeof(a); //12,a是数组名,所有求的是整个数组的大小

sizeof(b);//4,指针的大小,指针本质是地址,四字节

再举个例子说明指针地址+1

假如指针b的地址是2000(当然正常是十六进制,这里为了方便举例),b在上面我们知道是指向int数组,int四个字节,b+1指向的地址就是2004,b+2指向的地址就是2008

3.数组的地址

数组名解释为地址并不是所有情况,如果你对数组名应用地址运算符&时,它就不是解释为地址,而真的只是一个标识。

int a[10];

cout<<a<<endl; //数组第一个元素的地址

cout<<&a<<endl;//数组第一个元素的地址

这两个输出值是一样的,但是意义确是不一样,a上面有说过相当于第一个元素的地址,相当于&a[0],是一块4字节内存的地址,而&a是表示整个数组的地址,在这是一块40字节内存的地址,要体现出区别可以将他们分别+1

cout<<a+1<<endl; //地址值较a加了4

cout<<&a+1<<endl; //地址值较&a加了40

a看做指针的话,是一个int指针(int*),而&a是这样一个指针,指向包含10个元素的int数组(int (*)[10])

其实我们也碰过这样的问题,数组名不一定会作为地址,如sizeof(数组名)返回整个数组的长度

4.指针与字符串

4.1将数组和指针的关系扩展到C-风格字符串

char a[10] = "Hello";

cout<<a<<endl;

cout<<"Hello Word"<<endl;

数组名是第一个元素的地址,所以cout语句中的a是字符'H'的地址,然后继续打印后面的字符,知道碰见'\0'结束。

要知道:如果给cout提供一个字符的地址,那么cout将从这个字符开始打印,直到碰见空字符为止。

而打印字符串常量,在C++中,字符串常量其实也是一个地址,是第一个字符的地址。在打印的时候,并没有把整个字符串发送给cout,只是发送第一个字符的地址,如果cout就会一个个读取,直到碰见空字符为止。

4.2在cout和多数C++表达式中,char数组名、char指针以及用引号括起来的字符串常量被解释为字符串第一个字符的地址

char a = "Hello";

char *a ="Hello";

"Hello"

需要细品的是第二个,a不是char类型,而是char*类型,所以才能指向字符串。

定义一个字符串数组

char a[10][10]={"hello","world",haha"}; //可以用二维数组(还没有讲到)

char *a[10]={"hello","world",haha"};//也可以用char指针数组,每个元素都是一个char指针类型

当然定义字符串数组也可以用string,上面是基于C-风格字符串

string a[10]={"hello","world",haha"};

4.3

char a[] = {"Hello"};

char *p = a;

cout<<a<<endl; //Hello

cout<<p<<endl; //Hello

cout<<(int *)a<<endl; //地址

cout<<(int *)p<<endl; //地址

一般来说给cout提供一个指针,它打印的是地址,但如果是指针类型是char*,则cout将显示指向的字符串,如果要显示字符串的地址,则要对这种指针进行强制转换,如上面int*

int a[] ={1,2,3};

int *p = a;

cout<<p<<endl; //地址

4.4经常要把字符串放到数组中,初始化数组时,请使用=运算符,否则请使用strcpy()或strncpy()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章