免费注册 查看新帖 |

Chinaunix

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

拙著《狂人C》出版,特邀CU网友垂注,并欢迎品头论足、批评指正 [复制链接]

论坛徽章:
0
311 [报告]
发表于 2010-12-10 21:43 |只看该作者
能否详细说说有什么不同?
KBTiller 发表于 2010-12-08 22:35


通常意义上的address,可以认为是指存储器编址的一种简单的数学模型(地址空间)中的元素,也就是一个(非负的)整数。
C语言中的address constant(C++所说的address类似)是指指针(类型的实例)——
ISO C99 6.4.2:
Anaddress constant is a null pointer, a pointer to an lvalue designating an object of static
storage duration, or a pointer to a function designator; it shall be created explicitly using
the unary & operator or an integer constant cast to pointer type, or implicitly by the use of
an expression of array or function type.
显然,address constant是有类型的,和指针的运算规则相关。作为整数(数学概念)的地址,和指针运算的规则无关。
讨论C语言问题,要是单独说address,也没多大问题。只是应当注意C语言中没有再定义address的概念,address仍然应该指的是不考虑类型的整数。初学者如果不注意,可能会把两者混用——特别是用“地址”同时作为这两个不同概念的中文表述。
这显然是有问题的。例如:
int a[2] = {1};
要是说&a[0]得到的是一个“地址”(字面的说,是address,但严格意义上不是——它的类型在这里不能被忽略),那么“&a[0]+1的值是多少”这类问题可能就弄不清了。
其实还有一个问题,就是关于address constant中constant的意义。“地址常量”本身在字面上是没问题的,问题在于——很难描述C语言中所说的“常量”是什么,除非枚举外延(C语言中的常量包含地址常量、字符常量……)。因此有人反对使用“地址常量”这个译名(address constant是标准中定义的,大概不好反对;尽管这种定义确实很奇怪,容易产生误解),而用“地址”代替。上面已经提到过,C语言没有特别规定地址是什么,要表达“地址空间中的一个整数”这个意义时,“地址”是没有问题的;但是若在只能用address constant而不能用address的场合中用“地址”代替address constant,那就是一种误用。这种误用似乎还挺常见。于是学习者更加容易弄不清了。
(PS.我个人认为address constant是C语言中不必要出现的概念,直接用pointer来描述就行了——当然另外还要补充一下operator&的语义描述,如ISO C++风格的“unary operator & returns a pointer”之类。)

你的意思是学了计算机原理之类的基础课程,学习C更难了?
mirnshi 发表于 2010-12-09 10:55


在这些个别的概念上确实是这样。
另外,使用思维方式有较大的不同,也可能会造成一定的困难。不过这些课程本来就是要解决属于不同的领域(尽管有些相关)的问题,所以学习者应该可以理解到差异而不至于造成很大麻烦。

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
312 [报告]
发表于 2010-12-10 23:32 |只看该作者
“不认同变量名应该尽量见名知意这个准则”这个指责我是绝对不会承认的,事实也并非如此。
     ...
KBTiller 发表于 2010-12-09 13:08



函数多长的问题,其实是没有必要限定的。还有很多人建议将函数长度控制在一个屏幕范围内,其出发点是能够在一个屏幕内照顾到整个函数。函数多长,取决于内部耦合,编码前良好的设计是必须和必要的。如果没有设计习惯而直接编码,只能依赖于不断地重构,写到一定程度,就会将一些公共部分抽出,做成函数调用。

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
313 [报告]
发表于 2010-12-10 23:38 |只看该作者
说来说去,是我们对“入门”的定义不同
我认为精通这些复杂的数据类型才算入门
KBTiller 发表于 2010-12-09 19:48


那你的入门起点有些高了。复杂的数据类型往往伴随着复杂的算法(或解题算法)。一个能构建复杂数据类型并将实现相关算法的程序员,其水平不能说是入门吧?我觉得熟悉语法和语义,不借助参考书、编译器能够编写无语法和语义错误的程序就算入门了。

论坛徽章:
0
314 [报告]
发表于 2010-12-11 00:08 |只看该作者
本帖最后由 KBTiller 于 2010-12-11 00:17 编辑
那你的入门起点有些高了。复杂的数据类型往往伴随着复杂的算法(或解题算法)。一个能构建复杂数据类型 ...
mirnshi 发表于 2010-12-10 23:38



    我们转到 http://bbs.chinaunix.net/thread-1830222-1-1.html 继续讨论吧
