[复习]The C Programming Language 2nd 习题集(1.1-1.10)

买不起iPhone4,只能弄了一台iTouch4,想尝试一下iOS上的开发,虽然有monoTouch可用,但是这东西要399美金授权,换成RMB好几千块了,算了,为了省钱,还是老老实实复习C 吧,然后升级到Objective-C。

1.1 在你自己的系统中运行“hello, world”程序。再有意去掉程序中的部分内容,看看会得到什么出错信息。

#include <stdio.h> //虽然默认已经包括了stdio.h,但还是建议加上,以保证代码结构清晰 

//main函数总是返回int,虽然这个int不是必须,但是建议加上,以养成良好的习惯 
int main(void)
{
  printf("hello, world\n");
  system("pause");//暂停,否则程序一闪而过(相当于c#中的Console.Read()) 
  return 0; //明确给出返回值,虽然可省略,但是建议写上,main函数也需要向运行环境返回值 
}

1.2 做个实验,当printf 函数的参数字符串中包含\c(其中c 是上面的转义字符序列中未曾列出的某一个字符)时,观察一下会出现什么情况。

#include <stdio.h>
 
int main(void)
{
  //注:建议使用标准的转义字符(\n,\t,\b,\",\\之类),如果使用非标准的转义字符,结果将变得不可预期(比如下面的\a,\f,\r,\v 之类) 
  printf("\\Audible or visual alert. \a\n");  
  printf("Form feed. \f\n");
  printf("This escape, \r, moves the active position to the initial position of the current line.\n");
  printf("Vertical tab \v is tricky, as its behaviour is unspecified under certain conditions.\n");
  system("pause");
  return 0;
}

1.3 修改温度转换程序,使之能在转换表的顶部打印一个标题。

#include <stdio.h>

int main(void){ 
       printf("%2.1f",1.234);      
       float fahr,celsius;
       int lower,upper,step;
       
       lower = 0;
       upper = 300;
       step = 20;
       
       printf("华氏温度\t摄氏温度\n");
       fahr = lower;
       while(fahr <= upper){
                  celsius = (5.0/9) * (fahr - 32.0);//注:5/9最终的结果为int型,即0;而5.0/9结果为float型(int型9会自动转化为float) 
                  printf("%8.0f\t%8.1f\n",fahr,celsius);//注:%8.1f表示 不算小数点,总共占8位,其中小数位为1位 
                  fahr += step;
       }       
       system("pause");
       return 0;
}

1.4 编写一个程序打印摄氏温度转换为相应华氏温度的转换表。

#include <stdio.h>

int main(void){
       float fahr, celsius;
       int lower=0, upper=300, step=20;    
 
       printf("摄氏温度\t华氏温度\n");
       celsius = lower;
       while(celsius <= upper){
          fahr = (9.0/5.0) * celsius + 32.0;
          printf("%8.0f\t%7.1f\n", celsius, fahr);
          celsius = celsius + step;
       }
       system("pause");
       return 0;
}

1.5 修改温度转换程序,要求以逆序(即按照从300 度到0 度的顺序)打印温度转换表

#include <stdio.h>

int main(void)
{
       float fahr, celsius;
       int lower=0, upper=300, step=20;    
 
       printf("摄氏温度\t华氏温度\n");      
       for(celsius=upper;celsius>=lower;celsius-=step)
       {
           fahr = (9.0/5.0) * celsius + 32.0;
           printf("%8.0f\t%7.1f\n", celsius, fahr);                                           
       }       
       system("pause");
       return 0;
}

1.6 验证表达式getchar() != EOF的值是0还是1。

#include <stdio.h>
 
int main(void)
{
  printf("随便按个键,Ctrl+D或Ctrl+Z代表EOF\n");
  printf("表达式 getchar() != EOF 的值为 %d\n", getchar()!= EOF);
  system("pause");
  return 0;
}

1.7 编写一个打印EOF值的程序。

#include <stdio.h>
 
int main(void)
{
  printf("EOF的值用数字表示为:%d\n", EOF);
  system("pause");  
  return 0;
}

1.8 编写一个统计空格、制表符与换行符个数的程序。

#include <stdio.h>

