Make Correct Code Look Correct

这是以前从一本书上看到的一篇文章,在网上也找到了英文原版http://www.joelonsoftware.com/articles/Wrong.html

这里仅仅想用一个简单的例子把原文思想再复述一下,再掐个头去个尾,添点油加点醋。

匈牙利命名法

貌似匈牙利命名法挺有争议的,说实话,我也没怎么感受到它的好处。像C语言,编译器会帮我们检查类型,又何必再在名字上画蛇添足呢;名字前缀上类型,敲代码的时候就觉得很烦,而且编辑器的自动补全功能会跳出来一大堆候选名字,因为相同类型变量的开头字母都相同。

会不会是我们的用法有问题呢?

例子

假设有这样一个系统,从界面取得用户输入的一个书名,然后从数据库查出该书的相关信息。

要查询数据库,就要用输入的书名字符串BookName生成一条SQL查询语句。但首先要把BookName中含有的特殊字符转义掉:

Escape(BookName);

另外,系统可能还会把每天的查询记录写到一个日志文件中。这就要用到转义前的BookName了,需要

Unescape(BookName);

如果代码量小,这样写问题不大。但在代码量很多的情况下,假如要在代码中间加入一条语句,打印有关BookName的日志消息,问题就来了。这个BookName到底有没有被转义过呢?可能作者都晕头转向了。所以,这种“原地”转义不可取。(“原地”,就是在原字符串上做操作)

如果把转义得到的新字符串赋给另外一个量呢?

NewBookName = Escape( BookName);

嗯,问题解决一部分了。至少我知道,NewBookName是转义过的,BookName是没转义过的。但要是换一个人来维护,估计又搞不太清了。

问题的最终解决办法是,把转义前的字符串看做是一种数据类型,转义后的字符串看做是另一种数据类型。不过在编译器看来,它们的类型没有区别,都是字符串。所以要靠程序猿自己检查类型了,如何写才能把类型正确性直观地表现出来呢?就要在命名上做文章。

把转义前的类型用us表示(unsafe),转义后的类型用s表示(safe)。从界面读到的字符串我们存放在UsBookName中,转义后的字符串存放到SBookName中。这样什么时候用哪个变量就不会搞混了。甚至还可以给转换函数加上类型,把escape命名成SEscapeFromUs,表示从us类型转为s类型,调用时,

SBookName = SEscapeFromUs(UsBookName);

这样,至少从形式上可以判断出代码没有问题。

这才是匈牙利命名法的本意。它使那些仅在语义上有微小区别的变量,通过命名约定,从形式上加以区别,使得代码的正确性一目了然,而不必去联系上下文理解,大大降低了代码之间的耦合性。

好像有点故弄玄虚了,其实就是提醒我们要注意命名,名字要清晰、全面地表达所指对象的含义罢了~:)

帮我完成xv6实验的代码,以下是实验指南: sleep (easy) Implement a user-level sleep program for xv6, along the lines of the UNIX sleep command. Your sleep should pause for a user-specified number of ticks. A tick is a notion of time defined by the xv6 kernel, namely the time between two interrupts from the timer chip. Your solution should be in the file user/sleep.c. Some hints: Before you start coding, read Chapter 1 of the xv6 book. Put your code in user/sleep.c. Look at some of the other programs in user/ (e.g., user/echo.c, user/grep.c, and user/rm.c) to see how command-line arguments are passed to a program. Add your sleep program to UPROGS in Makefile; once you've done that, make qemu will compile your program and you'll be able to run it from the xv6 shell. If the user forgets to pass an argument, sleep should print an error message. The command-line argument is passed as a string; you can convert it to an integer using atoi (see user/ulib.c). Use the system call sleep. See kernel/sysproc.c for the xv6 kernel code that implements the sleep system call (look for sys_sleep), user/user.h for the C definition of sleep callable from a user program, and user/usys.S for the assembler code that jumps from user code into the kernel for sleep. sleep's main should call exit(0) when it is done. Look at Kernighan and Ritchie's book The C programming language (second edition) (K&R) to learn about C. Run the program from the xv6 shell: $ make qemu ... init: starting sh $ sleep 10 (nothing happens for a little while) $ Your solution is correct if your program pauses when run as shown above. Run to see if you indeed pass the sleep tests. make grade Note that runs all tests, including the ones for the assignments below. If you want to run the grade tests for one assignment, type: make grade $ ./grade-lab-util sleep This will run the grade tests that match "sleep". Or, you can type: which does the same. $ make GRADEFLAGS=sleep grade
11-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值