(今晚我机器坏了,现在才弄好)

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
315 [报告]
发表于 2010-12-11 00:26 |只看该作者
通常意义上的address,可以认为是指存储器编址的一种简单的数学模型(地址空间)中的元素,也就是一个( ...
幻の上帝 发表于 2010-12-10 21:43


从这种字面上去理解指针或地址,是无法解释得非常清楚的。计算机更多的是实践。有了计算机基础,建立起计算机的工作/处理模型,可以将语言的语义转化到计算机模型上。有了直接寻址、间接寻址这些概念很容易理解指针,有了一些计算机部件硬件知识,更容易理解位操作。鲜有听说将这些计算机基础理论与计算机语言搞混的,相对熟悉其他语言的,熟悉C的对计算机的细节更加了解和熟悉。

论坛徽章:
0
316 [报告]
发表于 2010-12-11 11:47 |只看该作者
从这种字面上去理解指针或地址,是无法解释得非常清楚的。计算机更多的是实践。有了计算机基础,建立起 ...
mirnshi 发表于 2010-12-11 00:26


这种从字面上去理解当然很有问题,但是为什么会使人容易误解呢?某种意义上来说,C语言的理论体系难逃其咎。
计算机领域实践固然重要,但不代表使理论更清晰(以便能更好地帮助实践)的工作本身是可以被其它的实践取代的。
语言的实现帮助把源语言翻译成目标代码,把源代码的语义翻译成目标代码的操作语义——于是语言的使用者可以不必了解具体的每一个操作语义(例如汇编代码表述)。直接寻址、间接寻址这些概念是一类操作语义的抽象,但不是使用和机器无关的公理或指称描述的,受限于具体的实现模型和平台(尽管现在看起来是个计算机就可以在上面套用直接寻址之类的概念- -),这一般和用高级语言源代码直接表达的语义是有相当距离的。如果要求每个使用者都尽可能理解这些语言之外、实现相关的操作语义细节才能保证正确使用一门高级语言的话,那么“高级”就失去了一部分意义。(话说C语言不那么“高级”,有一点就是体现在这里。)

“有了直接寻址、间接寻址这些概念很容易理解指针,有了一些计算机部件硬件知识,更容易理解位操作。鲜有听说将这些计算机基础理论与计算机语言搞混的,相对熟悉其他语言的,熟悉C的对计算机的细节更加了解和熟悉。”——当然我也同意这个实践中得到的经验。

论坛徽章:
0
317 [报告]
发表于 2010-12-12 10:14 |只看该作者
同沙发!

论坛徽章:
0
318 [报告]
发表于 2010-12-12 17:01 |只看该作者
&a[0]+1的值是多少?这个问题可以从c语言的汇编看得出,地址和定义的数据类型有关系:
char a[3]={1,2,3};         对应的汇编为
mov        BYTE PTR _a$[ebp], 1
mov        BYTE PTR _a$[ebp+1], 2
mov        BYTE PTR _a$[ebp+2], 3
int a[3]={1,2,3};对应的汇编为:
        mov        DWORD PTR _a$[ebp], 1
        mov        DWORD PTR _a$[ebp+4], 2
        mov        DWORD PTR _a$[ebp+8], 3
这个有编译器自动识别,在应用的时候,有各编译器自动进行计算。
且printf("%x,   %x,     %x\n",&a[0],&a[0]+1,&a[0]+2);语句编译时,自动指定了单元,而不是在使用地址的时候进行计算:
lea        eax, DWORD PTR _a$[ebp+8]
        push        eax
        lea        ecx, DWORD PTR _a$[ebp+4]
        push        ecx
        lea        edx, DWORD PTR _a$[ebp]
        push        edx
        push        OFFSET FLAT?_C@_0BC@NGFL@?$CFx?0?5?5?5?$CFx?0?5?5?5?5?5?$CFx?6?$AA@ ; `string'
        call        _printf
不知道,是不是这样的?

论坛徽章:
0
319 [报告]
发表于 2010-12-12 20:39 |只看该作者

论坛徽章:
0
320 [报告]
发表于 2010-12-13 14:07 |只看该作者
不是挺不错的么..
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP