the c programming language second edition第三章控制流 例子及练习题上

例1 if-else语句中的歧义性

#include 
#include 
int main()
{
int i,n=9
int s[7]={};
printf("%d\n",s[8])
if(n>=0)
for(i=0;i<8;i++)
if(s[i]>0)
{
printf("...");
return i;
}
else 
printf("error--n is negative\n");
}

the c programming language second edition第三章控制流 例子及练习题上_第1张图片

1.发现了if-else语句中else会与最近的前一个没有else配对的if进行匹配
2.明白了缩进结构return语句可以提前结束控制流
3.发现了超过数组在C中必须先分配空间超过后便是一个随机数字

例2 else-if语句中的折半查找函数

  • 目的是设置一个函数来判定已排序的数组V中是否存在某个特定的X。数组V的元素必须为升序排列。如果V中包含X则该函数返回X在V中的位置;否则该函数返回-1
#include 
#include 
int main()
{
int x;
printf("请输入想要查找的数字:");
scanf("%d",&x);
printf("此时数字的位置:%d\n", binsearch(x)+1);
}
int binsearch();
int binsearch(int x)
{
int  v[10]={5,11,22,34,55,56,57,61,77,79};
int  min,max,mid;
min=0;
max=9;
while(min<=max)
{
   mid=(min+max)/2;
   if(xv[mid])
       min=mid+1;
   else
       return  mid;
}
return -1;
}

the c programming language second edition第三章控制流 例子及练习题上_第2张图片

  • 折半法查找函数使运算效率提升:折半查找应注意的是折半的是元素的位置而不是元素大小,它是通过元素的位置进行比较,所以前提下必须数组元素必须是升序或者降序,这个过程一直进行下去直到找到指定的值或查找范围为空

练习3-1在上面有关折半查找的例子中while循环语句内共执行了两次测试其实只要一次就足够(代价时将更多的测试在循环外执行)。重写该函数使得在循环内部只执行一次测试。比较两种版本函数的运行时间

