C程序设计语言(第二版)-读书笔记

2016-12-14 09:56:43来源:http://blog.csdn.net/conanswp/article/details/53525238作者:conanswp人点击

第七城市

The C Programming Language


1.设计一个程序,作用为无限字符输出:









int c;


printf(“Please in put the char …/n”);


//getchar接受字符输入并存放到缓冲区,逐个返回给c


c=getchar();


while(c!=EOF)


{


putchar(c);


c=getchar();


}



2.设计一个程序,统计字符数目:









printf(“Please input char …/n”);


long nc=0;


while(getchar()!=EOF)


{


++nc;


}


printf(“%d/n”,nc);



3.设计一个程序,统计单词的个数:









#define IN 1


#define OUT 2


//c表示charnc表示出现字符的数目,nw表示单词数目,nl表示段落数


intc, nc, nw, nl, state;


state = OUT;


nl = nw = nc =0;


while(c=getchar()!=EOF)


{


++nc;


if(c==’/n’)


{


++nl;


}


if(c==’’||c==’/n’||c==’/t’)


{


state=OUT;


}


else if(state==OUT)


{


state = IN;


++nw;


}


printf(“字符数:%d,单词数:%d,段落数:%d”,nc,nw,nl);


}



4.C语言中的数据类型:


|-char1byte)、int4byte)、float4byte)、double8byte)、bool(1byte)


|-整形两种限定符:


|-shortlong,用于限定整形intint可以不写。short
int
2byte)、long int4byte)。


|-unsignedsigned用于限定是否含有符号,可用于charint。默认为signed


5.判断闰年:









int year=0;


scanf(“%d”,&year);


if(((year%4==0)&&(year%100)!=0)||year%400==0)


{


printf(“This year %d is leap year”,year);


}


else


{



}



6.enum#define定义常量的对比


|-enum定义枚举,#define定义宏,enum定义常量的值可以自动生成。


|-enum能够用于调试,而define定义的常量编译时不检查,只是对其进行字符的替换。


7.常用函数自定义实现:






























//strlen


int strlen(char s[])


{


int i=0;


while(s[i]!=’/0’)


{


++i;


}


return i;


}


//或者


int strlen(char *s)


{


int n;


for(n=0;*s!=’/0’;s++)


{


n++;


}


return n;


}



//atoi


int atoi(char s[])


{


int n=0;


for(int i=0;s[i]>=’0’&&s[i]<=’9’;++i)


{


n=(s[i]-‘0’)+10*n;


}


}



//lower


int lower(int c)


{


if(c>=’A’&&c<=’Z’)


{


return c+(‘a’-‘A’)


}


else


return c;


}



//strcat


void strcat(char s[], char t[])


{


int i=0;


int j=0;


while(s[i]!='/0')


{


++i;


}


while ((s[i++]=t[j++])!='/0')


{


}


}



//删除字符


void squeeze(char s[], int c)


{


int j,j;


for(int i=j=0;s[i]!=’/0’;i++)


{


if(s[i]!=c)


{


s[j++]=s[i];


}


s[j]=’/0’;


}


}



//trim,简化版,用于删除字符串尾部空格,理解break的使用


int trim(char s[])


{


int n;


for(n=strlen(s)-1;n>=0;n--)/


{


if(s[n]!=’’&&s[n]!=’/t’&&s[n]!=’/n’)


{


break;


}


s[n+1]=’/0’;


return n;


}


}



//strcpy


void strcpy(char *s,char *t)


{


while((*s++==*t++)!=’/0’)


{}


}



//strcmp


int strcmp()


{


for(;*s==*t;s++,t++)


{


if(*s==’/0’)


{


return 0;


}


return *s - *t);


}


}



8.在进行复制和函数参数传递时,低精度的可以向高精度的进行自动转换。例如接受float参数的函数乐意接受doulbe类型的参数。高精度要转换成低精度就要进行强制类型转换。


9.c语言中,字符数组和字符串很容易引起混淆。c语言中的字符串被当做成字符数组来处理。字符串的定义有两种:


char * c =“Hello”;或者char s[] =
“hello”;字符串在字符数组的结尾加上’/0’,因此对于char s2[] = {‘h’,’e’,’l’,’l’,’o’};sizeof(s2)=5,而sizeof(s)=6


10. 算法:












//冒泡


void bubble(int s[],int n)


