• 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;
        
    }
  • 相关阅读:
    数据挖掘、数据分析的书籍推荐
    跳槽时间如何选择
    求职网站总结
    Eclipse中Applet程序运行时Applet小程序大小的设置
    统计学习导论:基于R应用——第五章习题
    统计学习导论:基于R应用——第四章习题
    统计学习导论:基于R应用——第三章习题
    Windows环境下安装IPython NoteBook
    centos7上mysql无法启动也没有日志
    CentOS 6.4下Squid代理服务器的安装与配置
  • 原文地址:https://www.cnblogs.com/z-sm/p/4273181.html
Copyright © 2020-2023  润新知