zoukankan      html  css  js  c++  java
  • The C Programming Language (second edition) 实践代码(置于此以作备份)

    1、

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include<time.h>
    
    #define myPrint(expr) printf(#expr " =%d
    ",expr);
    //2-3
    int htoi(char *s)
    {
        int n=0;
        while(*s!='')
        {
            if (*s=='x' || *s=='X')
            {
                n=0;
            }
            else if ('0'<=*s && *s<='9')
            {
                n=n*16+(*s-'0');
            }
            else if ('a'<=*s && *s<='z')
            {
                n=n*16+(*s-'a'+10);
            }
            else if ('A'<=*s && *s<='Z')
            {
                n=n*16+(*s-'A'+10);
            }
            s++;
        }
        return n;
    }
    void swap(int &x,int &y)
    {
        x^=y;
        y^=x;
        x^=y;
    }//x,y不能是数组的同一个元素
    
    unsigned getbits(unsigned x,int p,int n)
    {//从右向左数从0起,取从p开始向右的n个位,的值
        return (x>>(p+1-n)) & ~(~0<<n);
    }
    //2-6
    unsigned setbits(unsigned x,int p,int n,unsigned y)
    {//把x从右起从0起向右的n位置为y最右n位
        y&=~(~0<<n);//得到y最右n位
        y<<=(p+1-n);//最右n位左移到与x中间n位对应的位置上
    
        y|=x & (~(~0<<n));//使y最右n位与x最右n位一样
        x>>=(p+1);
        x<<=(p+1);//得到x里p位置左边的部分
        y|=x;
        return y;
    }
    //2-7
    unsigned invert(unsigned x,int p,int n)
    {
        //return setbits(x,p,n,~getbits(x,p,n));
        return x ^(~(~0<<n)<<(p-n+1));
    }
    //2-8
    unsigned rightrot(unsigned x,int n)
    {//0^a=a,1^a=~a
        return ((~(~0<<n) & x)<<(sizeof(unsigned)*8-n)) ^ (x>>n);
    }
    
    //递归,将一个整数作为字符串打印
    int isNegtive=1;
    void printd(int n)
    { if(n<0 && isNegtive)
      {
          putchar('-');
          isNegtive=0;
      }
      if (n/10)
      {
          printd(n/10);
      }
      //putchar((n%10<0)?(abs(n%10)+'0'):(n%10+'0'));//int最小值的相反数仍是该数
    putchar(abs(n%10)+'0'); }
    //递归,将一个正整数作为字符串打印
    void printd(unsigned int n)
    { 
      if (n>=10)
      {
          printd(n/10);
      }
      putchar(n%10);
    }

    //快排的另一种写法 void quickSort(int data[],int left,int right) { int i,last; if(left>=right) return; //partition last=left; for (i=left+1;i<=right;i++) { if ((data[i]<data[left]) && (++last!=i)) { data[last]^=data[i]; data[i]^=data[last]; data[last]^=data[i]; } } if(last!=left) { data[left]^=data[last]; data[last]^=data[left]; data[left]^=data[last]; } //recursive quickSort(data,left,last-1); quickSort(data,last+1,right); } int binSearch(int data[],int n,int num) { int low,high,mid; low=0; high=n-1; while (low<=high) { mid=(low+high)/2; if (num==data[mid]) return mid; else if (num>data[mid]) low=mid+1; else high=mid-1; } return -1; } int main() { int c=1,d=2; swap(c,d); printf("c:%d d:%d ",c,d); printf("%u ",getbits(-2,2,3)); printf("%u ",setbits(25,4,3,1)); printf("%u ",invert(32,4,3)); printf("%x ",rightrot(0xff00ff,4)); extern void mytest(); mytest(); int testdata[]={4,3,2,5,6,9,8}; quickSort(testdata,0,6); for (c=0;c<7;c++) { printf("%d ",testdata[c]); } printf(" a" " b%d ",3);//前面的两个字符串将被连接起来 myPrint(c); return 0; } void mytest() { extern int num; printf(" %d ",num); } int num=2;

    2、

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include<time.h>
    #include <string.h>
    #include <limits.h>
    //2-3
    int htoi(char *s)
    {
        int n=0;
        while(*s!='')
        {
            if (*s=='x' || *s=='X')
            {
                n=0;
            }
            else if ('0'<=*s && *s<='9')
            {
                n=n*16+(*s-'0');
            }
            else if ('a'<=*s && *s<='z')
            {
                n=n*16+(*s-'a'+10);
            }
            else if ('A'<=*s && *s<='Z')
            {
                n=n*16+(*s-'A'+10);
            }
            s++;
        }
        return n;
    }
    unsigned getbits(unsigned x,int p,int n)
    {//从右向左数从0起,取从p开始向右的n个位,的值
        return (x>>(p+1-n)) & ~(~0<<n);
    }
    //2-6
    unsigned setbits(unsigned x,int p,int n,unsigned y)
    {//把x从右起从0起向右的n位置为y最右n位
        y&=~(~0<<n);//得到y最右n位
        y<<=(p+1-n);//最右n位左移到与x中间n位对应的位置上
        
        y|=x & (~(~0<<n));//使y最右n位与x最右n位一样
        x>>=(p+1);
        x<<=(p+1);//得到x里p位置左边的部分
        y|=x;
        return y;
    }
    //2-7
    unsigned invert(unsigned x,int p,int n)
    {
        //return setbits(x,p,n,~getbits(x,p,n));
        return x ^(~(~0<<n)<<(p-n+1));
    }
    //2-8
    unsigned rightrot(unsigned x,int n)
    {//0^a=a,1^a=~a
        return ((~(~0<<n) & x)<<(sizeof(unsigned)*8-n)) ^ (x>>n);
    }
    //2-9
    int bitcount(unsigned x)
    {//x的二进制形式中1的个数
        int n=0;
        while(x!=0)
        {
            //         if (x & 1)
            //         {
            //             n++;
            //         }//method1
            {
                x&=(x-1);
                n++;
            }//method2
            x>>=1;
        }
        return n;
    }
    char * reverse(char s[])
    {
        int i,j;
        for (i=0,j=strlen(s)-1;i<j;i++,j--)
        {
            s[i]^=s[j];
            s[j]^=s[i];
            s[i]^=s[j];
        }
        return s;
    }
    //3-4
    char * itoa(int num)
    {//num需在int范围内
        int i=0;
        bool isNegative=num<0?true:false;
        char s[100];//数的位数,包括可能的负号
        if (isNegative)
        {
            do 
            {
                s[i++]=-(num%10)+'0';
                num/=10;
            } while(num!=0);
            s[i++]='-';
        }
        else
        {
            do 
            {
                s[i++]=num%10+'0';
                num/=10;
            } while(num!=0);
        }
        s[i]='';
        reverse(s);
        return s;
    }
    int main()
    {
        char s[]="abcde423546g";
        printf("getbits: %u
    ",getbits(-2,2,3));
        printf("setbits: %u
    ",setbits(25,4,3,1));
        printf("invert:  %u
    ",invert(32,4,3));
        printf("rightrot:%x
    ",rightrot(0xff00ff,4));
        printf("bitcount:%d
    ",bitcount(131));
        printf("reverse: %s
    ",reverse(s));
        printf("itoa:    %s
    ",itoa(INT_MIN));
        printf("itoa:    %s
    ",itoa(INT_MAX));
        return 0;
    }

    3、

    #include <stdio.h>
    #include <stdarg.h>
    #include <stdlib.h>
    
    void printIntArgs(int arg1, ...) /* 输出所有int类型的参数,直到-1结束 */
    {//变长参数表处理
        va_list ap;
        int i;
        va_start(ap, arg1);
        for (i = arg1; i != -1; i = va_arg(ap, int))
            printf("%d ", i);
        va_end(ap);
        putchar('
    ');
    }
    void myPrintf(int a,char *format,...)
    {//变长参数表处理
        char *p;
        
        va_list ap;//参数指针
        
        va_start(ap,a);//初始化ap,指向某个有名参数
        printf("%s
    ",va_arg(ap,int));//再次调用后,ap指向最后一个有名参数。
        //在处理格式串前,必须将ap指向最后一个有名参数
        
        for (p=format;*p;p++)
        {
            if (*p!='%')
            {
                putchar(*p);
                continue;
            }
            switch(*++p)
            {
            case 'd':
                printf("%d",va_arg(ap,int));
                break;
            case 'f':
                printf("%f",va_arg(ap,double));
                break;
            case 's':
                printf("%s",va_arg(ap,char *));
                break;
            case 'c':
                printf("%c",va_arg(ap,char));
                break;
            }
        }
        va_end(ap);
    }
    
    
    
    void myScanf(char *format,...)
    {//变长参数表处理
        char *p;
        
        va_list ap;//参数指针
        
        //在处理格式串前,必须将ap指向最后一个有名参数
        va_start(ap,format);
        
        for (p=format;*p;p++)
        {
            if (*p!='%')
            {
                continue;
            }
            ++p;
            switch(*p)
            {//myScanf实参如&a传的是地址,所以里面参数值就是地址值,因此调用scanf时只要能按指针4字节得到其值即可
            case 'd':
                scanf("%d",va_arg(ap,void *));
                break;
            case 'f':
                scanf("%f",va_arg(ap, void *));
                break;
            case 's':
                scanf("%s",va_arg(ap,void *));
                break;
            case 'c':
                scanf("%c",va_arg(ap,void *));
                break;
            }
        }
        va_end(ap);
    }
    
    
    void scanfFormatTest()
    {//scanf格式特性示例
        char s[20];
        sscanf("123456abcd","%[1-4a-z]",s);
        printf("%s
    ",s);//1234
        s[0]='';
        
        sscanf("123456abcd","%[14az]",s);
        printf("%s
    ",s);//1
        s[0]='';
        
        sscanf("123456abcd","%[^3-4]",s);
        printf("%s
    ",s);//12
        s[0]='';
        
        sscanf("a123456abcd","%[3-4]",s);
        printf("%s
    ",s);//空,虽然串中有34但不是从首字符起的
        s[0]='';
        
        sscanf("123456abcd","%3[0-9a-z]",s);
        printf("%s
    ",s);//123,限定最多读取3个字符
        s[0]='';
        
        sscanf("a123456,abcd","%*c%s",s);
        printf("%s
    ",s);//123456,abcd,*  表示跳过此数据不读入. (也就是不把此数据读入参数中)
        s[0]='';
        
        sscanf("iios/12DDWDFF@122","%*[^/]/%[^@]",s);
        printf("%s
    ",s);//12DDWDFF,综合使用,某种程度上可以充当正则使用
        s[0]='';
    }
    
    
    struct stu
    {
        char name[10];
        int num;
        int age;
        char addr[15];
    }boya[2],boyb[2],*pp,*qq;
    void freadFwriteTest()
    {//fread、fwrite示例
        FILE *fp;
        char ch;
        int i;
        pp=boya;
        qq=boyb;
        if((fp=fopen("stu_list.txt","wb+"))==NULL)
        {
            printf("Cannot open file strike any key exit!");
            getchar();
        }
        printf("input data");
        for(i=0;i<2;i++,pp++)
            scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr);
        pp=boya;
        fwrite(pp,sizeof(struct stu),2,fp);
        rewind(fp);
        fread(qq,sizeof(struct stu),2,fp);
        printf("name number age addr");
        for(i=0;i<2;i++,qq++)
            printf("%s %5d%7d%s",qq->name,qq->num,qq->age,qq->addr);
        fclose(fp);
        getchar();
    }
    
    
    void StderrExitTest(int argc,char *argv[])
    {
        FILE *fp;
        void filecopy(FILE *,FILE *);
        char *prog=argv[0];
        if(argc==1)
            filecopy(stdin,stdout);
        else
        {
            while (--argc>0)
            {
                if ((fp=fopen(*++argv,"r"))==NULL)
                {
                    fprintf(stderr,"%s: can't open %s
    ",prog,*argv);
                    //exit(1);
                }
                else
                {
                    filecopy(fp,stdout);
                    fclose(fp);
                }
            }
        }
        if (ferror(stdout))
        {
            fprintf(stderr,"%s: error writing stdout
    ",prog);
            exit(2);
        }
        exit(0);
    }
    void filecopy(FILE *ifp,FILE *ofp)
    {
        int c;
        while ((c=getc(ifp))!=EOF)
        {
            putc(c,ofp);
        }
    }
    
    
    void ungetcTest()
    {
        char str[100];
        FILE *fp=fopen("file2.txt","r+");//文件file2.txt的内容:jklmn
        
        putc(getc(fp),stdout);//j
        putc(getc(fp),stdout);//k
        
        ungetc ('e', fp);
        ungetc ('f', fp);
        ungetc ('g', fp);
        
        //fscanf(fp,"%s",str);
        //printf("**%s**
    ",str);//**felmn**
        
        putc(getc(fp),stdout);//f
        putc(getc(fp),stdout);//e
        putc(getc(fp),stdout);//l
        
        ungetc ('a', fp);
        ungetc ('b', fp);
        ungetc ('c', fp);
        
        printf ("%c", getc(fp));//c
        printf ("%c", getc(fp));//b
        printf ("%c", getc(fp));//a
        printf ("%c", getc(fp));//m
        printf ("%c", getc(fp));//n
    }
    void mallocMemsetTest()
    {
        int * p=NULL;
        
        p=(int *)malloc(3*sizeof(int));//malloc不能自动初始化
        if(NULL==p){
            printf("Can't get memory!
    ");
            return -1;
        }
        
        printf("%d
    
    ",*p);//未初始化的不定乱值-842150451
        
        memset(p,1,2*sizeof(int));     //用c++的函数memset初始化前两个数
        
        printf("%d
    ",*p);//初始化值16843009
        printf("%d
    ",p[1]==0x01010101);//1,说明每个字节被0x01代替
        printf("%d
    ",p[2]);//未初始化乱值-842150451
        
        *(p+2)=2;
        
        printf("%d
    
    ",p[2]);//2
        
        free(p);//动态分配者在程序结束前必须释放,否则内存泄露
        printf("%d
    ",*p);;//乱值-572662307。free后指针仍指向原来指向的地方,为野指针
        
        return 0;
    }
    
    void callocTest()
    {
        int * p=NULL;
        int i=0;
        int SIZE=10;
        //为p从堆上分配SIZE个int型空间
        p=(int *)calloc(SIZE,sizeof(int));
        //p=(int *)malloc(SIZE*sizeof(int));与上句功能一样,只不过没有自动初始化
    
        if(NULL==p){
            printf("Error in calloc.
    ");
            return -1;
        }
        //输出各个空间的值
        for(i=0;i<SIZE;i++)
            printf("p[%d]=%d
    ",i,p[i]);
    
        //为p指向的SIZE个int型空间赋值
        for(i=0;i<SIZE;i++)
            p[i]=i;
        
        //输出各个空间的值
        for(i=0;i<SIZE;i++)
            printf("p[%d]=%d
    ",i,p[i]);
        
        free(p);
        p=NULL;
        return 0;
    }
    
    
    //模拟c语言中的带缓冲的getchar(), syscalls.h
    int myGetchar(void)
    {
        static char buf[100];
        static char *bufp=buf;
        static int n=0;
        if (n==0)
        {
            n=read(0,buf,sizeof(buf));
            bufp=buf;
        }
        return (n-->0)?(unsigned char)*bufp++:EOF;
    }
    
    int intAverage(int x,int y)
    {//x,y和为负时会出错,如-4、3结果会得到-1,正确为0
        return ( (x & y) + ( (x^y) >>1 ));
    }
    int intOpposite(int x)
    {//-x=~x+1=~(x+`)
        return (~x+1);//~(X+1)
    }
    int intAbs(int x)
    {//无分支取绝对值
        int y=x>>(8*sizeof(x)-1);
        return (x^y)-y;//(x+y)^y
    }
    
    
    //递归实现进制转换
    void decimalTranslate(int n,int desBase){
        if(desBase>16 || desBase<2){
            printf("error:desBase should be between[2,16]
    ");
            exit(0);
        }
        if(n){
            decimalTranslate(n/desBase,desBase);
            printf("%x",n%desBase);
        }
    }
    int main(int argc,char *argv[])
    {
        char a;
        char b[20]="helloworld";
        int c;
        float d;
        //变长参数表处理
        //printIntArgs(2,1,3,4,-1);
        //myPrintf(3," char:%c
     int:%d
     double%f
     string:%s
    ",'ab',12,12.2,"hello world" " good");
        //myScanf("%c%s%d%f",&a,b,&c,&d);
        //printf("%c %s %d %f
    ",a,b,c,d);
        
        //scanf格式特性示例
        //scanfFormatTest();
        
        //fread fwrite示例
        //freadFwriteTest();
        
        //stdrr exit示例
        //StderrExitTest(argc,argv);
        
        //ungetc示例
        //ungetcTest();
    
        //存储管理函数示例
        //mallocMemsetTest();
        //callocTest();
    
        //putchar(myGetchar());
    
        //rename("fi.txt","file");
        printf("%+d %+d
    ",-10,10);//加号,输出正负号
        printf("% d % d % d
    ",-10,+10,10);//一个空格,若数的第一个字符为符号位,则代替该空格
        printf("%x
    ",013);
        printf("hello%d  %n",10,&c);printf("%d
    ",c);//%n
        return 0;
        
    }
  • 相关阅读:
    January 25th, 2018 Week 04th Thursday
    January 24th, 2018 Week 04th Wednesday
    January 23rd, 2018 Week 04th Tuesday
    January 22nd, 2018 Week 04th Monday
    January 21st, 2018 Week 3rd Sunday
    January 20th, 2018 Week 3rd Saturday
    January 19th, 2018 Week 3rd Friday
    January 18th, 2018 Week 03rd Thursday
    January 17th, 2018 Week 03rd Wednesday
    January 16th, 2018 Week 03rd Tuesday
  • 原文地址:https://www.cnblogs.com/z-sm/p/4273181.html
Copyright © 2011-2022 走看看