C程序设计语言(KR)笔记
1.表達(dá)式中float類型的操作數(shù)不會(huì)自動(dòng)轉(zhuǎn)換為double類型。一般來說,數(shù)學(xué)函數(shù)(如math.h)使用雙精度類型的變量。使用float類型主要是為了在使用較大數(shù)組時(shí)節(jié)省存儲(chǔ)空間,有時(shí)也為了節(jié)省機(jī)器執(zhí)行時(shí)間(雙精度算數(shù)元算特別費(fèi)時(shí))。
2.scanf函數(shù)調(diào)用時(shí),字符串類型不需要寫‘&’,因?yàn)槠浔旧砑礊榈刂贰?
3.EOF可能被定義為不同的值,使用EOF等標(biāo)準(zhǔn)符號(hào)可以增強(qiáng)程序的可移植性,常見值有-1。
4.根據(jù)某種特定的狀態(tài)做不同的行為,可以用define定義狀態(tài)量,然后定義int state。如:
#define IN 0 #define OUT 1... if(state == IN)... else //OUT...
5. ~(~0<<n) ?得到最右邊n位為1,其他位是0.
6.條件表達(dá)式
?每10行一個(gè)換行符:
for(i=0;i<n,i++) printf("%6d%c",a[i],(i%10==9||i==n-1)? '\n':' '); for(i=0;i<n,i++) printf((i%10==9||i==n-1)? "%6d\n":"%6d ",a[i]);
是否復(fù)數(shù)的s
printf("You have %d item%s.\n",n,n==1?"":"s");
7.在switch語句中,case的作用只是一個(gè)標(biāo)號(hào)。
8.break只能跳出其所在的一級(jí)到上一級(jí),而不是所有層次。
9. ?getch和ungetch ? ?超前讀并放回一個(gè)字符
#define BUFSIZE 100char buf[BUFSIZE];//for ungetch to buffer int bufp=0;//the next spare index of bufint getch(void) {return (bufp>0) ? buf[--bufp] : getchar(); }void ungetch(char c) {if(bufp >= BUFSIZE-1)printf("ungetch: too many characters\n");elsebuf[bufp++]=c; }
10. 一個(gè)外部變量只能在某個(gè)文件中定義一次,而其他文件可以通過extern聲明來訪問他。外部變量的定義必須指定數(shù)組的長(zhǎng)度,但extern聲明則不一定要指定數(shù)組的長(zhǎng)度。外部變量的初始化只能出現(xiàn)在其定義中。
11.在函數(shù)中,可以以程序塊結(jié)構(gòu)的形式定義變量,例如for語句的花括號(hào)。
12.在不進(jìn)行顯式初始化的情況下,外部變量和靜態(tài)變量都將被初始化為0,而自動(dòng)變量和寄存器變量的初值則沒有定義。
對(duì)于外部變量和靜態(tài)變量來說,初始化表達(dá)式必須是常量表達(dá)式,且只初始化一次(在概念上講是在程序開始執(zhí)行前進(jìn)行初始化)。
對(duì)于自動(dòng)變量和寄存器變量,則在每次進(jìn)入函數(shù)或程序塊時(shí)都將被初始化,可以不是常量表達(dá)式。
數(shù)組的初始化,如果初始化表達(dá)式的個(gè)數(shù)比數(shù)組元素少,則對(duì)外部變量、靜態(tài)變量和自動(dòng)變量來說,未被初始化的元素將被初始化為0。若初始化表達(dá)式的個(gè)數(shù)比數(shù)組元素多,則是錯(cuò)誤的。
13.將一個(gè)數(shù)作為字符串打印
/*print decimal as string*/ void printd(int n) {if(n<0){putchar('-');n=-n;}if(n/10)printd(n/10);putchar(n%10+'0'); }14.引號(hào)分開的兩個(gè)字符串合并打印
printf("hello"" world!"); 輸出:15.宏定義中形式參數(shù)不能用帶引號(hào)的字符串替換。但是如果在替換文本中,參數(shù)名以#作為前綴則結(jié)果將被擴(kuò)展為由實(shí)際參數(shù)替換該參數(shù)的帶引號(hào)的字符串。
預(yù)處理器中運(yùn)算符##為宏擴(kuò)展提供了一種連接實(shí)際參數(shù)的手段。如果替換文本中的參數(shù)與##相鄰,則該參數(shù)將被實(shí)際參數(shù)替換,##與前后的空白符將被刪除,并對(duì)替換后的結(jié)果重新掃描。
#include <stdio.h>#define dprint(expr) printf(#expr " =%g\n",expr) #define paste(front,back) front ## backint main() {double x=2.0,y=3.0,x2=1.0;dprint(x/y);dprint(paste(x,2));return 0; } 輸出16. 獲取一個(gè)整型
#include <stdio.h> #include <ctype.h>//assign the next integer to *pn int getint(int *pn) {int c,sign;while(isspace(c=getc(stdin)))//skip spaces;if(!isdigit(c) && c!=EOF && c!='+' && c!='-'){ungetc(c,stdin);//it's not a numberreturn 0;}sign=(c=='-')? -1:1;if(c=='+'||c=='-')c=getc(stdin);for(*pn=0;isdigit(c);c=getc(stdin))*pn=10**pn+(c-'0');*pn*=sign;if(c != EOF)ungetc(c,stdin);return c; } 17.通過數(shù)組下標(biāo)所能完成的任何操作都可以通過指針來實(shí)現(xiàn)。一般來說,用指針編寫的程序比用數(shù)組下標(biāo)編寫的程序執(zhí)行速度快,但另一方面,用指針實(shí)現(xiàn)的程序理解起來困難一些。18.C語言保證,0永遠(yuǎn)不是有效的數(shù)據(jù)地址,因此,返回值0可用來表示發(fā)生了異常事件。指針與整數(shù)之間不能相互轉(zhuǎn)換,但0是唯一的例外:常量0可以賦值給指針,指針也可以和常量0進(jìn)行比較。程序中經(jīng)常用符號(hào)常量NULL代替常量0,這樣便于更清晰地說明常量0是指針的一個(gè)特殊值。符號(hào)常量NULL定義在標(biāo)準(zhǔn)頭文件<stddef.h>。
19.strcpy簡(jiǎn)單實(shí)現(xiàn)
void strcpy(char *d,char *s) {while(*d++ = *s++); } 20.strcmp簡(jiǎn)單實(shí)現(xiàn) int strcmp(char *s,char *t) {for(;*s == *t;s++,t++)if(*s=='\0')return 0;return *s-*t; }21.函數(shù)指針疑問,下面一句什么意思
(int (*)(void*,void*))(numeric ? numcmp : strcmp)What's happening here is indeed a cast. Lets ignore the ternary for a second and pretend that numcmp is always used. For the purpose of this question, functions can act as function pointers in C. So if you look at the type of numeric it is actually
(int (*)(int*,int*))In order for this to be properly used in qsort it needs to have void parameters. Because the types here all have the same size with respect to parameters and return types, it's possible to substitute on for the other. All that's needed is a cast to make the compiler happy.
(int (*)(void*,void*))(numcmp )22.typedef的作用
看上去整潔美觀;使程序參數(shù)化,以提高程序的可移植性;為程序提供更好的文檔,更容易理解。
23.一個(gè)聯(lián)合只能用它第一個(gè)成員類型的值來初始化。
24.位字段提供了一種在字內(nèi)直接定義和訪問字段的能力,而不用使用按位方式的邏輯運(yùn)算。
struct {unsigned int isk :1;unsigned int ise :1;unsigned int iss :1;} flags;25.minprintf函數(shù)(處理變長(zhǎng)參數(shù)表)
#include <stdarg.h> #include <stdio.h>/* minimal printf with variable argument list */ void minprintf(char *fmt, ...) {va_list ap; /*points to each unnamed arg in turn*/char *p,*sval;int ival;double dval;va_start(ap,fmt);//make ap point to the first unnamed argfor(p=fmt;*p;p++){if(*p!='%'){putchar(*p);continue;}switch(*++p){case 'd':ival=va_arg(ap,int);printf("%d",ival);break;case 'f':dval=va_arg(ap,double);printf("%f",dval);break;case 's':for(sval=va_arg(ap,char*);*sval;sval++)putchar(*sval);break;default:putchar(*p);break;}}va_end(ap);//clean up when done }1.表達(dá)式中float類型的操作數(shù)不會(huì)自動(dòng)轉(zhuǎn)換為double類型。一般來說,數(shù)學(xué)函數(shù)(如math.h)使用雙精度類型的變量。使用float類型主要是為了在使用較大數(shù)組時(shí)節(jié)省存儲(chǔ)空間,有時(shí)也為了節(jié)省機(jī)器執(zhí)行時(shí)間(雙精度算數(shù)元算特別費(fèi)時(shí))。
2.scanf函數(shù)調(diào)用時(shí),字符串類型不需要寫‘&’,因?yàn)槠浔旧砑礊榈刂贰?br /> 3.EOF可能被定義為不同的值,使用EOF等標(biāo)準(zhǔn)符號(hào)可以增強(qiáng)程序的可移植性,常見值有-1。
4.根據(jù)某種特定的狀態(tài)做不同的行為,可以用define定義狀態(tài)量,然后定義int state。如:
#define IN 0 #define OUT 1... if(state == IN)... else //OUT...
5. ~(~0<<n) ?得到最右邊n位為1,其他位是0.
6.條件表達(dá)式
?每10行一個(gè)換行符:
for(i=0;i<n,i++) printf("%6d%c",a[i],(i%10==9||i==n-1)? '\n':' '); for(i=0;i<n,i++) printf((i%10==9||i==n-1)? "%6d\n":"%6d ",a[i]);
是否復(fù)數(shù)的s
printf("You have %d item%s.\n",n,n==1?"":"s");
7.在switch語句中,case的作用只是一個(gè)標(biāo)號(hào)。
8.break只能跳出其所在的一級(jí)到上一級(jí),而不是所有層次。
9. ?getch和ungetch ? ?超前讀并放回一個(gè)字符
#define BUFSIZE 100char buf[BUFSIZE];//for ungetch to buffer int bufp=0;//the next spare index of bufint getch(void) {return (bufp>0) ? buf[--bufp] : getchar(); }void ungetch(char c) {if(bufp >= BUFSIZE-1)printf("ungetch: too many characters\n");elsebuf[bufp++]=c; }
10. 一個(gè)外部變量只能在某個(gè)文件中定義一次,而其他文件可以通過extern聲明來訪問他。外部變量的定義必須指定數(shù)組的長(zhǎng)度,但extern聲明則不一定要指定數(shù)組的長(zhǎng)度。外部變量的初始化只能出現(xiàn)在其定義中。
11.在函數(shù)中,可以以程序塊結(jié)構(gòu)的形式定義變量,例如for語句的花括號(hào)。
12.在不進(jìn)行顯式初始化的情況下,外部變量和靜態(tài)變量都將被初始化為0,而自動(dòng)變量和寄存器變量的初值則沒有定義。
對(duì)于外部變量和靜態(tài)變量來說,初始化表達(dá)式必須是常量表達(dá)式,且只初始化一次(在概念上講是在程序開始執(zhí)行前進(jìn)行初始化)。
對(duì)于自動(dòng)變量和寄存器變量,則在每次進(jìn)入函數(shù)或程序塊時(shí)都將被初始化,可以不是常量表達(dá)式。
數(shù)組的初始化,如果初始化表達(dá)式的個(gè)數(shù)比數(shù)組元素少,則對(duì)外部變量、靜態(tài)變量和自動(dòng)變量來說,未被初始化的元素將被初始化為0。若初始化表達(dá)式的個(gè)數(shù)比數(shù)組元素多,則是錯(cuò)誤的。
13.將一個(gè)數(shù)作為字符串打印
/*print decimal as string*/ void printd(int n) {if(n<0){putchar('-');n=-n;}if(n/10)printd(n/10);putchar(n%10+'0'); }14.引號(hào)分開的兩個(gè)字符串合并打印
printf("hello"" world!"); 輸出:15.宏定義中形式參數(shù)不能用帶引號(hào)的字符串替換。但是如果在替換文本中,參數(shù)名以#作為前綴則結(jié)果將被擴(kuò)展為由實(shí)際參數(shù)替換該參數(shù)的帶引號(hào)的字符串。
預(yù)處理器中運(yùn)算符##為宏擴(kuò)展提供了一種連接實(shí)際參數(shù)的手段。如果替換文本中的參數(shù)與##相鄰,則該參數(shù)將被實(shí)際參數(shù)替換,##與前后的空白符將被刪除,并對(duì)替換后的結(jié)果重新掃描。
#include <stdio.h>#define dprint(expr) printf(#expr " =%g\n",expr) #define paste(front,back) front ## backint main() {double x=2.0,y=3.0,x2=1.0;dprint(x/y);dprint(paste(x,2));return 0; } 輸出16. 獲取一個(gè)整型
#include <stdio.h> #include <ctype.h>//assign the next integer to *pn int getint(int *pn) {int c,sign;while(isspace(c=getc(stdin)))//skip spaces;if(!isdigit(c) && c!=EOF && c!='+' && c!='-'){ungetc(c,stdin);//it's not a numberreturn 0;}sign=(c=='-')? -1:1;if(c=='+'||c=='-')c=getc(stdin);for(*pn=0;isdigit(c);c=getc(stdin))*pn=10**pn+(c-'0');*pn*=sign;if(c != EOF)ungetc(c,stdin);return c; } 17.通過數(shù)組下標(biāo)所能完成的任何操作都可以通過指針來實(shí)現(xiàn)。一般來說,用指針編寫的程序比用數(shù)組下標(biāo)編寫的程序執(zhí)行速度快,但另一方面,用指針實(shí)現(xiàn)的程序理解起來困難一些。18.C語言保證,0永遠(yuǎn)不是有效的數(shù)據(jù)地址,因此,返回值0可用來表示發(fā)生了異常事件。指針與整數(shù)之間不能相互轉(zhuǎn)換,但0是唯一的例外:常量0可以賦值給指針,指針也可以和常量0進(jìn)行比較。程序中經(jīng)常用符號(hào)常量NULL代替常量0,這樣便于更清晰地說明常量0是指針的一個(gè)特殊值。符號(hào)常量NULL定義在標(biāo)準(zhǔn)頭文件<stddef.h>。
19.strcpy簡(jiǎn)單實(shí)現(xiàn)
void strcpy(char *d,char *s) {while(*d++ = *s++); } 20.strcmp簡(jiǎn)單實(shí)現(xiàn) int strcmp(char *s,char *t) {for(;*s == *t;s++,t++)if(*s=='\0')return 0;return *s-*t; }21.函數(shù)指針疑問,下面一句什么意思
(int (*)(void*,void*))(numeric ? numcmp : strcmp)What's happening here is indeed a cast. Lets ignore the ternary for a second and pretend that numcmp is always used. For the purpose of this question, functions can act as function pointers in C. So if you look at the type of numeric it is actually
(int (*)(int*,int*))In order for this to be properly used in qsort it needs to have void parameters. Because the types here all have the same size with respect to parameters and return types, it's possible to substitute on for the other. All that's needed is a cast to make the compiler happy.
(int (*)(void*,void*))(numcmp )22.typedef的作用
看上去整潔美觀;使程序參數(shù)化,以提高程序的可移植性;為程序提供更好的文檔,更容易理解。
23.一個(gè)聯(lián)合只能用它第一個(gè)成員類型的值來初始化。
24.位字段提供了一種在字內(nèi)直接定義和訪問字段的能力,而不用使用按位方式的邏輯運(yùn)算。
struct {unsigned int isk :1;unsigned int ise :1;unsigned int iss :1;} flags;25.minprintf函數(shù)(處理變長(zhǎng)參數(shù)表)
#include <stdarg.h> #include <stdio.h>/* minimal printf with variable argument list */ void minprintf(char *fmt, ...) {va_list ap; /*points to each unnamed arg in turn*/char *p,*sval;int ival;double dval;va_start(ap,fmt);//make ap point to the first unnamed argfor(p=fmt;*p;p++){if(*p!='%'){putchar(*p);continue;}switch(*++p){case 'd':ival=va_arg(ap,int);printf("%d",ival);break;case 'f':dval=va_arg(ap,double);printf("%f",dval);break;case 's':for(sval=va_arg(ap,char*);*sval;sval++)putchar(*sval);break;default:putchar(*p);break;}}va_end(ap);//clean up when done } 26.cat int cat(int argc,char* argv[]) {FILE *fp;void filecopy(FILE*,FILE*);char *prog=argv[0];if(argc==1)//no argumentsfilecopy(stdin,stdout);else{while(--argc>0){if((fp=fopen(*++argv,"r"))==NULL){fprintf(stderr,"cat: can't open %s\n",*argv);return 1;}else{filecopy(fp,stdout);fclose(fp);}}}if(ferror(stdout)){fprintf(stderr,"%s:error writing stdout\n",prog);return 2;}return 0; }void filecopy(FILE *ifp, FILE *ofp) {int c;while((c=getc(ifp))!=EOF)putc(c,ofp); }總結(jié)
以上是生活随笔為你收集整理的C程序设计语言(KR)笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言调用api函数
- 下一篇: TCP 协议(包含三次握手,四次挥手)