说出来你们可能不信,但是数组名确实不是指针常量

这篇是一篇C语言劝退流教学文,看不懂的同学应该是劝退教学流的目标对象

(写完了才想起来注一下,本文提到的“数组”和“数组名”字样,指的是数组左值表达式(array lvalue expression)或数组声明(array declaration)所声明的变量)

首先,数组名不是常量指针,从两方面:

  1. 类型方面,数组的类型是type[size],和常量指针类型type* const不同
  2. 使用方面,sizeof(数组名)等于数组所有元素的大小,而不是sizeof(指针);对数组取地址,得到的指针进行加减,增减字节数是sizeof(数组);你可以用字符串字面量初始化一个字符数组,但是不能用常量指针来初始化一个字符数组。

其次,为什么很多老师都说数组是常量指针

  1. 他们不了解C语言的类型系统和隐式转换规则
  2. 他们怕下面的人听不懂
  3. 他们解释不清为什么数组名不能进行赋值或者++之类的运算而指针可以

切入正题,我们从类型系统和隐式转换规则来讲:

  1. sizeof运算的时候
  2. 取址的时候
  3. 用字符串字面量初始化字符数组的时候
  4. 以及C11的_Alignof运算符(这个本文不考虑)

其他情况下都会发生数组到指针隐式转换,比如你用方括号取值,如果方括号左边是个数组,那么数组会被隐式转换为首元素指针右值,然后对这个值进行的解引用。(参见Member access operators

更进一步,二维数组type[size1][size2],实际上就是元素类型是数组的数组,进行隐式转换后得到的首元素指针类型是type(*)[size2],指向数组的指针,对这个指针加减,得到的也是数组的指针,对它解引用,得到数组。这一套过程,用那个什么数组名是常量指针的说法,是解释不来的。

最后出一个题:写出程序输出

typedef char(*AP)[5];AP foo(char* p) {
    for (int i = 0; i < 3; i++) {
        p[strlen(p)] = 'A';
    }
    return (AP)p+1;}int main() {
    char s[] = "FROG\0SEAL\0LION\0LAMB";
    puts(foo(s)[1] + 2);}

这个题用数组名是指针那套理论是做不出来的。

原文发布于微信公众号 - 顶级程序员(TopCoding)

原文发表时间:2017-01-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏决胜机器学习

PHP数据结构(二十六) ——基数排序实现36进制数排序

PHP数据结构(二十六)——基数排序实现36进制数排序 (原创内容,转载请注明来源,谢谢) 一、概述 插入排序、选择排序、快速排序等,都是通过关键字之间的比...

40411
来自专栏书山有路勤为径

插入位置

给定一个排序数组nums(无重复元素)与目标值target,如果target在nums里 出现,则返回target所在下标,如果target在nums里未出现,...

923
来自专栏五分钟学算法

五分钟学会一个有意思的排序:计数排序

由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新的一些复杂题目的动画,推出一个新系列 -----《图解数据结构》,主要使用动画...

1166
来自专栏代码世界

Python之迭代器和生成器

迭代器 可迭代的数据类型: list   dic   str    set     tuple      f=open()--文件句柄      range  ...

39011
来自专栏小文博客

写出这个数——《C语言代码笔记》

2512
来自专栏猿人谷

C++ primer里的template用法

template 的用法     在程序设计当中经常会出现使用同种数据结构的不同实例的情况。例如:在一个程序中     可以使用多个队列、树、图等结构来组织数据...

2195
来自专栏决胜机器学习

PHP数据结构(二十一) ——希尔排序

PHP数据结构(二十一)——希尔排序 (原创内容,转载请注明来源,谢谢) 一、概述 希尔排序,又称缩小增量排序,也属于插入排序类方法,时间上有较大改进。前面...

3467
来自专栏林德熙的博客

正则表达式30分钟入门教程

30分钟内让你明白正则表达式是什么,并对它有一些基本的了解,让你可以在自己的程序或网页里使用它。

540
来自专栏机器学习算法与Python学习

python基础语法(1)

从今天起,将进行python的一个系列学习,从基本的语法学起,后期会推出一些关于web开发,网络爬虫以及用python的第三方库进行数据挖掘与机器学习等高级的开...

40014
来自专栏web前端教室

javascript数据结构之基数排序浅淡

队列是一种列表,但它只能在队头删除元素,并在队尾插入元素。 所以,它是一个有序的列表,是先进先出的。 就像在银行排除一样,先到先办,新人排在后面。 可以使用队列...

2199

扫码关注云+社区

领取腾讯云代金券