int  binsearch(int x;int v[],int n)
{
int low,mid,high;
low=0;
high=n-1;
mid=(high+low)/2;
while(low<=high&&x!=v[mid])
{
if(x

我们可以认识到循环的条件变化与if的判断语句可以联系到一起从而完成所要求的函数
两种方案的执行时间几乎没有什么差异也并没有得到多大的性能改进反而缺失了代码可读性

例三用switch语句中统计数字,空白符及其他字符的函数

  • 是本人的写法所以略有粗糙
#include 
#include 
#include 
#include 
int main()
{
   count();
}
void count(char s[]);
void count(char s[])
{
    int a=0;//统计数字
    int b=0;//统计空白符
    int c=0;//统计其他字符
    int i;
    int d;//用于判断真假
    s=(char *)malloc(100);
    gets(s);
    for(i=0;s[i]!='\0';i++)
    {
        if(isdigit(s[i])!=0)
            d=1;
       else if(s[i]==' '||s[i]=='\n'||s[i]=='\t')
            d=0;
       else
           d=-1;
       switch(d)
       {
       case 1:
         a++;
         break;
       case 0:
         b++;
         break;
       default :
         c++;
         break;
       }
    }
    printf("dight=%d\n",a);
   printf("white space=%d\n",b);
     printf("nother=%d\n",c);
}

the c programming language second edition第三章控制流 例子及练习题上_第3张图片

此方法用了字符串的录入(需要动态分配空间)和switch语句的运用

  • 书上的写法与本人写法运算时间相差不大
#include 
#include 
#include 
#include 
int main()
{
    int c;
    int i;
    int a=0,b=0;
    int d[10];
    for(i=0;i<10;i++)
        d[i]=0;
    while((c=getchar())!=EOF)
    {
        switch(c)
        {
        case '0':case '1':case '2':case '3':case '4':case '5':
            case '6':case '7':case '8':case '9':
                d[c-'0']++;
                break;
            case ' ':
            case '\n':
            case '\t':
                a++;
                break;
            default :
                b++;
                break;
        }
    }
    printf("dight=");
    for(i=0;i<10;i++)
        printf("%d",d[i]);
    printf(",white=%d,other=%d\n",a,b);

}

the c programming language second edition第三章控制流 例子及练习题上_第4张图片

练习3-2 编写一个函数escape(s,t),将字符串t复制到字符串s中并在复制过程中将换行符,制表符等不可见字符分别转为\n,\t等相应的的课件转义字符序列。要求使用switch语句。z再编写一个具有相反功能的函数,在复制过程中将转义字符序列转换为实际字符

  • 将字符串t复制进字符串s
    转换字符
#include 
#include 
void escape(char s[],char t[]);
void escape(char s[],char t[])
{

    int i,j;
    printf("输入字符串:");
    gets(t);
    for(i=j=0;t[i]!='\0';i++)
    {
       switch(t[i])
       {
       case '\n':
        s[j++]='\\';
        s[j++]='n';
        break;
       case '\t':
        s[j++]='\\';
        s[j++]='t';
        break;
     default :
        s[j++]=t[i];
        break;
       }
    }
    s[j]='\0';
}
int main()
{
    int i;
    char s[100],t[100];
    escape(s,t);
    printf("复制后的字符串:");
    for(i=0;s[i]!='\0';i++)
    {
        printf("%c",s[i]);
    }
}

处理结果也就是简单的复制进去只不过我也不是很明白怎么输入换行符和制表符等不可见的字符

  • 相反的函数与原函数很相似
#include 
#include 
void unescape(char s[],char t[]);
void unescape(char s[],char t[])
{
int i,j;
for(i=j=0;t[i]!='\0';i++)
  {
    switch(t[i])
    {
    case '\\':
             switch(t[++i])
             {
             case 'n':
                   s[j++]='\n';
                   break;
             case 't':
                   s[j++]='\t';
                   break;
              defalut:
                  s[j++]='\\';
                  s[j++]=t[i];
                  break;
             }
      defalut :
      s[j++]=t[i];
      break;
          }
  }
  s[j]='\0';
}

此函数运用到了switch语句的嵌套的使用,外层的switch语句负责区分反斜杠和其他字符,反斜杠的分支还嵌套着另一条switch语句

例子4while与for循环中atoi函数是将字符串转换为对应数值

  • 下面是程序的结构:
    如果有空白符则跳过
    如果有符号的话则读取符号
    取整数部分并执行转换
#include 
#include 
#include 
#include 

int aatoi();
int aatoi()
{
   int   i,n=1;
   int   b=0;
   char  a[100];
   printf("请输入字符串:");
   gets(a);
   for(i=0;a[i]!='\0';i++)
   {
       if(a[i]==' ')
            ;
      else if(a[i]=='-')
            n=-n;

      else if(a[i]=='+')
            n=1;
      else if(isdigit(a[i])!=0)
            b=b*10+(a[i]-'0');

   }
   return b*n;
}
int main()
{
  printf("提取字符串数字转换为整型:%d",aatoi());
}

在这里插入图片描述
此函数便是将字符串中的数字提取出来变成Int类型(此为本人的想法)

书中提供的函数为

int a(char s[])
{
    int i,n,sign;
    for(i=0;isspace(s[i]);i++)
        ;    //跳过空白符
    sign=(s[i]=='-')? -1: 1;
    if(s[i]=='+'||s[i]=='-')
        i++; //跳过符号
    for(n=0;isdigit(s[i]);i++)
        n=10*n+(s[i]-'0');//输出字符串里面的数字
    return sign*n;
}

书中提供的函数并没有完善此功能只能处理第一个空格并不能处理后面的其他内容

  • 用while跳过空白符
while((c=getchar())==' '||c=='\n'||c=='\t');

例5希尔排序算法

  • 先比较距离远的元素,这可以快速减少大量的无序情况,从而减轻后续的工作。被比较的元素之间的距离逐步减少直到减少为1,这时排序变成了相邻元素的互换。算是一种比较高级的插入排序
#include 
#include 
void shellsort(int v[],int n);
void shellsort(int v[],int n)
{
    int i,j,gap,temp;
    for(gap=n/2;gap>0;gap/=2)
        for(i=gap;i=0&&v[j]>v[gap+j];j-=gap)
    {
        temp=v[j];
        v[j]=v[j+gap];
        v[j+gap]=temp;
    }
}
int main()
{
    int i;
    int v[8]={0,2,3,4,5,6,10,8};
    int n=8;
    shellsort(v,n);
    for(i=0;i<8;i++)
    printf("%d\n",v[i]);
}

the c programming language second edition第三章控制流 例子及练习题上_第5张图片

例6reverse函数:倒置字符串中各个字符的位置

#include 
void reverse(char s[])
{
int c,i,j;
for(i=0,j=strlen(s)-1;i

练习3-3 编写函数expand(s1,s2),将字符串S1类似于a-z之类的速记符号在字符串s2中扩展为等价的完整列表abc…xyz 等。该函数可以处理大小写字母和数字,并可以处理a-b-c与-a-z等类似的情况。作为前导和尾随的-字符原样排印

  • 本人程序
#include 
#include 
void expand(char s1[],char s2[]);
void expand(char s1[],char s2[])
{
     int i,j=0;
     char a,b;
     for(i=0;s1[i]!='\0';i++)
     {
           a=s1[i];
           b=s1[i+2];
                if(s1[i+1]=='-'&&a<=b)
           {
               for(j=0;a<=b;j++)
               {
                   s2[j]=a++;
               }
           }
     }
      s2[j]='\0';
}
int main()
{
    int i;
    char s1[50];
    char s2[100];
    gets(s1);
    expand(s1,s2);
    for(i=0;s2[i]!='\0';i++)
    printf("%c",s2[i]);
}

在这里插入图片描述

  • 书上答案
void expand(char s1[],char s2[])
{
    char c;
    int i,j;
    i=j=0;
    while((c=s1[i++])!='\0')
        if(s1[i]=='-'&&s1[i+1]>=c)
        {
            i++;
            while(c

你可能感兴趣的:(C程序设计语言的学习)