complete code

本文探讨了如何通过改进变量命名、控制结构清晰度及合理使用布尔表达式等方式提高代码质量。此外,还介绍了有效调试策略,包括使用科学方法定位错误、避免试错法以及利用调试工具等。

2008-8-31

P250

True False 之类的词来表示布尔表达式的结果,如果所用语言不支持这种类型,用预

定义宏或全局变量的方法来创造一个。

True False 作变量名使得用意很清楚。你不用记“1”和“0”表示什么意思,也不用

偶尔回头检查。

 

C中用1 == 1的形式定义TRUEFALSE

C中,有时很难记住是否TRUE等于1FALSE

等于0 或者正好相反,你得记住测试FALSE 和测试空终止符或其它零值一样。否则用下面定义

TRUEFALSE的方法来避免出现这个问题。

这个C 程序用易于记住的方法定义布尔量:

     define TRUE 1 ==1

define FALSE!TRUE

 

CPascal 用短路法计算,如

果第一个运算and是假,那么第二个运算不再执行,因为整个式就已经是假了。

 

17.1.7  C语言中与0比较的用法

C 语言中0有几个用途。它是一个数字量;在字符串中它是一个结束符(’\0’),它是地

址指针所允许的最小值;在逻辑表达式中它表示假,因为它有这么多的用途,你在编程时要清

楚地表明是哪种。

隐含地和逻律变量比较。正如前面提到,这样写逻辑表达式是正确的。

    while(!Done

这个表达式隐含在和0 作比较是正确的,因为这个比较是在一个逻辑表达式里。

数与0 比较。虽然可隐含地把逻辑表达式与0 比较,你却不可以把数字表达式隐含地与0

比较。对于数字,编程:

   whileBalance!=0)…

而不可写成

     whileBalance)…

  把字符与结束符(’/0’)字一样,字符也不是逻辑表达式。因此对字符编程:

      while* CharPtr!=’0’)…

而不能写成:

      while (* CharPtr)

这种说法与常用的c 语言在处理字符数据时的习惯可能有出入,但它强化了这种观点,即

表达式是在处理字符数据,而非逻辑数据。C语言的有些用法并不是基于可读性和或维护而设计

的,比如上例即是。

把指针与Null(空指针)比较。对指针编程:

whileBufferPtr!=Null)…

而不写成:

   whileBufferPtr)…

与字符的情形一样,这也不是C 的常用用法,但却增强可读性。  

 

重新编写部分测试条件来简化嵌套的If 语句。

 

17.7.4  检查表

控制结构方面

·  表达式用TrueFalse而非1 0

·  布尔型表达式的值是否隐含地与False比较?

·  是否通过定义中间布尔型变量和布尔型函数及用决策表的方法来简化表达式?

·  布尔型表达式是用肯定形式写出来的吗?

·  C 中,数值、字符,指针是显式0比较的吗?

·  beginend能保持平衡吗?

·  为了使程序看起清楚,需要的地方用beginend对标明了吗?

·  空语句看起来清楚吗?

·  通过诸如重新组合测试条件、转化为if-thenelsecase 语句或把嵌套内代码写成子

程序的方法来简化嵌套语句了吗?

·  如果程序的决定点数超过10,有什么正常理由不重新设计它吗?

17.8   

 ·  使布尔型表达式简单可读性高对代码的质量很有好处。

 ·  深层嵌套使程序难懂,不过可用相对简单方法避免这样做。

 ·  结构化编程是一个简化程序的思想,用顺序编程、选择或循环中的一种或几种方法的组

     合可编出任何程序。

 ·  作这种简化程序的思想可提高程序的产量和质量。

 ·  如果所用语言不支持结构化结构,你能模仿它们。你应该把程序编成某种语言的程序而

     不是用某种语言编程的。

 ·  降低复杂性是编写高质量的代码的关键。 

――――――――――――――――以上是 17 章―――――――――――

 

1

2

3

4

5

6

7

8

9

小结

· 恰当的变量名是可读性好的必要条件之一。特殊的变量如循环变量和状态变量要予以

特殊考虑。

· 命名约定可以区分局部、模块和全局变量。同时它还可以区分类型名称,比如可以对

命名常量、枚举类型和变量加以区分。

· 不管你从事的是哪种项目,都应该采用命名约定。所采用的命名约定取决于程序的规

模和从事这一程序的程序员的人数。

· 匈牙利约定是一种非常有效的命名约定,比较适于大规模项目和程序。

· 在现代编程语言中几乎不需要采用缩写技术。

9.8.1  检查表

通用命名约定

· 变量名称是否完全准确地描述了变量代表的是什么?

· 变量名是否指向是客观世界中的问题,而不是关于这问题的用程序语言表达解决方案?

· 变量名称是否是够长,使得你不必破译它?

· 变量名中如果含有计算限定词的话,是否将其放在最后?

· 是否在名称中用CountIndex来代替了Num

对特殊类型数据的命名

· 循环变量的名称是有意义的吗?(如果循环体较长是嵌套循环的话,应用有含义的名

称来代替ijk 之类的名称)

