The C programming language (second edition,K&R) exercise(CHAPTER 3)

      E x c e r c i s e 3 − 1 Excercise\quad 3-1 Excercise31:输出结果如图1所示,这里故意让二分搜索算法去寻找一个在数组中不存在在的数,然后去看两种二分搜索算法分别所花费的时间的大小,为了使得所花费的时间更具有可分辨性,这里让搜索过程重复执行了 100000000 100000000 100000000次。

/* Solution by Paul Griffiths (mail@paulgriffiths.net) */

/*
  
  EX3_1.C
  =======

  Suggested solution to Exercise 3-1

*/

#include <stdio.h>
#include <time.h>

int binsearch(int x, int v[], int n);     /*  Original K&R function  */
int binsearch2(int x, int v[], int n);    /*  Our new function       */

#define MAX_ELEMENT 200000


/*  Outputs approximation of processor time required
    for our two binary search functions. We search for
    the element -1, to time the functions' worst case
    performance (i.e. element not found in test data)   */

int main(void) 
{
    int testdata[MAX_ELEMENT];
    int index;                  /*  Index of found element in test data  */
    int n = -1;                 /*  Element to search for  */
    int i;
    clock_t time_taken;

    /*  Initialize test data  */
    
    for ( i = 0; i < MAX_ELEMENT; ++i )
        testdata[i] = i;
    
    
    /*  Output approximation of time taken for 100000000 iterations of binsearch() */
    
    for ( i = 0, time_taken = clock(); i < 100000000; ++i ) 
	{
        index = binsearch(n, testdata, MAX_ELEMENT);
    }
    time_taken = clock() - time_taken;
    
    if ( index < 0 )
        printf("Element %d not found.\n", n);
    else
        printf("Element %d found at index %d.\n", n, index);
    
    printf("binsearch() took %lu clocks (%lu seconds)\n",
           (unsigned long) time_taken,
           (unsigned long) time_taken / CLOCKS_PER_SEC);
    
    
    /*  Output approximation of time taken for 100000000 iterations of binsearch2() */
    
    for ( i = 0, time_taken = clock(); i < 100000000; ++i ) 
	{
        index = binsearch2(n, testdata, MAX_ELEMENT);
    }
    time_taken = clock() - time_taken;
    
    if ( index < 0 )
        printf("Element %d not found.\n", n);
    else
        printf("Element %d found at index %d.\n", n, index);
    
    printf("binsearch2() took %lu clocks (%lu seconds)\n",
           (unsigned long) time_taken,
           (unsigned long) time_taken / CLOCKS_PER_SEC);
    
    return 0;
}


/* binsearch:find x in v[0] <= v[1] <= ... v[n-1] */

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

/* binsearch2:find x in v[0] <= v[1] <= ... v[n-1] */

int binsearch2(int x, int v[], int n) 
{
    int low, mid, high;
    
    low = 0;
    high = n - 1;
    mid = (low+high) / 2;	
    while (( low < high ) &&(x != v[mid]))
	{
        if ( x < v[mid] )
            high = mid - 1;
        else
            low = mid + 1;
        mid = (low+high) / 2;		
    }
    if ( x == v[mid] )
        return mid;
    else
        return -1;
}
 
图1.

      E x c e r c i s e 3 − 2 Excercise\quad 3-2 Excercise32:输出结果如图2所示

#include <stdio.h>

void escape(char s[], char t[]);  
void unescape(char s[], char t[]); 
int main(void) 
{
    char text1[100] = "\aHello,\n\tWorld! Mistakee\b was \"Extra 'e'\"!\n";
    char text2[100];
    char text3[100];    
    printf("Original string:\n%s\n", text1);
    
    escape(text2, text1);
    printf("Escaped string:\n%s\n", text2);
    
    unescape(text2, text3);
    printf("Unescaped string:\n%s\n", text3);
    
    return 0;
}


/*  Copies string t to string s, converting special
    characters into their appropriate escape sequences.
    The "complete set of escape sequences" found in
    K&R Chapter 2 is used, with the exception of:
    
    \? \' \ooo \xhh
    
    as these can be typed directly into the source code,
    (i.e. without using the escape sequences themselves)
    and translating them is therefore ambiguous.    */