{


int tmp=0;


for(int i=0;i


{


for (int j=0;j


{


if (s[j]>s[j+1])


{


tmp = s[j];


s[j] = s[j+1];


s[j+1] = tmp;


}


}


}


}



//折半查找,x是要查找的数字,v是已排序的数组,n是数组长度


int binsearch(int x,int v[],int n)


{


int low,high,mid;


low = 0;


high = n-1;


while (low<=high)


{


mid = (low + high)/2;


if(x


{


high = mid-1;


}


else if(x>v[mid])


{


low = mid +1;


}


else


return mid;


}


}



10.对于extern修饰符,extern i;表示变量声明,并未生成对象,用于说明i为全局变量,可在不同的文件中调用。


11.对于static修饰符,在c语言中,使用static声明变量为文件中访问,文件外不能访问该static变量。


12.寄存器变量使用register表示,其访问速度快,但寄存器地址不能访问。


13.预处理器:


|-#include<>系统默认搜索路径,””源文件路径+默认路径


|-#define:编译时进行字符替换


|-优点:节省调用开销


|-缺点:重复计算产生副作用


|-#ifndef…#define…#endif:条件包含


14.关于*++(--)的结合性,先++*


|-*p++ ==> p++; *p;


|-(*p)++ ==> p指向的对象值+1;


例如int s[]={2,3};int *p = s;printf(“%d,”*p++);结果输出的是2,而不是3,因为是先引用在++


15. ++ii++:在VC编译环境下,如果在一个计算表达式中,首先计算++i,然后看有几个i++,完成该表达式后,有几个i++i就自增几。例如:int
i=3,j; j=(i++) + (i++) + (++i);printf(
“i=%d,j=%d”,i,j);编译输出为612


16. VC的编译器中,printf函数是自右向左执行的。例如,printf(“%d,%d”,i,i+1);首先计算i+1,然后再输出i


17. 使用宏编写比较两个数的大小









#define max(A,B) ((A)>(B)?(A) : (B))



注意一定要加括号,用于放回宏的副作用。


18.对于32位的机器,指针永远占据4byte的长度,即sizeof(指针)=4


19.数组名就是指向数组指针的首地址,与指向数组的指针相比(例如int a[]={2,3};int *p = a;),a不可以a++,但是p可以p++。在函数定义中,char
*s < == > char s[].


20.*p++=value;理解为入栈,value放到p原先的位置,然后p++


val=*--p;理解为出栈,p地址首先减一,然后取值。


21. 命令行参数









#include


void main(int argc,char* argv[])//或者int argc, char**argv


{


int i;


for(i=1;i


{


printf(“%s”,argv[i]);


}


}



22. 指向函数的指针









//函数的定义并声明


void printf()


{


printf(“Hello”);


}


void (*f)(); //指向函数的指针声明


f = printf(); //赋值、初始化


(*f)(); //调用



int (*fun) (par):指向函数的指针,返回类型为int


int* fun(par):函数,返回类型为int *


23.union:单块存储区中管理不同类型的数据,其中所有元素相对于union基地地址的偏移为0


24.void* malloc(size_t n):返回n字节大小的未初始化的空间


void* calloc(size_t n,size_t size):返回能够容纳nsize大小的空间


PS:


1.###分别用与转换字符串和连接字符串。









#defineTOSTRING(n) #n


#defineCONTACT(n,m)
n##m



2.i++++i效率问题:


对于原生数据,效率一样;对于自定义类型,i++返回的是临时变量(需要使用自增之后的值),++i返回的是引用(使用自增之后的值),效率高。


3.四字节对齐:









#defineALIGN4(n) (((n)+3)&(~3))



4.#pragma









#pragmamessage("Hello")编译时输出信息


#pragmaonce确保该文件被编译一次



5.#undef用于注销之前定义的宏变量


6.长度为0的数组:


也成为柔性数组,多用于占位符。不增加类型的大小(因此使用柔性数组而不用char*(四个字节))。这样一次malloc便能申请带有缓冲区的一块内存,并且是连续的内存。柔性数组可以按照数组的访问方式进行读取。如下:









typedefstructstrZeroTest


{


intnum;


charposition[0];


}
ZeroTest;



intmain()


{


ZeroTest*pzt=
(
ZeroTest*)malloc(sizeof(ZeroTest)+10);


for(inti=
0;
i< 10; ++i)


{


pzt->position[i]
=
i;


}


return0;


}



第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台