· 是否用更富于含义的名称来代替了被叫作"tempotarg"的临时变量?

· 当逻辑变量的值是"True"时,它的名称是否充分表达了其含义?

· 是否用前缀或后缀来表明了某些枚举类型是一类的?如用Color 来作ColorRed

ColorGreenColorBlue等枚举类型的前缀。

· 命名常量的名称是否是指向它们代表的实体而不是它们所代表的数值的?

命名约定

· 命名约定是否区分了局部、模块和全局数据?

第九章 数据名称 140

· 命名约定是否对类型名称、命名常量、枚举类型和变量进行了区分?

· 在不支持强化仅供子程序输入参数的语言中,命名约定是否对这类参数进行了标识?

· 命名约定是不是与程序语言的标准约定尽可能地相容?

· 对于语言中没有强制的子程序中仅做输入的参数,是否约定将它标识了?

· 是否对名称进行了格式化以增强程序的可读性?

短名称

· 代码是否使用了长名称?(除非有必要使用短名称)

· 是否避免了只省略一个字母的缩写?

· 所有单词保持缩写的连续性了吗?

· 所有的名称都是容易发音的吗?

· 是否避免了会引起错误发音的名称?

· 是否在注释表中对短变量名进行了注释?

避免如下这些常见的命名错误了吗

· 易引起误会的名称

· 含义相似的名称

· 仅有一或两个字母不同的名称

· 发音相似的名称

· 使用数字的名称

· 对单词作改写以使其比较短的名称

· 英语中常拼写错的名称

· 标准库子程序或已定义的变量名又定义了

· 完全是随意的名称

· 含有难以辨识字母的名称

 

10

检查表

使用数据时通常要考虑的一些问题

一般数据

· 是否已经使变量的作用域尽可能地小?

· 是否把对变量的使用集中到了一起?

· 控制结构与数据结构是相对应的吗?

· 每个变量是否有且仅有一个功能?

· 每个变量的含义都是明确的吗?是否保证了每个变量都没有隐含的意义?

· 每一个说明过的变量都被用到了吗?

全局变量

· 是否是在迫不得已的情况下,才使某些变量成为全局的?

· 命名约定是否对局部、模块和全局变量进行了区分?

· 是否说明了所有全局变量?

· 程序中是否不含有伪全局变量——传往各个子程序的庞大而臃肿的数据结构?

· 是否用存取子程序来代替了全局数据?

· 是把存取子程序和数据组织成模块而不是随意归成一堆的吗?

· 存取子程序的抽象层次是否超过了程序语言实现细节?

· 所有相互有联系的存取子程序,其抽象程度都是一致的吗?

10.7  小结

· 尽量减小变量的作用域。把对变量引用集中到一起,应尽量使变量成为局部或模块的,

避免使用全局变量。

· 使每个变量有且仅有一个功能。

· 并不是因为全局数据危险才避免使用它们,之所以避免用它是因为可以用更好的技术

来代替它。

· 如果全局数据确实不可避免的话,应通过存取子程序来对其进行存取操作。存取子程

序不仅具备全局变量和全部功能,而且可以提供更多的功能。

 

11

P154P161 已看

12

13

14

15

16

17

18

19

20

21

P154

22

23

24

25

26

2008-8-31

定期发生错误通常是由于量进行使用了悬挂指针。如果一数有时错有

时对,这可能是计算中所涉及到的有被正确地初——大多数情况此变

0。如果你使用了指针,并所发生的现奇怪不可测的,你可能使用了一

未初化指针,或对已分存储器单元使用了指针

确定错误位置

    简化测试用例的目的是,改变测试用例的任何一方面是否都能引起错误的出现。然后,细

心地改变测试用例,并观察在一定条件下错误的表现形式,这样你才能诊断错误。

    确定错误的位置也同样需要使用科学的方法,你可能怀疑错误是由某一特定问题,比如边

界条件错误所引起。你可将你怀疑的常量取不同值——一个低于边界值,一个恰为边界值,另

一个高于边界值——以此来确定你的假想是否正确。

 

检查表

·调试

    发现错误的方法:

    ·  使用所有数据建立假设

    ·  求精产生错误的测试用例

    ·  通过不同的方法再生错误

    ·  产生更多的数据以生成更多的假设

    ·  使用否定测试结果

    ·  提出尽可能多的假设

    ·  缩小可疑代码区

    ·  检查最近作过修改的代码

    ·  扩展可疑代码区

    ·  逐步集成

    ·  怀疑以前出过错的子程序

    ·  耐心检查

    ·  为迅速的草率的调试设定最大时间

    ·  检查一般错误

    ·  使用交谈调试法

    ·  中断对问题的思考

    改正错误的方法:

    ·  理解问题的实质

    ·  理解整个程序

·  确诊错误

    ·  放松情绪

第二十六章调 试 430

