自我总结:C语言编程中犯的小错误

DeathKing posted @ 2013年1月25日 17:52 in C\C++ with tags c C语言 陷阱 缺陷 错误 , 3082 阅读

起因


  12年10月初的时候,手头有一笔闲款,于是就把传说中的“C/C++务实经典”给买齐了。虽然差一本C++ Templates但是其余的四本书还是非常给力的。由于Andrew KoenigC陷阱与缺陷》最薄,所以我就先拿他开刀,读罢收获的确也不少。

  为什么要关注这些东西呢?我觉得,知识本身固然重要,但“经验”更加不可缺少。很多时候,教科书只传授给你了知识本身,没有将经验传授给你。而在处理实际问题时,所遇到的情况往往不如教科书上的那么理想化,这个时候,经验就比知识有用多了。

  说说错误吧。除了C陷阱与缺陷》中提到的一些典型的问题,我自己还经常范一些小毛病。归一下类的话,大概有:编码习惯Typo缺少对函数的认识这三类吧。故此,在这里总结一下,希望对大家能有所帮助。这些小错误嘛,以后还会变着花样犯,慢慢总结吧

 

编码习惯


二维数组,行-列还是X-Y?

  首先,这个错误源于一个不好的习惯。很多人习惯用(X,Y)来描述一个二维点(我也是这样)。然而在二维数组(数组的数组)中,标准的描述应该是行-列(Row-Col)。

char check[][10] = { "#@########",
                     "##########"};

putchar(check[0][1]); /* --> @ */
putchar(check[1][0]); /* --> # */

  所以一定要小心,将二维数组的元素定义为点的时候,最好用行-列来描述!

struct pt {
  int row;
  int col;
} at_sym;

char check[][10] = { "#@########",
                     "##########"};

at_sym.row = 0;
at_sym.col = 1;

/* 实际代码没这么复杂,这里只是为了强调 */
putchar(check[at_sym.row][at_sym.col]); /* --> @ */

 

游标所指之处的意义?

  我们有一个数组arr和游标pt,那么arr[pt]是数组的最后一个元素还是第一个空可用空间?也就是,我们使用下面那一种图示?

  我认为,让pt所指为“第一个可用空间”叫好,因为pt的值即是arr中元素的个数。

 

Typo


main()还是mian()?

  下面代码的错误,你能一眼看出来么?他可以通过编译,但无法链接,自己观察,发现把main()打成了mian()。我在做C程序设计语言》的习题时,曾犯过这个错误,折磨得我生不如死啊!

#include <stdio.h>

int mian()
{
    printf("Hello, World!\n");
    return 0;
}

  这顿面可不好吃啊!

 

true还是ture?

  其实这个问题不大,现在很多编辑器或IDE都支持语法高亮,这个错误很容易看出来。而且,C89不是原生支持true,所以出现这个错误的可能性不高。但还是要留个心。

 

对函数的了解


memset()

  假设你有一个可以容纳10个int型元素的数组arr,你想要将它全初始化为0,于是你很高兴的写下了下面的代码:

#include <string.h>
#define LENGTH 10

int main()
{
  int arr[LENGTH];
  memset(arr, 0, LENGTH);
  return 0;
}

  这样,你又犯了一个错误!memset()是以字节为单位设置内存的,因此,如果在某个int占2个字节的机器上运行此代码,只有前5个元素会被设置为0。memset()函数置一类型为T的数组为0的做法应该是这样(两种方法都可):

memset(arr, 0, LENGTH * sizeof(T));
memset(arr, 0, LENGTH * sizeof(arr[0]));

 

scanf()

  说实话,scanf()用起来十分危险,千万要小心!假设我们有下面的数据:

11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........

  你可能会用下面的代码来读取:

/* 省去了一些代码,并认为map的空间在这里例子中足够了 */
scanf("%d %d", &col, &row);
i = 0;
j = row;
while (j--)
  gets(map[i++]);

  然而,你会发现少读了一行。因为如果将map的内容给输出出来,会是这样(注意:第一行是个空行):

/* 这里是一个空行 即map[0] */ 
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.

  很简单,scanf()在读取完两个int后,并没有处理缓冲区中的那个'\n',这个'\n'就交给gets()来处理了。gets()认为他是字符串的第一行,将它读入,造成的结果就是少读一行。解决办法也很简单,在scanf()format的末尾加上一个空格,让他跳过“空白字符(回车、制表、空格)”:

scanf("%d %d ", &col, &row);

  切记,使用scanf()时绝不可掉以轻心,有时还应清空缓冲区!

 

附录


C\C++务实经典系列

C陷阱与缺陷(C Traps and Pitfalls)》:Andrew Koenig

C++沉思录(Ruminations on C++)》:Andrew Koenig && Barbara Moo

C专家编程(Expert C Programming)》:LinDen P.V.D

C和指针(Pointers on C)》:Kenneth A.Reek

C++ Templates》:David Vandevoorde && Nicolai M. Josuttis

Avatar_small
夏福的猎鹿帽 说:
2013年1月28日 18:46

挺好的,scanf用起来真的容易出错

Admit Card 2022 说:
2021年11月10日 21:51

Please read our article thoroughly to learn everything there is to know about Admit Card 2022. It will be stated when the admission card will be provided and how to obtain it online. Admit Card 2022 You will also be given a link to the official website where you can get the admission card. We hope you will take the time to read it carefully, and for more information, please visit our website.

Jaa Lifestyle Sign U 说:
2022年8月07日 16:17

Jaa Lifestyle is a money earning website which has its roots from United Kingdom. The Jaa Lifestyle not fully open in India, but still an individual can try to get a glance about services from website. They offer some new ways to earn money by involving the individuals in different activities. Jaa Lifestyle Sign Up There are referral programs and other game in Java Lifestyle, which are available to earn money. Individual has to fully get involve in the activities and has to win the game to earn money. In the modern time, everyone addicted to digital devices and Jaa Lifestyle tries to attract such users to use these websites and earn money. Here 25penny will provides you the detail steps for Sign up and login.

NCERT History Questi 说:
2022年9月29日 14:31

By knowing about history we may get aware of what kind of result we gain by doing what kind of things either good or evil. It inspires the students to understand their successes and failures. NCERT History Question Paper Class 9 history shows the past patterns of behaviour or events and their outcome, which can help us avoid similar outcomes in the future. NCERT has introduced topic-wide study & learning material for all class 9th standard students for History.NCERT has introduced topic-wide study & learning material for all class 9th standard students for History.By knowing about history we may get aware of what kind of result we gain by doing what kind of things either good or evil. It inspires the students to understand their successes and failures.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter