娓娓道来c指针 (3)指针和数组
来源:互联网 发布:sql调用存储过程 参数 编辑:程序博客网 时间:2024/05/02 04:36
(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;
- }
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)的含义是没有意义的,它只是为了让人看着舒服,用着方便。这是语法糖:
p[i]是*(p+i)的简单写法,实际上,至少对于编译器来说,[]这样的运算符完全可以不存在。
可是对于人类来说,*(p+i)的写法在解读上比较困难,写起来也麻烦(键入量大)。因此,c语言引入[]运算符。
就像这样,这些仅仅是为了让人类容易理解而引入的功能,的确可以让我们感受到编程语言的甜蜜味道(容易着手),有时我们称这些功能为语法糖(syntax sugar 或者 syntactic sugar)。
以上摘自《征服c指针》,借此推荐这本书。书中一针见血地指出:只有在声明语句中,[]才表达数组的含义,在表达式中,[]与数组无关!
总结起来就是,看似数组的用法:p[i],其实是*(p+i)的语法糖,p仍然是指针,与数组并无关系。
指针和数组的不同之处,还可以从下面的例子看出
- void fun(int array[5])
- {
- 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;
- }
void fun(int array[5]){ 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……),而数组是聚合类型。
- 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(” %d[p]…%d\n”, i, i[p]);
- return 0;
- }
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(" %d[p]...%d\n", i, i[p]); return 0;}运行
- 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;
- }
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;}运行
那么为什么int(*)[2]表示的是数组指针呢?这需要透彻理解c的声明语法。又比如,二维数组(更甚者,多维数组)的数组名又是什么类型的指针呢?这需要了解c中数组的实际含义,后序讲解。
更多指针和数组的内容见(5)c数组本质。
专栏目录:
- C指针
- 数据结构与算法
</div>
- 娓娓道来c指针 (3)指针和数组
- 娓娓道来c指针 (3)指针和数组
- 娓娓道来c指针 (5)c数组本质
- 娓娓道来c指针 (1)指针就是地址
- 娓娓道来c指针 (7)指针运算
- 娓娓道来c指针 (1)指针就是地址
- 娓娓道来c指针 (2)内存分配
- 娓娓道来c指针 (6)const的使用
- 娓娓道来c指针 (0)c语言的梦魇:c指针
- 【c/c++】指针数组和数组指针
- 娓娓道来c指针 (4)解析c的声明语句
- 娓娓道来c指针 (4)解析c的声明语句
- c++---数组和指针
- C 指针和数组
- C -- 数组和指针
- C++:数组和指针
- C 指针和数组
- C:数组和指针
- matlab常用函数
- IDEA下SSH项目的配置(一)-配置strut2
- andriod 资源大全
- win10下安装Ubuntu遇到的一些问题
- 微信小程序 网络请求之设置合法域名
- 娓娓道来c指针 (3)指针和数组
- 1129: 第几天
- elasticsearch-doc_value和fieldata
- 第13周项目1-(2)验证分块查找算法
- 1130: 杨辉三角
- 2>/dev/null和>/dev/null 2>&1和2>&1>/dev/null
- android 检测手机号格式
- HDU
- 1131: 最常用字符