设为首页 加入收藏

TOP

娓娓道来c指针 (3)指针和数组
2015-01-22 20:58:13 来源: 作者: 【 】 浏览:15
Tags:娓娓道来 指针

(3)指针和数组

在c中指针和数组似乎有着千丝万缕的关系。其实它们不是一回事:指针是指针,数组是数组,两者不相同。

说它们有关系,不过是因为常见这样的代码:

int main()
{
	int array[] = {1,2,3,4,5};
	int n = sizeof(array) / sizeof(int);
	int *p = array;
	int i;
	for (i = 0; i < n; i++)
		printf("p[%d]...%d\n", i, p[i]);
	system("pause");
	return 0;
}
运行

\

在上面的代码中,指针和下标运算符的结合使用,给人一种指针和数组一样的感觉。

本质是:数组名是一个指向数组起始元素的常量指针。这也是数组和指针的唯一联系!

之所以可以使用 p[i] 来访问数组中的元素,是因为在编译器中 p[i] 被解释为 *(p+i),这仍然是指针的功能。对编译器而言,用p[i]表达*(p+i)的含义是没有意义的,它只是为了让人看着舒服,用着方便。这是语法糖<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPqO6PC9wPgo8cD4gICAgcFtpXcrHKihwJiM0MztpKbXEvPK1pdC0t6ijrMq1vMrJz6Os1sHJ2bbU09qx4NLrxvfAtMu1o6xbXdXi0fm1xNTLy+O3+83qyKu/ydLUsru05tTaoaM8L3A+CjxwPiAgICC/ycrHttTT2sjLwODAtMu1o6wqKHAmIzQzO2kptcTQtLeo1Nq94rbByc+xyL3PwKfE0aOs0LTG8MC00rLC6bezKLz8yOvBv7TzKaGj0vK0y6OsY9Pv0dTS/cjrW13Uy8vjt/uhozwvcD4KPHA+ICAgIL7Nz/HV4tH5o6zV4tCpvfa99srHzqrBy8jDyMvA4Mjd0tfA7b3itvjS/cjrtcS5psTco6y1xMi3v8nS1MjDztLDx7jQyty1vbHgs8zT79HUtcTM8MPbzra1wCjI3dLX18XK1imjrNPQyrHO0sPHs8bV4tCpuabE3M6q0++3qMzHKHN5bnRheCBzdWdhciC78tXfIHN5bnRhY3RpYyBzdWdhcimhozwvcD4KPHA+0tTJz9Wq19ShttX3t/5j1rjV66G3o6y96LTLzca89tXisb7K6aGjyunW0NK71eu8+9GqtdjWuLP2o7rWu9PQ1NrJ+cP30+++5NbQo6xbXbLFse2078r91+m1xLqs0uWjrNTase2078q91tCjrFtd0+vK/dfpzt652KOhPC9wPgo8cD7X3L3hxvDAtL7NysejrL+0JiMyMDI4NDvK/dfptcTTw7eoo7pwW2ldo6zG5Mq1yscqKHAmIzQzO2kptcTT77eozMejrHDI1Mi7ysfWuNXro6zT68r91+myos7eudjPtaGjPC9wPgo8cD48YnI+CjwvcD4KPHA+1rjV67rNyv3X6bXEsrvNrNautKajrLu5v8nS1LTTz8LD5rXEwP3X07+0s/Y8L3A+CjxwPjwvcD4KPHByZSBjbGFzcz0="brush:java;">void fun(int *array) { printf(" sizeof(array)...%d\n", sizeof(array)); } int main() { int array[] = { 1, 2, 3, 4, 5 }; printf(" sizeof(array)...%d\n", sizeof(array)); fun(array); return 0; }运行

\

从运行结果看,指针和数组确实不同。这揭示了c语言中传递数组时的规则:传递过去的是地址,是指向数组起始元素的地址。之所以这样,基于两点;

从效率上考虑,若是把整个数组赋值过去,太耗时,也耗空间。还不如传地址过去,使用同一份内容。在c语言设计之初,赋值操作就仅限于基本类型(char、int、float……),而数组是聚合类型。 这给我们的编程启示是:传递数组时,不要忘了把数组大小也传递过去。否则,函数那边由于不知道数组大小,极易越界。应这样设计函数 void fun(int *array, int n),n是数组大小。 还有一点需要指出,即使函数被设计成void fun(int array[], int),array依然被看成是指针。也就是说即使数组带了长度,如 int array[5],该长度也会被编译器忽略掉。一句话:形参中的数组统统看成指针。
总结:只有在函数形参中,仅有这一种情况,声明的数组,如 int array[]会被看作是指针。其它情况下,指针与数组并无联系。
还有一点,对于 int array[5];array表示指向数组起始元素的指针,那么&array又是什么呢?实验下:
int main()
{
	int array[] = { 1, 2};
	printf("   array...%p\n", array);
	printf("  &array...%p\n", &array);
	printf("&array+1...%p\n", &array+1);
	return 0;
}
运行
分析实验结果:0031FCEC与0031FCE4相差8,而sizeof(array)就是8。 结论就是:array和&array都是指针,但类型不同。array的类型是int*,而&array的类型是int(*)[2]。array是指向普通int类型的指针;&array是数组指针,该数组元素是int类型的,且数组大小是2。 至于array和&array两者的值是一样的,应该很好理解。

那么为什么int(*)[2]表示的是数组指针呢?这需要透彻理解c的声明语法,后序讲解。





】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C和指针 (pointers on C)――第.. 下一篇C语言进行网站开发之cgi

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: