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\n",expr);
//2-3
int htoi(char *s)
{
int n=;
while(*s!='\0')
{
if (*s=='x' || *s=='X')
{
n=;
}
else if (''<=*s && *s<='')
{
n=n*+(*s-'');
}
else if ('a'<=*s && *s<='z')
{
n=n*+(*s-'a'+);
}
else if ('A'<=*s && *s<='Z')
{
n=n*+(*s-'A'+);
}
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+-n)) & ~(~<<n);
}
//2-6
unsigned setbits(unsigned x,int p,int n,unsigned y)
{//把x从右起从0起向右的n位置为y最右n位
y&=~(~<<n);//得到y最右n位
y<<=(p+-n);//最右n位左移到与x中间n位对应的位置上 y|=x & (~(~<<n));//使y最右n位与x最右n位一样
x>>=(p+);
x<<=(p+);//得到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 ^(~(~<<n)<<(p-n+));
}
//2-8
unsigned rightrot(unsigned x,int n)
{//0^a=a,1^a=~a
return ((~(~<<n) & x)<<(sizeof(unsigned)*-n)) ^ (x>>n);
} //递归,将一个整数作为字符串打印
int isNegtive=;
void printd(int n)
{ if(n< && isNegtive)
{
putchar('-');
isNegtive=;
}
if (n/)
{
printd(n/);
}
//putchar((n%<)?(abs(n%)+''):(n%+''));//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+;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-);
quickSort(data,last+,right);
}
int binSearch(int data[],int n,int num)
{
int low,high,mid;
low=;
high=n-;
while (low<=high)
{
mid=(low+high)/;
if (num==data[mid])
return mid;
else if (num>data[mid])
low=mid+;
else
high=mid-;
}
return -;
}
int main()
{
int c=,d=;
swap(c,d);
printf("c:%d d:%d\n",c,d);
printf("%u\n",getbits(-,,));
printf("%u\n",setbits(,,,));
printf("%u\n",invert(,,));
printf("%x\n",rightrot(0xff00ff,)); extern void mytest();
mytest(); int testdata[]={,,,,,,};
quickSort(testdata,,);
for (c=;c<;c++)
{
printf("%d ",testdata[c]);
} printf("\na" " b%d\n",);//前面的两个字符串将被连接起来
myPrint(c);
return ;
}
void mytest()
{
extern int num;
printf("\n%d\n",num);
}
int num=;
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=;
while(*s!='\0')
{
if (*s=='x' || *s=='X')
{
n=;
}
else if (''<=*s && *s<='')
{
n=n*+(*s-'');
}
else if ('a'<=*s && *s<='z')
{
n=n*+(*s-'a'+);
}
else if ('A'<=*s && *s<='Z')
{
n=n*+(*s-'A'+);
}
s++;
}
return n;
}
unsigned getbits(unsigned x,int p,int n)
{//从右向左数从0起,取从p开始向右的n个位,的值
return (x>>(p+-n)) & ~(~<<n);
}
//2-6
unsigned setbits(unsigned x,int p,int n,unsigned y)
{//把x从右起从0起向右的n位置为y最右n位
y&=~(~<<n);//得到y最右n位
y<<=(p+-n);//最右n位左移到与x中间n位对应的位置上 y|=x & (~(~<<n));//使y最右n位与x最右n位一样
x>>=(p+);
x<<=(p+);//得到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 ^(~(~<<n)<<(p-n+));
}
//2-8
unsigned rightrot(unsigned x,int n)
{//0^a=a,1^a=~a
return ((~(~<<n) & x)<<(sizeof(unsigned)*-n)) ^ (x>>n);
}
//2-9
int bitcount(unsigned x)
{//x的二进制形式中1的个数
int n=;
while(x!=)
{
// if (x & 1)
// {
// n++;
// }//method1
{
x&=(x-);
n++;
}//method2
x>>=;
}
return n;
}
char * reverse(char s[])
{
int i,j;
for (i=,j=strlen(s)-;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=;
bool isNegative=num<?true:false;
char s[];//数的位数,包括可能的负号
if (isNegative)
{
do
{
s[i++]=-(num%)+'';
num/=;
} while(num!=);
s[i++]='-';
}
else
{
do
{
s[i++]=num%+'';
num/=;
} while(num!=);
}
s[i]='\0';
reverse(s);
return s;
}
int main()
{
char s[]="abcde423546g";
printf("getbits: %u\n",getbits(-,,));
printf("setbits: %u\n",setbits(,,,));
printf("invert: %u\n",invert(,,));
printf("rightrot:%x\n",rightrot(0xff00ff,));
printf("bitcount:%d\n",bitcount());
printf("reverse: %s\n",reverse(s));
printf("itoa: %s\n",itoa(INT_MIN));
printf("itoa: %s\n",itoa(INT_MAX));
return ;
}
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 != -; i = va_arg(ap, int))
printf("%d ", i);
va_end(ap);
putchar('\n');
}
void myPrintf(int a,char *format,...)
{//变长参数表处理
char *p; va_list ap;//参数指针 va_start(ap,a);//初始化ap,指向某个有名参数
printf("%s\n",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[];
sscanf("123456abcd","%[1-4a-z]",s);
printf("%s\n",s);//
s[]='\0'; sscanf("123456abcd","%[14az]",s);
printf("%s\n",s);//
s[]='\0'; sscanf("123456abcd","%[^3-4]",s);
printf("%s\n",s);//
s[]='\0'; sscanf("a123456abcd","%[3-4]",s);
printf("%s\n",s);//空,虽然串中有34但不是从首字符起的
s[]='\0'; sscanf("123456abcd","%3[0-9a-z]",s);
printf("%s\n",s);//123,限定最多读取3个字符
s[]='\0'; sscanf("a123456,abcd","%*c%s",s);
printf("%s\n",s);//123456,abcd,* 表示跳过此数据不读入. (也就是不把此数据读入参数中)
s[]='\0'; sscanf("iios/12DDWDFF@122","%*[^/]/%[^@]",s);
printf("%s\n",s);//12DDWDFF,综合使用,某种程度上可以充当正则使用
s[]='\0';
} struct stu
{
char name[];
int num;
int age;
char addr[];
}boya[],boyb[],*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=;i<;i++,pp++)
scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr);
pp=boya;
fwrite(pp,sizeof(struct stu),,fp);
rewind(fp);
fread(qq,sizeof(struct stu),,fp);
printf("name number age addr");
for(i=;i<;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[];
if(argc==)
filecopy(stdin,stdout);
else
{
while (--argc>)
{
if ((fp=fopen(*++argv,"r"))==NULL)
{
fprintf(stderr,"%s: can't open %s\n",prog,*argv);
//exit(1);
}
else
{
filecopy(fp,stdout);
fclose(fp);
}
}
}
if (ferror(stdout))
{
fprintf(stderr,"%s: error writing stdout\n",prog);
exit();
}
exit();
}
void filecopy(FILE *ifp,FILE *ofp)
{
int c;
while ((c=getc(ifp))!=EOF)
{
putc(c,ofp);
}
} void ungetcTest()
{
char str[];
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**\n",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(*sizeof(int));//malloc不能自动初始化
if(NULL==p){
printf("Can't get memory!\n");
return -;
} printf("%d\n\n",*p);//未初始化的不定乱值-842150451 memset(p,,*sizeof(int)); //用c++的函数memset初始化前两个数 printf("%d\n",*p);//初始化值16843009
printf("%d\n",p[]==0x01010101);//1,说明每个字节被0x01代替
printf("%d\n",p[]);//未初始化乱值-842150451 *(p+)=; printf("%d\n\n",p[]);// free(p);//动态分配者在程序结束前必须释放,否则内存泄露
printf("%d\n",*p);;//乱值-572662307。free后指针仍指向原来指向的地方,为野指针 return ;
} void callocTest()
{
int * p=NULL;
int i=;
int SIZE=;
//为p从堆上分配SIZE个int型空间
p=(int *)calloc(SIZE,sizeof(int));
//p=(int *)malloc(SIZE*sizeof(int));与上句功能一样,只不过没有自动初始化 if(NULL==p){
printf("Error in calloc.\n");
return -;
}
//输出各个空间的值
for(i=;i<SIZE;i++)
printf("p[%d]=%d\n",i,p[i]); //为p指向的SIZE个int型空间赋值
for(i=;i<SIZE;i++)
p[i]=i; //输出各个空间的值
for(i=;i<SIZE;i++)
printf("p[%d]=%d\n",i,p[i]); free(p);
p=NULL;
return ;
} //模拟c语言中的带缓冲的getchar(), syscalls.h
int myGetchar(void)
{
static char buf[];
static char *bufp=buf;
static int n=;
if (n==)
{
n=read(,buf,sizeof(buf));
bufp=buf;
}
return (n-->)?(unsigned char)*bufp++:EOF;
} int intAverage(int x,int y)
{//x,y和为负时会出错,如-4、3结果会得到-1,正确为0
return ( (x & y) + ( (x^y) >> ));
}
int intOpposite(int x)
{//-x=~x+1=~(x+`)
return (~x+);//~(X+1)
}
int intAbs(int x)
{//无分支取绝对值
int y=x>>(*sizeof(x)-);
return (x^y)-y;//(x+y)^y
} //递归实现进制转换
void decimalTranslate(int n,int desBase){
if(desBase> || desBase<){
printf("error:desBase should be between[2,16]\n");
exit();
}
if(n){
decimalTranslate(n/desBase,desBase);
printf("%x",n%desBase);
}
}
int main(int argc,char *argv[])
{
char a;
char b[]="helloworld";
int c;
float d;
//变长参数表处理
//printIntArgs(2,1,3,4,-1);
//myPrintf(3," char:%c\n int:%d\n double%f\n string:%s\n",'ab',12,12.2,"hello world" " good");
//myScanf("%c%s%d%f",&a,b,&c,&d);
//printf("%c %s %d %f\n",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\n",-,);//加号,输出正负号
printf("% d % d % d\n",-,+,);//一个空格,若数的第一个字符为符号位,则代替该空格
printf("%x\n",);
printf("hello%d %n",,&c);printf("%d\n",c);//%n
return ; }
The C Programming Language (second edition) 实践代码(置于此以作备份)的更多相关文章
- The C Programming Language Second Edition
%12d at least #include <stdio.h> main() { ,sum=,w=; ; ; w<=end; w++ ) { sum+=w; // for(wb= ...
- About learn《The C programming Language,Second Edition》
Today,My last week buy C language book arrived. Today,I week earnest study. No matter what difficult ...
- C: Answers to “The C programming language, Edition 2”
<The C programming language> Edition 2的习题答案地址: http://users.powernet.co.uk/eton/kandr2/index.h ...
- ESSENTIALS OF PROGRAMMING LANGUAGES (THIRD EDITION) :编程语言的本质 —— (一)
# Foreword> # 序 This book brings you face-to-face with the most fundamental idea in computer prog ...
- iOS Swift-元组tuples(The Swift Programming Language)
iOS Swift-元组tuples(The Swift Programming Language) 什么是元组? 元组(tuples)是把多个值组合成一个复合值,元组内的值可以使任意类型,并不要求是 ...
- iOS Swift-控制流(The Swift Programming Language)
iOS Swift-控制流(The Swift Programming Language) for-in 在Swift中for循环我们可以省略传统oc笨拙的条件和循环变量的括号,但是语句体的大括号使我 ...
- The Swift Programming Language 中文翻译版(个人翻新随时跟新)
The Swift Programming Language --lkvt 本人在2014年6月3日(北京时间)凌晨起来通过网络观看2014年WWDC 苹果公司的发布会有iOS8以及OS X 10.1 ...
- [iOS翻译]《The Swift Programming Language》系列:Welcome to Swift-01
注:CocoaChina翻译小组已着手此书及相关资料的翻译,楼主也加入了,多人协作后的完整译本将很快让大家看到. 翻译群:291864979,想加入的同学请进此群哦.(本系列不再更新,但协作翻译的进度 ...
- the C programming language 阅读笔记1
读了一遍著名的<the C programming language>,果然如听说的一样,讲解基础透彻,案例简单典型,确实自己C语言还有很多细节点不是很清楚. 总结一下阅读的收获(部分原书 ...
随机推荐
- C#中的默认访问修饰符
1.命名空间下的元素的默认访问修饰符 public : 同一程序集的其他任何代码或引用该程序集的其他程序集都可以访问该类型或成员.internal : 同一程序集中的任何代码都可以访问该类型或成员,但 ...
- Sql Server UniCode编码解码
); set @s = N'揶'; select UniCode(@s),nchar(UniCode(@s)); 在 SQL Server 中处理 Unicode 字串常数时,您必需在所有的 Unic ...
- js 与ios 交互的三种方法
第一种:IOS拦截url 实现跳转 参考链接:http://www.cnblogs.com/pengyingh/articles/2354381.html IOS9.0 及以上支持 第二种:IOS ...
- 卫星轨道和两行数据TLE
最近由于Sino-2和北斗的关系,很多网友贴了表示卫星运行轨道的TLE数据.这里想对卫星轨道参数和TLE的格式做一个简单介绍.虽然实际上没有人直接读TLE数据,而都是借助软件来获得卫星轨道和位置信息, ...
- oracle系统包—-dbms_output用法
dbms_output包主要用于调试pl/sql程序,或者在sql*plus命令中显示信息(displaying message)和报表,譬如我们可以写一个简单的匿名pl/sql程序块,而该块出于某种 ...
- Nutch搜索引擎(第4期)_ Eclipse开发配置
1.环境准备 1.1 本期引言 前三期分别介绍了Nutch与Solr在Linux上面的安装,并做了简单的应用,这一期从开发的角度进行,因为我们日常最熟悉的开发环境是Windows,所以本期详细介绍Wi ...
- Object C学习笔记15-协议(protocol)
在.NET中有接口的概念,接口主要用于定义规范,定义一个接口关键字使用interface.而在Object C 中@interface是用于定义一个类的,这个和.NET中有点差别.在Object C中 ...
- [设计模式] javascript 之 适配器模式
适配器模式说明 说明: 适配器模式,一般是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况: 场景: 就好比我们买了台手机,买回来后发现,充电线插头是三插头,但家里,只有两插 ...
- Moqui学习之代码分析mantle priceServices.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- This software is in the pub ...
- Task.Run Vs Task.Factory.StartNew
在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...