免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Ager
打印 上一主题 下一主题

[C] 浅谈一下C语言中的指针与数组的关系 [复制链接]

论坛徽章:
0
61 [报告]
发表于 2012-12-24 10:14 |只看该作者
回复 58# timothyqiu


    你先前的认为是对的。int *p=&a 应该分为 int 和 *p=&a 两部分,后面的*(就和楼主在一楼阐述[]一样)和运算符的*是两码事,纯属巧合。声明里面的 * 是declarator的一部分,非运算符。

初始化属于declarator,初始化的是identifier。
  1. int *p1 = &a1, *p2 = &a2;

  2. int (*pf1)(int, int) = &sum, (*pf2)(int) = &abs;
复制代码

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
62 [报告]
发表于 2012-12-24 10:18 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
63 [报告]
发表于 2012-12-24 10:25 |只看该作者
回复 61# sonicling

你说的不对,我又翻了下 K&R,里对于声明语法的形式化定义是这样的:
  1. declaration:
  2.   declaration-specifiers init-declarator-list(opt)

  3. ...

  4. init-declarator-list:
  5.   init-declarator
  6.   init-declarator-list, init-declarator

  7. init-declarator:
  8.   declarator
  9.   declarator = initializer
复制代码
所以 declarator 和 initializer 不是一个东西。初始化并不属于 declarator。

换句话说,完全可以剥离出来而不影响声明,只是声明语法恰巧提供了初始化的地方而已,相当于语法糖。

论坛徽章:
0
64 [报告]
发表于 2012-12-24 10:50 |只看该作者
回复 63# timothyqiu


    好吧,属于init-declarator!

论坛徽章:
0
65 [报告]
发表于 2012-12-24 10:56 |只看该作者
回复 64# sonicling


「init-declarator」的意思是「initializer 和 declarator」啊,只是用来解释语法的中间产物,不是实际存在的概念……

……我觉得楼主在变量声明的解释上还是过度解读了,作者 K&R 的本意其实很简单啊……

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
66 [报告]
发表于 2012-12-24 11:33 |只看该作者
回复 51# pmerofc

这本来就不是哲学,就算是,神奇的土地上也没几个人能到这个高度,就连华老也只能窝里香。

不讲xx是,xx本质 是几乎不能做正常讨论的,比如ag建楼里就有“作为下标操作符的方括号,其真确含义是:”这样的对真确含义的定义。。。呵呵。
类型系统里有很多类型,基本的,复合的,递归的,但没有所谓的推导类型,只有类型的推导。

C的指针为什么要单独拿出来,是因为指针是独立于语言系统的,一个语言系统,或者说类型推断的语言系统,可以没有指针但必须要有类型系统和推断,这个可以参见SQL语系,ML语系等系统。甚至Java都没有这个东西。
C的指针的特殊在于它直接体现的物理模型而不是逻辑模型,它体现的是access而不是compute,而类型系统不会care如何access某个object,例如SQL就是很显然的一个不care如何access对象的例子。因此当你在C里access某片存储的内容之后,还需要dereference还原本来的type才能进行compute。当我们解读一个指针的时候,必须的说这个指针是指向xx类型的对象的指针。

指针是机制,是访问机制,不是策略,策略的应用需要建立在机制之上但不能反过来说。所以各种树,图,多态等类型都在指针提供的机制之上构建策略。同样策略之下的机制可以有很多种各不相同的机制。但把机制上升到策略的高度,或许可以等于说“我们都知道只有H、O、C等原子事实上并不等同于人”,而你现在做的我个人认为恰是告诉大家H,O,C就是人。

所以,指针是字面上的类型。

论坛徽章:
0
67 [报告]
发表于 2012-12-24 11:47 |只看该作者
回复 65# timothyqiu


   
「init-declarator」的意思是「initializer 和 declarator」啊,只是用来解释语法的中间产物,不是实际存在的概念……


我认为是initialized-declarator,你可以看标准所有带连字符的词,除了个别identifier-nondigit之外,连字符之前都做定语。

至于是否实际存在,我不考虑,反正都是看不见摸不着的东西。

K&R说的道理很简单,操作却很复杂。他将声明的标识符代入到表达式中去解释,拐了个大弯。

就好比5+5为什么等于10?K&R说因为5往后再数5个数就是10,多么通俗易懂。实际操作需要数5个数吗?大家从小学学的不都是10以内背下来,10以上竖式计算。研究数数只有幼儿园和大学去研究。幼儿园只能研究数数,大学要研究集合论,什么有限集合、无限集合、可数、不可数、可枚举、不可枚举。要说自打会数数起就知道自然数是可数的了,还用你去花一页纸证明自然数集合是可数的?居然还用数学归纳法证明。

论坛徽章:
0
68 [报告]
发表于 2012-12-24 12:47 |只看该作者
回复 67# sonicling

诶~无论「init-declarator」究竟怎么展开,都只是中间产物的一个名字,和 declarator 的身份不同……(这里的存在/不存在的意思是「是否是术语」)

后面的就看不出可比性在哪里了。

楼主的各种概念陈述(尤其是独创了「声明语句中的方括号/星号是不同的操作符」这一点)和作者的一句「declaration mimics use」到底谁更突兀呢?

退一步,即使作者解释得再绕,也是其本意。就像鲁迅文章里用词的理由再荒诞、老师的解读再科学再煽情,也终究要以作者的本意为正解,不是吗?

论坛徽章:
0
69 [报告]
发表于 2012-12-24 14:32 |只看该作者
timothyqiu 发表于 2012-12-24 12:47
回复 67# sonicling

也终究要以作者的本意为正解,不是吗?


作者的本意是什么我不清楚,只知道他们出了本书,说了些话。如果对于C语言的任何解释都必须在思想上与他们保持一致的话,C语言这东西不研究也罢,没意思。

我没有说K&R的解释错,但是的确绕远了。我说“initializer属于declarator”,不管对于错,好歹initializer和declarator被写在同一个产生式里面了,就算你不认同从属关系,总还是有个什么关系吧。把声明放到表达式中去解释。。。声明和表达式在标准中都跨章节了,这关系比initializer和declarator的关系不知道远了十万八千里,还要把这个捧为正朔?

还是那句话:初始化是属于声明器的,被初始化的是标识符。这句话适用于变量带初始化声明的所有情况,信不信由你。

这句话回答了@Ager 的“那个“int *p=&a;” 到底是在对“p”初始化,还是对“*p”初始化?” 的问题。

论坛徽章:
0
70 [报告]
发表于 2012-12-24 15:00 |只看该作者
@timothyqiu

要怪就怪C的声明太复杂,人家C#的就简单许多,类型都放在标识符左边,初始化都放在右边。
  1. string[] a, b;
复制代码
a和b都是string[]类型。

C语言就不一样了,char a[] = "hello", *b = "hello";  同一条声明语句里相同初始化的a和b的类型不一样,值也不一样,这不是蛋疼吗?

C语言声明那一章里最复杂的就是声明器那节。C++标准把声明器单独拎出来讲,和声明并列,足见其复杂程度。而且顺带说一下,C++标准里的initializer就是放在declarator那一章里讲的,我认为这么划分比C标准更合理。

declarator包含了部分类型信息,而且这部分信息很难和被声明的标识符剥离。所以形式上被初始化的是declarator,实质上被初始化的只能是标识符。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP