《THE C PROGRAMMING LANGUAGE》读书笔记一

来源:互联网 发布:javascript timeout 编辑:程序博客网 时间:2024/06/05 00:30
《THE C PROGRAMMING LANGUAGE》读书笔记一

1.1开始

经典范例:
  1. #include <stdio.h>
  2. main()
  3. {
  4.   printf("hello, world/n");
  5. }

说明:
#01 为引用标准输入输出函数库;注意“<...>”为引用标准库时使用,“"..."”则用于引用自定义文件时使用,两者的查找路径不一致,前者搜索标准库目录,而后者则从当前目录查找,然后才考虑系统目录;
#04 函数printf不会自动换行,因此可以用printf("hello, "); printf("world"); printf("/n");三条语句等价替换;
转义字符“/”,特殊字符输出均需要采用转义字符配合使用:“/t”制表符、“/b”退格、“//”反斜杠、“/"”双引号;

1.2变量和数学表达式
示例:
  1. #include <stdio.h>
  2. /* print Fahrenheit-Celsius table
  3. for fahr = 0, 20, ..., 300; floating-point version */
  4. main()
  5. {
  6.   float fahr, celsius;
  7.   float lower, upper, step;
  8.   lower = 0; /* lower limit of temperatuire scale */
  9.   upper = 300; /* upper limit */
  10.   step = 20; /* step size */
  11.   fahr = lower;
  12.   while (fahr <= upper) {
  13.     celsius = (5.0/9.0) * (fahr-32.0);
  14.     printf("%3.0f %6.1f/n", fahr, celsius);
  15.     fahr = fahr + step;
  16.   }
  17. }
说明:
#13 数学运算,整数运算中“/”在C语言中为整除运算符,5/9结果为0,所以这里采用5.0/9.0使之转换为浮点运算结果也为浮点数;
#14 格式化输出,%d--整数、%6d--至少6位宽度整数,右对齐、%f--浮点数、 %6f--至少6位浮点数,右对齐、  %.2f--两位小数浮点数、 %6.2f--至少6位宽度浮点数,2位小数;
%o--八进制、 %x--十六进制、 %c--字符、 %s--字符串、 %%--%,而采用其他方法"/%"或"%"均不正确;

1.4符号常量
  1. #include <stdio.h>
  2. #define LOWER 0 /* lower limit of table */
  3. #define UPPER 300 /* upper limit */
  4. #define STEP 20 /* step size */
  5. /* print Fahrenheit-Celsius table */
  6. main()
  7. {
  8.   int fahr;
  9.   for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
  10.   printf("%3d %6.1f/n", fahr, (5.0/9.0)*(fahr-32));
  11. }
说明:
#02、#03、#04 符号常量通常采用大写字母表示,不采用分号作为行结束符;

1.5字符输入、输出

  1. #include <stdio.h>
  2. #define IN 1 /* inside a word */
  3. #define OUT 0 /* outside a word */
  4. /* count lines, words, and characters in input */
  5. main()
  6. {
  7.   int c, nl, nw, nc, state;
  8.   state = OUT;
  9.   nl = nw = nc = 0;
  10.   while ((c = getchar()) != EOF) {
  11.     ++nc;
  12.     if (c == '/n')
  13.       ++nl;
  14.     if (c == ' ' || c == '/n' || c = '/t')
  15.       state = OUT;
  16.     else if (state == OUT) {
  17.       state = IN;
  18.       ++nw;
  19.     }
  20.   }
  21.   printf("%d %d %d/n", nl, nw, nc);
  22. }

说明:
#10 注意!=的优先级高于=,如果去掉括号c = getchar() != EOF等价于c = (getchar() != EOF)虽然逻辑判断仍然正确,但c的值将是1或0;
#11 自增++,自减--,注意无论运算符前置或后置变量的值都会相应的加1或减1,而表达式的值则有所不同,前置为变量运算后的值,后置则为变量运算前的值;
#12 相等逻辑判断符“==”,而“=”为赋值运算符,多语言编程的人不小心会混淆,而如果误用“=”作为逻辑判等,系统首先做赋值运算然后判断左侧变量的值是否为真;
#14 逻辑运算表达式的短路,系统在确定整个表达式最终值时会立即返回而不一定会进行所有的逻辑判断,比如C=' '那么后两个判断将不会再进行,利用这个“短路”我们可以在写多个逻辑条件时适当考虑顺序进行优化;

1.7函数

  1. #include <stdio.h>
  2. int power(int m, int n);
  3. /* test power function */
  4. main()
  5. {
  6.   int i;
  7.   for (i = 0; i < 10; ++i)
  8.     printf("%d %d %d/n", i, power(2,i), power(-3,i));
  9.   return 0;
  10. }
  11. /* power: raise base to n-th power; n >= 0 */
  12. int power(int base, int n)
  13. {
  14.   int i, p;
  15.   p = 1;
  16.   for (i = 1; i <= n; ++i)
  17.     p = p * base;
  18.   return p;
  19. }
说明:
#02 函数声明,可以不提供函数变量名称仅提供参数类型,等价int power(intint);函数声明中的参数名称可以与定义中的参数名称不同,即本语句可改为int power(int x, int y);

1.8参数-传值调用
  1. /* power: raise base to n-th power; n >= 0; version 2 */
  2. int power(int base, int n)
  3. {
  4.   int p;
  5.   for (p = 1; n > 0; --n)
  6.     p = p * base;
  7.   return p;
  8. }
说明:
  1、传值调用即被调用函数将调用者参数值赋给临时变量而非调用者传入参数本身;
  2、如果要实现被调用函数直接修改调用者传入变量的值则需要通过指针方式来处理;
  3、数组参数传入的是调用者数组的首地址而非数组的拷贝,因此其操作为指针方式处理;

1.9字符数组
  1. #include <stdio.h>
  2. #define MAXLINE 1000 /* maximum input line length */
  3. int getline(char line[], int maxline);
  4. void copy(char to[], char from[]);
  5. /* print the longest input line */
  6. main()
  7. {
  8.   int len; /* current line length */
  9.   int max; /* maximum length seen so far */
  10.   char line[MAXLINE]; /* current input line */
  11.   char longest[MAXLINE]; /* longest line saved here */
  12.   max = 0;
  13.   while ((len = getline(line, MAXLINE)) > 0)
  14.   if (len > max) {
  15.     max = len;
  16.     copy(longest, line);
  17.   }
  18.   if (max > 0) /* there was a line */
  19.   printf("%s", longest);
  20.   return 0;
  21. }
  22. /* getline: read a line into s, return length */
  23. int getline(char s[],int lim)
  24. {
  25.   int c, i;
  26.   for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='/n'; ++i)
  27.     s[i] = c;
  28.   if (c == '/n') {
  29.     s[i] = c;
  30.     ++i;
  31.   }
  32.   s[i] = '/0';
  33.   return i;
  34. }
  35. /* copy: copy 'from' into 'to'; assume to is big enough */
  36. void copy(char to[], char from[])
  37. {
  38.   int i;
  39.   i = 0;
  40.   while ((to[i] = from[i]) != '/0')
  41.   ++i;
  42. }
说明:
#23 数组参数,函数体中
修改操作直接作用于传入数组参数本身,本例中为line数组

1.10外部变量和作用域
  1. #include <stdio.h>
  2. #define MAXLINE 1000 /* maximum input line size */
  3. int max; /* maximum length seen so far */
  4. char line[MAXLINE]; /* current input line */
  5. char longest[MAXLINE]; /* longest line saved here */
  6. int getline(void);
  7. void copy(void);
  8. /* print longest input line; specialized version */
  9. main()
  10. {
  11.   int len;
  12.   extern int max;
  13.   extern char longest[];
  14.   max = 0;
  15.   while ((len = getline()) > 0)
  16.   if (len > max) {
  17.     max = len;
  18.     copy();
  19.   }
  20.   if (max > 0) /* there was a line */
  21.     printf("%s", longest);
  22.   return 0;
  23. }
  24. /* getline: specialized version */
  25. int getline(void)
  26. {
  27.   int c, i;
  28.   extern char line[];
  29.   for (i = 0; i < MAXLINE - 1 
  30.        && (c=getchar)) != EOF && c != '/n'; ++i)
  31.     line[i] = c;
  32.   if (c == '/n') {
  33.     line[i] = c;
  34.     ++i;
  35.   }
  36.   line[i] = '/0';
  37.   return i;
  38. }
  39. /* copy: specialized version */
  40. void copy(void)
  41. {
  42.   int i;
  43.   extern char line[], longest[];
  44.   i = 0;
  45.   while ((longest[i] = line[i]) != '/0')
  46.     ++i;
  47. }
说明:
  1、外部变量必须在任何函数外部被定义一次,每个使用函数中必须被显示(extern)或隐式声明;
  2、下面情况下extern可以省略,外部变量在源文件中使用其函数之前定义的可以省略;
  3、如果程序由多个源文件组成,通常情况下把所有外部变量集中在一个头文件中声明,其他源文件引用该头文件即可;
  4、变量定义是指变量被创建或分配内存的地方,声明是指变量形式被指明但不进行内存分配的地方;
  5、鉴于外部变量的不可控性,容易引起不可预期的修改及维护困难,正逐渐被其他方式替代;


原创粉丝点击