·  保存初始源代码

    ·  修改错误而不是修改症状

    ·  仅为某种原因修改代码

    ·  一次作一个修改

    ·  检查你的工作,验证修改

    ·  寻找相似错误

    调试的一般方法

    ·  你是否将调试作为学习有关程序、错误、代码质量及解决问题方法的一次机会?

    ·  你是否避免使用试错法,或避免采用迷信的方法?

    ·  你是否认为错误是由于你的过错?

    ·  你是否使用科学方法以固定间歇性错误?

    ·  你是否使用科学方法发现错误?

    ·  你是否每次使用不同的方法,而不是只用一种方法发现错误?

    ·  你是否验证了修改信息是正确的?

·  你是否利用了警告信息、执行剖析程序、建立脚手架方法、交互式调试等?

26.6   

·   调试是软件开发中的问题。最好的方法是使用本书的其他方法避免一开始就发生错误。

你仍需花费时间提高你的调试技能——因为最好和最差的调试效率差别为10:1,甚至

更大。

·   注意你的编译警告信息,并及时改正编译所提示的错误。如果你忽略了明显错误的话,

你就难以改正微妙的错误。

·  发现和改正某错误的关键是,有一个有条理的方法,注重你的测试,这样每次你都能

向前迈进一步。

·  在你改正一个问题之前应理解问题的本质,对错误源的任意猜测和修改只会使你的程

序更为糟糕。

·  调试是软件开发的有力工具。你应能利用调试工具。记住你还应好好动脑筋

Certainly! Below is a complete code example based on the content from the document "Lab 7 - VGA Application-1.pdf". This code includes the initialization of GPIO objects, handling of slide switches, and setting the color and region values for the VGA display. ### `gpio_init.h` ```c #ifndef GPIO_INIT_H_ #define GPIO_INIT_H_ #include "xparameters.h" #include "xgpio.h" // Define the GPIO device IDs #define SLIDE_SWITCHES_DEVICE_ID XPAR_GPIO_0_DEVICE_ID #define VGA_REGION_DEVICE_ID XPAR_GPIO_1_DEVICE_ID #define VGA_COLOUR_DEVICE_ID XPAR_GPIO_2_DEVICE_ID // Function prototypes void initGpio(void); extern XGpio SlideSwitches; extern XGpio VgaRegion; extern XGpio VgaColour; #endif // GPIO_INIT_H_ ``` ### `gpio_init.c` ```c #include "gpio_init.h" #include "xstatus.h" XGpio SlideSwitches; XGpio VgaRegion; XGpio VgaColour; void initGpio(void) { int status; // Initialize the slide switches GPIO status = XGpio_Initialize(&SlideSwitches, SLIDE_SWITCHES_DEVICE_ID); if (status != XST_SUCCESS) { return XST_FAILURE; } // Set the direction of the slide switches to input XGpio_SetDataDirection(&SlideSwitches, 1, 0x0000); // Initialize the VGA region GPIO status = XGpio_Initialize(&VgaRegion, VGA_REGION_DEVICE_ID); if (status != XST_SUCCESS) { return XST_FAILURE; } // Set the direction of the VGA region to output XGpio_SetDataDirection(&VgaRegion, 1, 0xFFFF); // Initialize the VGA colour GPIO status = XGpio_Initialize(&VgaColour, VGA_COLOUR_DEVICE_ID); if (status != XST_SUCCESS) { return XST_FAILURE; } // Set the direction of the VGA colour to output XGpio_SetDataDirection(&VgaColour, 1, 0xFFFF); } ``` ### `main.c` ```c #include "gpio_init.h" #include "xil_io.h" #include "xil_printf.h" int main() { u16 slideSwitchIn = 0; u16 region = 0; u16 colour = 0; // Initialize the GPIOs initGpio(); while (1) { // Read the current state of the slide switches slideSwitchIn = XGpio_DiscreteRead(&SlideSwitches, 1); // Extract the lower 12 bits for colour and the upper 4 bits for region colour = slideSwitchIn & 0x0FFF; region = (slideSwitchIn >> 12) & 0x000F; // Map the 4-bit region to the 9-bit region selection switch (region) { case 0: region = 0b000000001; break; case 1: region = 0b000000010; break; case 2: region = 0b000000100; break; case 3: region = 0b000001000; break; case 4: region = 0b000010000; break; case 5: region = 0b000100000; break; case 6: region = 0b001000000; break; case 7: region = 0b010000000; break; case 8: region = 0b100000000; break; default: region = 0b000000000; break; } // Write the region and colour to the VGA GPIOs XGpio_DiscreteWrite(&VgaRegion, 1, region); XGpio_DiscreteWrite(&VgaColour, 1, colour); } return 0; } ``` ### Explanation 1. **GPIO Initialization (`gpio_init.h` and `gpio_init.c`)**: - Define the device IDs for the slide switches, VGA region, and VGA colour. - Initialize the GPIO objects and set their directions (input for slide switches, output for VGA). 2. **Main Loop (`main.c`)**: - Continuously read the state of the slide switches. - Extract the lower 12 bits for the colour and the upper 4 bits for the region. - Map the 4-bit region to the 9-bit region selection. - Write the region and colour values to the respective GPIOs. This code should allow you to control the VGA display using the slide switches on the Basys3 board, where the slide switches determine both the region and the colour to be displayed.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值