本帖最后由 打滚的橘子 于 2015-12-1 23:39 编辑
老早想要说说指针和数组,拖延症一犯就拖了好久。以下主要讲易混淆的地方,各人理解方式不同,希望能帮到部分同学。单纯的指针和数组应该没什么不懂的,比较容易混淆的是指针数组、数组指针,也许还有个字符串指针。
- 字符串指针 char *y = "abc"; 这个很简单,其实就是个简单的指针,指向字符串而已。
- 指针数组 跟我念3遍:这是一个数组!这是一个数组!这是一个数组!其元素是指针。
- char a = 'z', b = 'x'; //定义2个char型变量a和b
- char *p1 = &a, *p2 = &b; //定义2个指针,分别指向变量a和b
- char *p[2] = {p1,p2}; //定义一个指针数组p,此时p有2个元素,且元素赋了初值。p[0] = p1,p[1] = p2
复制代码- 数组指针 跟我念3遍:这是一个指针!这是一个指针!这是一个指针!
- char h[3] = {'e','o'}; // 定义一个一维数组
- char (*ch)[3] = &h; //定义一个数组指针,它指向的是有3个元素的一维数组。现在指向h。
复制代码 现在我们有:
1、字符串指针y 一个普通的指针。
2、指针数组p[2] 一个一维数组,里面存放2个元素,元素必须是指针。
3、数组指针ch。 一个指针,指向一个一维数组。ch+1指向的地址是这个一维数组末尾地址的后一位,也就是说,每次移动ch,它就移动一个数组那么长,所以又称行指针。把它称为行指针可以和指针数组分的清一点。
清楚了吗?一般般清楚就不用看下面的的了,非常清楚就接着看。
以下看看,不要纠结,继续往后看。- char ah[2][3] = {"ke","pg"},*p3 = "well", *p4 ="bad";
- p[0] = p3; p[1] = p4; p3 = y;
- p[0] = ch; p[1] = ah; p1 = ah; p2 = ch; p3 = p[0];
- p4 = p; ch = p;
- *p = ah;
复制代码 上面的赋值语句都能编译通过,但是除了第1、2行是完全正确的,其他都不妥,大部分会出警告。而不管出不出警告,有些得不到值有些能得到值,得到值的有些也不是想要的值。感觉很乱是不是?咱往底层走就能清楚了。
首先,上面代码块里的项都是表示地址,无论是二维一维,无论是指针还是数组名,他们的值都是地址。除了p和ah是地址常量(数组名,但是可赋值给*p却不能赋给*ah,因为*p之后是个指针,*ah之后还是个数组),其他都是指针变量。既然是指针变量,理论上是可以给它同类型的任何地址,管他是一维二维还是一级多级,这也是为什么上面那一堆可以运行。出警告的大部分是因为维度或者级数的不对等,有时候级数对等但是写法不规范,也不会出警告。比如p[0]=*ah;这里是因为ah里存得是数组首地址,*ah相当于ah[0],p[0]是一个一级指针,ah[0]可看作一个一维数组,它们等级一样。此时p[0]变为了数组ah的一个行指针。只要分清变量存的是哪个地址,基本上可以在指针变量之间随心所欲的赋值,不用数维度级数什么的。但是这样不规范的写法还是要杜绝,而且以后写复杂程序的时候可能会出错,或者出错找不到地方。
数组指针(行指针)是指针的一个细分,它专门用来指向数组,被指向的数组长度由用户定义后就是固定长度了。
而指针数组相当的灵活,这个数组里的每一个元素是个指针,而指针指向的长度可以是任意的,甚至可以是个数组或者结构体(结构体我没试,应该可以)。
数组指针(行指针)、指针数组与二维数组的关系
- 数组指针(行指针)可以构成二维数组的一个行指针,可通过加减正整数移动行指针来访问二维数组不同的行,通过*取值之后再加减正整数来访问每一 个元素。
- 指针数组可以构成一个二维数组(可以是每行列数不相等的二维数组)。此时指针数组里的元素是二维数组的行指针。指针数组还可以包含二维数组,让指针数组的元素指向一个二维数组即可,但是这时候要访问这个二维数组的元素就比较困难了,而且指针数组的元素和二维数组级数上不对等,会出警告,尽量不要这样写。
这个写了好久,写的时候差点把自己给绕晕了,虽然可以很灵活的用指针,但是还是要用规范的写法,也只要记住规范的写法就好了。
|
|