void escape(char s[], char t[]) 
{
    int i=0;
    int j=0;
    while ( t[i]!='\0' ) 
	{
        switch (t[i])
		{
			case '\t':
			    s[j++]='\\';
			    s[j++]='t';			
			    break;
			case '\n':
			    s[j++]='\\';
			    s[j++]='n';				
			    break;	
			case '\a':
			    s[j++]='\\';
			    s[j++]='a';			
			    break;
			case '\b':
			    s[j++]='\\';
			    s[j++]='b';			
			    break;
			case '\f':
			    s[j++]='\\';
			    s[j++]='f';			
			    break;
			case '\r':
			    s[j++]='\\';
			    s[j++]='r';			
			    break;
			case '\v':
			    s[j++]='\\';
			    s[j++]='v';			
			    break;	
			case '\"':
			    s[j++]='\\';
			    s[j++]='\"';			
			    break;
			case '\\':
			    s[j++]='\\';
			    s[j++]='\\';			
			    break;								
			default:
			    s[j++]=t[i];			
			    break;			
		}
		i++;
    }
	s[j]='\0';
}

/*  Copies string s to string t, converting escape sequences
    into their appropriate special characters. See the comment
    for escape() for remarks regarding which escape sequences
    are translated. */
void unescape(char s[], char t[]) 
{
    int i=0;
    int j=0;
    while ( s[i]!='\0' ) 
	{
        switch (s[i])
		{
			case '\\':
                switch (s[++i])
		        {
		        	case 't':
		        	    t[j++]='\t';		
		        	    break;
		        	case 'n':
		        	    t[j++]='\n';			
		        	    break;	
		        	case 'a':
		        	    t[j++]='\a';		
		        	    break;
		        	case 'b':
		        	    t[j++]='\b';		
		        	    break;
		        	case 'f':
		        	    t[j++]='\f';		
		        	    break;
		        	case 'r':
		        	    t[j++]='\r';		
		        	    break;
		        	case 'v':
		        	    t[j++]='\v';		
		        	    break;
		        	case '\"':
		        	    t[j++]='\"';			
		        	    break;
		        	case '\\':
		        	    t[j++]='\\';		
		        	    break;
                    default:
                
                /*  We don't translate this escape
                    sequence, so just copy it verbatim  */                
                        t[j++] = '\\';
                        t[j++] = t[i];						
		        }			
			    break;								
			default:
			    t[j++]=s[i];			
			    break;			
		}
		++i;
    }
	t[j]='\0';
}
 
图2.

      E x c e r c i s e 3 − 3 Excercise\quad 3-3 Excercise33:输出结果如图3所示。

#include <stdio.h>

#define MAXIMUM 1000

void expand(char s1[], char s2[]);
int is_valid(char c);

int main()
{
    char s1[MAXIMUM] = "-A-C-E-I first a-z0-9 second -a-z third   9-2 fourth   6-6- end-";	
    char s2[MAXIMUM];
    printf("%s\n", s1);
    expand(s1, s2);
    printf("%s\n", s2);
    return 0;
}

void expand(char s1[], char s2[]) 
{
    char c, d;
    int i, j;
    i = j = 0;

    while ('\0' != (c = s1[i++])) 
	{
        if (is_valid(c) && '-' == s1[i]  && is_valid(s1[i + 1])) 
		{
            i++;
            d = s1[i];
            if (c > d) 
			{
                while (c > d) 
				{
                    s2[j++] = c--;
                }
            }
            else 
			{
                while (c < d) 
				{
                    s2[j++] = c++;
                }
            }
        }
        else 
		{
            s2[j++] = c;
        }
    }
    s2[j] = '\0';
}

int is_valid(char c)
{
    if(((c>='a') && (c<='z'))	|| ((c>='A') && (c<='Z'))	|| ((c>='0') && (c<='9')))
	{
		return 1;
	}
	else
	{
		return 0;
	}	
}
 