int main(void)
{   
    printf("请输入一些字符,ctrl+Z 或 ctrl+D 结束:\n");
    int c,blanks,tabs,newlines,done,lastchar;
    c = blanks = tabs = newlines = done = 0;
    while(done==0){
        c = getchar();
        if (c==' ')
           ++blanks;
        
        if(c=='\t')
            ++tabs;          
        
        if(c=='\n')
            ++newlines;
        
        if (c==EOF)
        {
            //根据The C Answer Book一书上的解释,下面的处理是为了应付“某文本文件可能并不以换行符结尾”的情况,
            //但我在windows console应用程序里试不出来,因为不按回车,字符根本就没送到while循环里,所以就算最后打一个Ctrl+Z,不敲回车也白费

            if (lastchar!='\n')
            {
               ++newlines;
            }
            done = 1;            
        }
        lastchar = c;
    }       
    printf("刚才输入的字符中,空格有%d个,制表符有%d个,换行符有%d个\n",blanks,tabs,newlines);
    
    system("pause");
    return 0;
}

1.9 编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替。

解法1

#include <stdio.h>
 
int main(void)
{
  int c;
  int inspace=0;//用来判断是不是遇到了连续空格(0否,1是) 
 
 
  while((c = getchar()) != EOF)
  {
    if(c == ' ')
    {
      //如果未遇到连续空格(即前一个字符是否为空格) 
      if(inspace == 0)
      {                 
        inspace = 1;//先假设下一个字符也是空格(即连续空格) 
        putchar(c);//显示第一个字格 
      }
    }
 
    /* 因为书中到目前为止,还未讲到yet关键字,所以这里暂用二个不太优雅的连续if语句处理 */
    
    //如果下一个字符不是空格 
    if(c != ' ')
    {
      inspace = 0;//纠正上一个if中的"连续空格假设",并inspace重新设置为0,即非连续空格 
      putchar(c);//显示下一个非空格字符 
    }
  }
  system("pause");
  return 0;
}

解法2

#include <stdio.h>

int main(void)
{
    int c,pc;//c用来保存当前字符,而pc即previous charactor前一个字符 
    pc = EOF;//将前一个字符设置为EOF,这样不匹配任何字符
    while((c=getchar())!=EOF)
    {
       if (c==' ') //如果当前字符为空格 
          if (pc!=' ') //继续判断上一个字符是否为空格 
             putchar(c); //如果不是连续空格,则输出该字符 
       
       if (c!=' ') //因为原书到目前为止仍未讲到else关键字,这里暂时用二个连续if语句处理 
          putchar(c);
       
       pc = c; //"更新"前一个字符的值 
    } 
    system("pause");
    return 0;
}

解法3

#include <stdio.h>

int main(void)
{
    int c;
    while((c=getchar())!=EOF)
    {
      if (c==' ')
      {
         putchar(c);
         while((c=getchar())==' ' && c !=EOF) //继续接受下一个字符,如果下一个字符是空格,且没有输入结束符       
            ;//什么也不干,即无视该连续的空格         
      }
      if (c==EOF)//遇到结束符,则退出 
         break;
      
      putchar(c);//注:这里实际上是输出第二个while循环中的“合法”字符 
    }
    return 0;
}

1.10 编写一个将输入复制到输出的程序,并将其中的制表符替换为\t,把回退符替换为\b,把反斜杠替按为\\。这样可以将制表符和回退符以可见的方式显示出来。

解法1

#include <stdio.h>

int main(void)
{
    int c,d;//d用来判断是否指定的转义字符(1是,0否) 
    while((c=getchar())!=EOF)
    {
       d=0;
       if (c=='\\')
       {
          //连续输出二个'\' 
          putchar('\\');
          putchar('\\');
          d = 1;
       }  
       if (c=='\t')
       {
          //输出'\t' 
          putchar('\\');
          putchar('t');
          d = 1;
       } 
       if (c=='\b')
       {
          putchar('\\');
          putchar('b');
          d = 1;
       } 
       if (d==0) //如果不是指定转义字符,则输出(注:如果去掉此判断,则仍然会以不可见方式输出转义字符) 
          putchar(c);  
    }
    system("pause");
    return 0;
}

解法2

#include <stdio.h>

#define ESC_CHAR '\\' //相当于定义了一个"字符常量" 

int main(void)
{
  int c;

  while((c = getchar()) != EOF)
  {
    switch(c)
    {
      case '\b':        
        putchar(ESC_CHAR);
        putchar('b');
        break;
      case '\t':
        putchar(ESC_CHAR);
        putchar('t');
        break;
      case ESC_CHAR:
        putchar(ESC_CHAR);
        putchar(ESC_CHAR);
        break;
      default:
        putchar(c);
        break;
    }
  }
  system("pause");
  return 0;
}



posted @ 2010-12-06 17:02  菩提树下的杨过  阅读(2731)  评论(4编辑  收藏  举报