您的位置:首页 > 编程语言 > C语言/C++

数组和指针的区别和联系

2018-01-30 20:13 323 查看
科普开始。本篇主要内存是引述C99标准文档,解析C语言中数组和指针的主要误区。

数组和指针的基础概念

数组是指针是这样的说法活跃于各种大小C语言论坛。误导了无数新人。本篇旨在阐明数组不是指针。之所以会有数组是指针这样的误解。根源在于对C语言类型系统的不了解。C语言的类型系统似乎内容不多很好理解。其实是C语言中内容最多最琐碎最麻烦的一部分。类型系统的麻烦是题外话暂略。回归主题,在C语言中数组和指针其实是两种不同的派生类型。

ISO/IEC 9899:1999 (E)
6.2.5 Types
21
Arithmetic types and pointer types are collectively called scalar types.
算术类型和指针类型统称为标量类型
Array and structure types are collectively called aggregate types.
数组和结构类型统称为聚合类型。

这是数组和指针,最根本的区别。所有认为数组是指针的说法,都是没搞清楚这句话。从这一点延伸上去,能看到数组和指针的很多差异。比如:强制类型转换。强制类型转换的语法要求(纯量类型或者void)纯量类型表达式。纯量类型就是前面所说的算术类型和指针类型(吐槽:我打赌很多人不知道强制类型转换要求这么多)

(double)0
(int*)0

这样的表达式都是没问题的。但数组不是纯量类型,上面所说数组是聚合类型。所以

(int[10])0

这个表达式是语法错误。指针和数组的区别暂时说这么多,有必要再补充。

数组和指针的联系

很多人会误会数组就是指针,是C里面一个规定导致的。

6.3.2 Other operands
6.3.2.1
Lvalues, arrays, and function designators
3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.
除了,作为一元&运算符的操作数、作为sizeof的操作数和用于初始化数组的字符串字面量;这三种情况之外,一个数组类型的表达式会转换为一个指针类型的表达式 (指向数组第一个元素 并且转换结果不是左值)。

这段话是什么意思?
int arr[10];
arr[0] = 100;

这里arr 不属于上面三种情况,所以arr 隐式转换为指向arr[0]的指针。所有误会,数组是指针都是基于这种情况。没搞清楚里面的类型转换,以为数组和指针的行为是一样的。甚至到误以为数组指针是一个二级指针。这就太离谱了。
int arr[10];
int (*p)[10] = &arr;

*p 得到是一个完整的 int[10] 类型的数组。不是什么地址,不是指针。*p的行为会和int[10]的行为一样。

//int[10]不能++
++arr;
//这样做是错的
//*p的行为和int[10]一样
++*p;
//也是错误的

吐槽完毕,终结一下:

数组是一种派生类型
指针是另一种派生类型
数组在某些时候会隐式转换为指向数组第一个元素的指针
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息