图3.

      E x c e r c i s e 3 − 4 Excercise\quad 3-4 Excercise34:下面我们首先来看一段代码以及输出,输出结果如图4所示。这里 i n t int int型变量能表示的数的最大范围是 [ − 2147483648 , 2147483647 ] [-2147483648,2147483647] [2147483648,2147483647],这里我们可以看到 i n t int int型可以表示的最大负数的绝对值要比 i n t int int型可以表示的最大正数的值大一(其它类型的有符号数的类型也是一样的),当我们在尝试使用书中的那个版本的 i t o a itoa itoa接口来将 i n t int int型可以表示的最大负数 − 2147483648 -2147483648 2147483648转换为字符串的时候会出现问题。书中的那个版本的 i t o a itoa itoa接口会首先将要转换的负数变成正数,但是对于 i n t int int型,它可以表示的最大正数是 2147483647 2147483647 2147483647,因此从图4中我们可以看到 i n t u = − i ; int u=-i; intu=i;操作之后 u u u的值还是 − 2147483648 -2147483648 2147483648,因此书中的那个版本的 i t o a itoa itoa接口中的 d o w h i l e do\quad while dowhile循环只会运行一次且就算是这一次对个位数的转换也是错误的,这是因为这一次循环中 n % 10 n\%10 n%10操作的结果是 − 8 -8 8,因此 n % 10 + ′ 0 ′ n\%10+'0' n%10+0操作的结果是 40 40 40(字符 ′ 0 ′ '0' 0 A S C I I ASCII ASCII码值是48,字符 ′ ( ′ '(' ( A S C I I ASCII ASCII码值是40,),因此这里并没有得到我们所预期的字符 ′ 8 ′ '8' 8。为了能够成功实现对 i n t int int型可以表示的最大负数的转换,改进后的程序在判断 d o w h i l e do\quad while dowhile循环的执行的时候改为 w h i l e ( n / = 10 ) ; while ( n /= 10 ); while(n/=10);,而不是 w h i l e ( ( n / = 10 ) > 0 ) ; while( ( n /= 10 )>0); while((n/=10)>0);也就是不为0就可以继续执行循环,且改进后的程序在求余数之后做了绝对值的操作。

#include <stdio.h>
#include <limits.h>


int main(void)
{
	char c='\0';
	printf("sizeof(int)=%d\n",sizeof(int));
    printf("Signed int[%d to %d]\n", INT_MIN, INT_MAX);
    printf("Unsigned int[0 to %u]\n", UINT_MAX);
    int i=-2147483648;
    int u=-i;	
	printf("i=%d\n",i);	
	printf("u=%d\n",u);			
	c=(u%10)+'0';
	printf("c=%d\n",c);	
	printf("c=%c\n",c);		
	return 0;
}
 
图4.
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>

void itoa_myself(int n, char s[]);
void reverse(char s[]);

int main(void) 
{
    char buffer[100];
    
    printf("INT_MIN: %d\n", INT_MIN);
    itoa_myself(INT_MIN, buffer);
    printf("Buffer : %s\n", buffer);
    
    return 0;
}

void itoa_myself(int n, char s[]) 
{
    int i, sign;
    sign = n;
    
    i = 0;
    do 
	{
        s[i++] = abs(n % 10) + '0';
    } while ( n /= 10 );
    if (sign < 0)
        s[i++] = '-';
    
    s[i] = '\0';
    reverse(s);
}

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

      E x c e r c i s e 3 − 5 Excercise\quad 3-5 Excercise35

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void itob(int n , char s[], int b);
void reverse(char s[]);

#define MAXIMUM 100

int main(){
    int b = 16;
    char s[MAXIMUM];
    itob(-2147483648,s,b);
    printf("Base %d = %s\n",b,s);
    return 0;
}

void itob(int n, char s[], int b)
{
    int i = 0;
	int negative=0;
	if(n<0)
	{
		negative=-1;			
	}
    if((b!=2) && (b!=8) && (b!=16)) 
	{		
	    printf("base error\n");	
	}		
    do
    {
        if (abs(n%b)>9)
            s[i++]= abs(n%b) +'A'-10;
        else
            s[i++] = abs(n%b) +'0';
    } while ((n/=b));
	if(negative==-1)
	{
		s[i++]='-';			
	}
    s[i] = '\0';	
    reverse(s);
}

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

      E x c e r c i s e 3 − 6 Excercise\quad 3-6 Excercise36

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>

void itoa_myself(int n, char s[], int minmum);
void reverse(char s[]);

int main(void) 
{
    char buffer[100];
    
    printf("INT_MIN: %d\n", INT_MIN);
    itoa_myself(INT_MIN, buffer,25);
    printf("Buffer : %s\n", buffer);
    
    return 0;
}

void itoa_myself(int n, char s[], int minmum) 
{
    int i, sign;
    sign = n;
    
    i = 0;
    do 
	{
        s[i++] = abs(n % 10) + '0';
    } while ( n /= 10 );
    if (sign < 0)
        s[i++] = '-';
	while(i<minmum)
	{
        s[i++] = ' ';		
	}	
    s[i] = '\0';
    reverse(s);
}

void reverse(char s[]) 
{
    int c, i, j;
    for ( i = 0, j = strlen(s)-1; i < j; i++, j--) 
	{
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}
  • 27
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值