指针、数组、字符串是C/C++语言中重要的组成部分,很多人认为指针比较难理解,而初学者更容易在这里犯错误,其实当你真正理解其本质后,也就不难了。
首先来看一些错误用法的示范:
// 错误示范1 - 尝试修改只读区域
char *p1 = "This is a constant string, it's read only.";
p1[3] = 'x';
// 错误示范2 - 把一个字符串赋给数组名
char str1[32];
str1 = "something funny";
// 错误示范3 - 把字符串直接赋给一个new分配的指针
char *p2 = new char[32];
p2 = "hello, world";
std::cout << p2 << std::endl;
delete[] p2;
错误示范一中把一个字符串赋给一个指针,字符串是存储在只读数据区,是不能被修改的。错误示范二中不能把一个字符串赋给数组名,因为数组名本身是一个const指针,而应用strcpy。错误示范三是很多初学者容易犯的错误,这是想当然的做法,对p2指针赋字符串应用strcpy,不能直接赋值,直接赋值等于把之前的指针值覆盖掉了,等下delete的时候就会出问题。
再来看两个新鲜的用法:
std::cout << "abcde"[2] << std::endl;
std::cout << 3["abcde"] << std::endl;
以上两种表述都是合法的,你没有接触过很正常,因为谁也不会写那样的代码。这两句话运行后输出字符c和d,想要理解这里的语法必须要理解数组的本质。
我们知道数组的一般定义是:
type name[index];
实际上也可理解为这样:
type index[name];
编译器对它的理解都是*(name + index),也就是不管怎么写它都把它转成指针,知道了这个后那两句话就不难理解了。
这里对指针、数组、字符串作一个总结性的描述:
1)指针就是一个变量,里面存储一个地址,指针本身需要占存储空间,所以其本身也拥有地址,指针变量本身的地址是不变的,但该变量里面存储的值可以改变,不要将指针本身的地址和它里面存储的地址混淆。访问指针所指向的内容之前必须确保其指向了有效位置。
2)数组就是一段存储有N个相同类型数据的连续内存, 数据类型可以为任意。
3)字符串的本质是一段以0结束的连续内存,在操作字符串时必须小心0的位置。