diff --git a/01.md b/01.md index f6487da..ababa94 100644 --- a/01.md +++ b/01.md @@ -38,8 +38,9 @@ main() } } } - -执行 +``` +执行结果 +``` 1 is an apphabetic character 2 is an apphabetic character 3 is an apphabetic character @@ -92,8 +93,9 @@ main() } } } - -执行 +``` +执行结果 +``` c is an apphabetic character F is an apphabetic character D is an apphabetic character @@ -147,8 +149,9 @@ main() } } } - -执行 +``` +执行结果 +``` 125 is an ascii character:} 126 is an ascii character:~ 127 is an ascii character: @@ -157,7 +160,47 @@ main() ``` --- +## isblank +(测试字符是否为空格字符) + +**相关函数** +[`isspace`](#isspace) + +**头文件** +`#include ` + +**定义函数** +`int isblank(int c);` + +**函数说明** +检查参数`c`是否为空格字符,也就是判断是否为空格(space)或是定位字符(tab)。空格(space)的ASCII码为32,定位字符(tab)的ASCII码则为9。 + +**返回值** +若参数`c`为空格字符,则返回`TRUE`,否则返回`NULL(0)`。 + +**附加说明** +此为宏定义,非真正函数。 + +**范例** +```/*将字符串str[]中内含的空格字符找出.并显示空格字符的 ASCII码 */ +#include +main() +{ + char str[]="123c @# FD sP[e?"; + int i; + for(i=0;str[i] !=0; i++) + if (isblank(str[i])) printf("str[%d] is blank character: %d\n",i,str[i]); +} +``` +执行结果: +``` +str[4] is blank character: 32 +str[7] is blank character: 32 +str[10] is blank character: 9 +``` + +--- ## iscntrl (测试字符是否为ASCII 码的控制字符) @@ -220,8 +263,9 @@ main() } } } - -执行 +``` +执行结果 +``` 1 is an digit character 2 is an digit character 3 is an digit character @@ -269,8 +313,9 @@ main() } } } - -执行 +``` +执行结果 +``` str[0] is printable character:a str[1] is printable character:5 str[3] is printable character:@ @@ -316,8 +361,9 @@ main() } } } - -执行 +``` +执行结果 +``` c is a lower-case character s is a lower-case character e is a lower-case character @@ -365,9 +411,9 @@ main() } } } - -执行 - +``` +执行结果 +``` str[0] is printable character:a str[1] is printable character:5 str[2] is printable character: @@ -417,8 +463,9 @@ main() } } } - -执行 +``` +执行结果 +``` str[4] is a white-space character:32 str[7] is a white-space character:32 str[10] is a white-space character:9 /* \t */ @@ -467,10 +514,13 @@ main() } } } - -执行 -v -@#[? +``` +执行结果 +``` +@ +# +[ +? ``` --- @@ -515,8 +565,9 @@ main() } } } - -执行 +``` +执行结果 +``` F is an uppercase character D is an uppercase character P is an uppercase character @@ -564,8 +615,9 @@ main() } } } - -执行 +``` +执行结果 +``` 1 is a hexadecimal digits 2 is a hexadecimal digits 3 is a hexadecimal digits diff --git a/02.md b/02.md index 0badd1d..752d3a0 100644 --- a/02.md +++ b/02.md @@ -36,8 +36,9 @@ main() c = atof(a) + atof(b); printf("c=%.2f\n", c); } - -执行 +``` +执行结果 +``` c=-98.23 ``` @@ -79,8 +80,9 @@ main() c = atoi(a) + atoi(b); printf("c=%d\n", c); } - -执行 +``` +执行结果 +``` c=356 ``` @@ -122,11 +124,98 @@ main() c = atol(a) + atol(b); printf("c=%d\n", c); } - -执行 +``` +执行结果 +``` c=1234567890 ``` +--- + +## ecvt +(将浮点型数转換威宇符串,取四舍五人) + +**相关函数** +[`fcvt`](#fcvt), [`gcvt`](#gcvt), [`sprintf`](#sprintf) + +**头文件** + `#include ` + +**定义函数** +`char *ecvt (double number, int ndigits, int *decpt, int *sign);` + +**函数说明** +`ecvt()`用来将参数 `number`转换成ASCⅢ码字符串,参数`ndigits`表示显示的位数。若转换成功,参数`decpt`指针所指的变量会返回数值中小数点的地址(从左至右算起),而参数`sign`指针所指的变量则代表数值正或负,若数值为正,该返回值则为0,否则为1。 + +**返回值** +返回一字符串指针,此字符串声明为 static,若再调用`ecvt()`或`fcvt()`,此字符串内容会被覆盖。 +**附加说明** +请尽量改用 `sprintf()`做转换 + +**范例** + +``` +#include +main() +{ + double a= 123.45; + double b=-1234.56; + char *ptr; + int decpt, sign; + ptr =ecvt(a, 5, &decpt, &sign); + printf("decept = %d, sign =%d, a value= %s\n",decpt, sign, ptr); + ptr =ecvt(b, 6, &decpt, &sign); + printf("decept = %d, sign =%d, b value= %s\n",decpt, sign, ptr); +} +``` +执行结果 +``` +decept = 3, sign =0, a value= 12345 +decept = 4, sign =1, b value= 123456 +``` +--- + +## fcvt +(将浮点型数转换为字符串,取四舍五人) + +**相关函数** +[`ecvt`](#ecvt), [`gcvt`](#gcvt), [`sprintf`](#sprintf) + +**头文件** +`#include ` + +**定义函数** +`char *fcvt(double number, int ndigits, int *decpt, int *sign);` + +**函数说明** +`fcvt()`用来将参数 `number`转换成ASCII码字符串,参数 `ndigits`表示小数点后显示的位数。若转换成功,参数 `decpt`指针所指的变量会返回数值中小数点的地址(从左至右算起),而参数`sign`指针所指的变量则代表数值正或负,若数值为正,该传回值则为0,否则为1。 + +**返回值** +返回一字符串指针,此字符串声明为static,若再调用`ecvt()`或`fcvt()`,此字符串内容会被覆盖。 + +**附加说明** +请尽量改用 `sprintf()`做转换。 + +**范例** +``` +#include +main() +{ + double a =123.45; + double b =-1234.567; + char *ptr; + int decpt, sign; + ptr= fcvt(a , 2, &decpt ,&sign); /*小数点后显示2位数 */ + printf("decept =%d, sign = %d, a value =%s\n", decpt, sign, ptr); + ptr= fcvt(b , 3, &decpt ,&sign); /*小数点后显示3位数 */ + printf("decept =%d, sign = %d, b value =%s\n", decpt, sign, ptr); +} +``` +执行结果 +``` +decept =3, sign = 0, a value =12345 +decept =4, sign = 1, b value =1234567 +``` --- ## gcvt @@ -165,8 +254,9 @@ main() ptr = gcvt(b, 6, ptr); printf("b value=%s\n", ptr); } - -执行 +``` +执行结果 +``` a value=123.45 b value=-1234.56 ``` @@ -210,8 +300,9 @@ mian() printf("b=%d\n", strtod(b, NULL, 2)); printf("c=%d\n", strtod(c, NULL, 16)); } - -执行 +``` +执行结果 +``` a=1000000000 b=512 c=65535 @@ -256,8 +347,9 @@ main() printf("b=%d\n", strtol(b,NULL,2)); printf("c=%d\n", strtol(c,NULL,16)); } - -执行 +``` +执行结果 +``` a=1000000000 b=512 c=65535 @@ -322,8 +414,9 @@ main() b=toascii(a); printf("after toascii() : a value =%d(%c)\n",b,b); } - -执行 +``` +执行结果 +``` before toascii() : a value =217() after toascii() : a value =89(Y) ``` @@ -366,8 +459,9 @@ main() s[i]=tolower(s[i]); printf("after tolower() : %s\n",s); } - -执行 +``` +执行结果 +``` before tolower() : aBcDeFgH12345;!#$ after tolower() : abcdefgh12345;!#$ ``` @@ -412,8 +506,9 @@ main() } printf("after toupper() : %s\n",s); } - -执行 +``` +执行结果 +``` before toupper() : aBcDeFgH12345;!#$ after toupper() : ABCDEFGH12345;!#$ ``` diff --git a/03.md b/03.md index b938852..92f583b 100644 --- a/03.md +++ b/03.md @@ -75,7 +75,7 @@ main() #include main() { - printf("page size = %d\n",getpagesize( ) ); + printf("page size = %d\n",getpagesize()); } ``` @@ -166,13 +166,15 @@ main() fd=open("/etc/passwd",O_RDONLY); /*打开/etc/passwd*/ fstat(fd,&sb); /*取得文件大小*/ start=mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,fd,0); - if(start= = MAP_FAILED) /*判断是否映射成功*/ + if(start == MAP_FAILED) /*判断是否映射成功*/ return; printf("%s",start); - munma(start,sb.st_size); /*解除映射*/ - closed(fd); + munmap(start,sb.st_size); /*解除映射*/ + close(fd); } -执行 +``` +执行结果 +``` root : x : 0 : root : /root : /bin/bash bin : x : 1 : 1 : bin : /bin : daemon : x : 2 : 2 :daemon : /sbin @@ -219,4 +221,43 @@ munmap()用来取消参数start所指的映射内存起始地址, 参数length start或length 不合法。 **范例** -参考mmap() \ No newline at end of file +参考mmap() + +--- +## realloc +(更改已配置的内存空间) + +**相关函数** +malloc,calloc,free,brk + +**头立件** +`#include ` + +**定义函数** +`void *realloc (void *ptr, size_t size);` + +**函数说明** +参数`ptr`为指向先前由 `malloc()`、 `calloc()`或`realloc()`所返回的内存指针,而参数`size`为新配置的内存大小,其值可比原内存大或小。若参数`size`值较原配置空间较小,内存内容并不会改变,且返回的指针为原来内存启始地址;但若`size`值较原配置空间大,则 `realloc()`不一定会返回原先的指针,原先的内容虽不会改变,但新多出的内存则未设初值。若是参数`ptr`指针为`NULL`,此调用相当于 `malloc(size)`;若参数`size`值为0,此调用相当于`free(ptr)`; + +**返回值** +若配置成功则返回一指针,失败则返回`NULL`。 + +**范例** +``` +#include +main() +{ + char *ptr1 =malloc(11); + char *ptr2; + memset(ptr1, 'A', 10); + *(ptr1+10) = '\0'; + printf("before realloc: ptr = %x [%s]\n",ptr1, ptr1); + ptr2 = realloc(ptr1,40960); + printf("after realloc: ptr =%x [%s]\n",ptr2, ptr2); +} +``` +执行结果 +``` +before realloc: ptr = ae1420 [AAAAAAAAAA] +after realloc: ptr =900080 [AAAAAAAAAA] +``` \ No newline at end of file diff --git a/04.md b/04.md index 26edf4c..2478eeb 100644 --- a/04.md +++ b/04.md @@ -30,10 +30,29 @@ main() time (&timep); printf("%s",asctime(gmtime(&timep))); } - -执行 +``` +执行结果 +``` Sat Oct 28 02:10:06 2000 ``` +--- +## clock +(取得进程占用CPU的大约时间) + +**相关函数** +time + +**头文件** +`#include ` + +**定义函数** + `clock_t clock(void)` + +**函数说明** + `clock()`用来取得进程所占用CPU的大约时间。 + +**返回值** +返回进程所占用CPU的大约时间。 --- @@ -64,10 +83,85 @@ main() time (&timep); printf("%s",ctime(&timep)); } - -执行 +``` +执行结果 +``` Sat Oct 28 10 : 12 : 05 2000 ``` +--- +## difftime +(计算时间差距) + +**相关函数** +time,ctime, gmtime, localtime + +**头文件** +`#include ` + +**定义函数** + `double difftime(time_t time1, time_t time0);` + +**函数说明** + `difftime()`用来计算参数timel和time0所代表的时间差距,结果以 double 型精确值返回。两个参数的时间皆是以1970年1月1日零时零分零秒算起的UTC时间。 + +**返回值** +返回确精的时间差距秒数。 + +--- +## ftime +(取得目前的时间和日期) + +**相关函数** +time,ctime, gettimeofday + +**头文件** +`#include ` + +**定义函数** +` int ftime(struct timeb *tp);` + +**函数说明** +`ftime()`将目前时间日期由tp所指的结构返回。tp结构定义为: + + struct timeb { + time_t time; + unsigned short millitm; + short timezone; + short dstflag; + } + +成员 | 定义 +--------|- +time | 为从公元1970年1月1日至今的秒数。 +millitm | 为千分之一秒 。 +timezone| 为目前时区和 Greenwich相差的时间,单位为分钟。 +dstflag | 为日光节约时间的修正状态,如果为非0代表启用日光节约时间修正。 +| + + +**返回值** +无论成功或失败都返回0 + +**范例** +``` +#include +main() +{ + struct timeb tp; + ftime(&tp); + printf("time: %d\n", tp.time); + printf("millitm: %d\n", tp.millitm); + printf("timezone: %d\n", tp.timezone); + printf("dstflag: %d\n", tp.dstflag); +} +``` +执行结果 +``` +time: 1628931162 +millitm: 356 +timezone: -480 +dstflag: 0 +``` --- @@ -129,8 +223,9 @@ main(){ printf("tz_minuteswest; %d\n", tz.tz_minuteswest); printf("tz_dsttime, %d\n",tz.tz_dsttime); } - -执行 +``` +执行结果 +``` tv_sec: 974857339 tv_usec:136996 tz_minuteswest:-540 @@ -196,8 +291,9 @@ main() printf("%d%d%d",(1900+p->tm_year), (1+p->tm_mon),p->tm_mday); printf("%s%d;%d;%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec); } - -执行 +``` +执行结果 +``` 2000/10/28 Sat 8:15:38 ``` @@ -234,8 +330,9 @@ main() printf ("%d%d%d ", (1900+p->tm_year),( l+p->tm_mon), p->tm_mday); printf("%s%d:%d:%d\n", wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec); } - -执行 +``` +执行结果 +``` 2000/10/28 Sat 11:12:22 ``` @@ -274,8 +371,9 @@ main() timep = mktime(p); printf("time()->localtime()->mktime():%d\n",timep); } - -执行 +``` +执行结果 +``` time():974943297 time()->localtime()->mktime():974943297 ``` @@ -307,6 +405,100 @@ EINVAL 时区或某个数据是不正确的, 无法正确设置时间。 --- +## strftime +(格式化日期和时间) + +**相关函数** +time, asctime, gmtime, localtime + +**头文件** +`#include ` + +**定义函数** + `size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);` + +**函数说明** +`strftime()`会将参数`tm`的时间结构,依照参数 `format`所指定的字符串格式做转换,转换后的字符串内容将复制到参数`s`所指的字符串数组中,该字符串的最大长度为参数`max`所控制。 +参数 `format`的格式和一般格式化字符串相当类似,都是以`%`字符做控制,下面是其格式指令: + +格式 | 含义 +--|:-- +%a|当地星期日期的名称缩写,如 Sun +%A|当地星期日期的完整名称,如 Sunday +%b|当地月份的缩写。 +%B|当地月份的完整名称。 +%c| 当地适当的日期与时间表示法 +%C|以year/100表示年份。 +%d|月里的天数,表示法为01-31。 +%D|相当于"%m/%d/%y"格式。 +%e|如同%d为一个月里的天数,表示法为1-31。 +%h|和%b相同。 +%H|以24小时制表示小时数(00-23)。 +%I|以12小时制表示小时数(01-12)。 +%j|年中的天数(001-366)。 +%k|如同%H,但表示法为0-23 +%l|如同%l,但表示法为1- 12。 +%m|月份(01-12)。 +%M|分数(00-59)。 +%n|同\n +%p|显示对应的AM或PM表示 +%P|和%p相同,但是用小写的am和pm表示。 +%r|相当于使用"%I:%M:%S%p"格式。 +%R|相当于使用"%H:%M"格式。 +%s|从1970-01-01 00:00:00 UTC算起迄今的秒数 +%S|秒数(00-61)。 +%t|同\t。 +%T|24小时时间表示,相当于使用"%H:%M:%S"格式。 +%u|一星期中的星期日期,范围1-7,星期一从1开始。 +%U|年中的星期数(00-53),一月第一个星期日开始为01 +%w|一星期中的星期日期,范围0-6,星期日从0开始。 +%W|一年中的星期数(00-53),一月第一个星期一开始为01。 +%x|当地适当的日期表示。 +%X|当地适当的时间表示。 +%y|一世纪中的年份(00-99)。 +%Y|完整的公元年份表示。 +%Z|使用的时区名称。 +%%|'%'符号。 + | + +**返回值** +返回复制到参数`s`所指的字符串数组的总字符数,不包括字符串结束符号。 +如果返回`0`,表示未复制字符串到参数`s`内,但不表示一定有错误发生。 + +**附加说明** +环境变量`TZ`和 `TC_TIME`会影响此函数结果。 + +**范例** +``` +#include +main() +{ + char *format[] ={ "%I:%M:%S %p %m/%d %a ", + "%x %X %Y", + NULL + }; + char buf [30]; + int i; + time_t clock; + struct tm *tm; + + time(&clock); + tm =gmtime(&clock); + for (i =0; format[i] != NULL; i++) + { + strftime(buf, sizeof(buf), format[i], tm); + printf("%s => %s\n",format[i] ,buf); + } +} + +``` +执行结果 +``` +%I:%M:%S %p %m/%d %a => 03:01:44 AM 08/15 Sun +%x %X %Y => 08/15/21 03:01:44 2021 +``` +--- + ## time (取得目前的时间) @@ -333,7 +525,8 @@ mian() int seconds= time((time_t*)NULL); printf("%d\n",seconds); } - -执行 +``` +执行结果 +``` 9.73E+08 ``` \ No newline at end of file diff --git a/05.md b/05.md index 8632bbf..d85852d 100644 --- a/05.md +++ b/05.md @@ -65,7 +65,9 @@ main() for(i=0;i<30;i++) printf("%c",dest[i]); } -执行 +``` +执行结果 +``` bcopy() : string string memcpy() :string sring ``` @@ -125,7 +127,9 @@ main() p =index(s,’5’); printf(%s\n",p); } -执行 +``` +执行结果 +``` 5.68E+25 ``` @@ -159,7 +163,9 @@ main() memccpy(a,b,'B',sizeof(b)); printf("memccpy():%s\n",a); } -执行 +``` +执行结果 +``` memccpy():string(b) ``` @@ -193,7 +199,9 @@ main() p=memchr(s,'5',10); printf("%s\n",p); } -执行 +``` +执行结果 +``` 5.68E+25 ``` @@ -230,8 +238,9 @@ main() printf("memcmp(a,c):%d\n",memcmp((void*)a,(void*) c,6)); printf("memcmp(a,d):%d\n",memcmp((void*)a,(void*) d,6)); } - -执行 +``` +执行结果 +``` memcmp(a,b):1 /*字符串a>字符串b, 返回1*/ memcmp(a,c):-1 /* 字符串a<字符串c,返回-1*/ memcmp(a,d):0 /*字符串a=字符串d, 返回0*/ @@ -278,7 +287,9 @@ main() for(i=0; i<30; i++) printf("%c",a[i]); } -执行 +``` +执行结果 +``` strcpy() : string a ) memcpy() : string string ``` @@ -342,7 +353,9 @@ main() s[30]='\0'; printf("%s\n",s); } -执行 +``` +执行结果 +``` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ``` @@ -376,8 +389,9 @@ mian() p=rindex(s,'5'); printf("%s\n",p); } - -执行 +``` +执行结果 +``` 567890 ``` @@ -411,7 +425,9 @@ main() if(!strcasecmp(a,b)) printf("%s=%s\n",a,b); } -执行 +``` +执行结果 +``` aBcDeF=AbCdEf ``` @@ -445,8 +461,9 @@ main() printf("before strcat() : %s\n",a); printf("after strcat() : %s\n",strcat(a,b)); } - -执行 +``` +执行结果 +``` before strcat () : string(1) after strcat () : string(1)string(2) ``` @@ -481,8 +498,9 @@ main() p=strchr(s,'5'); printf("%s\n",p); } - -执行 +``` +执行结果 +``` 5.68E+25 ``` @@ -519,8 +537,9 @@ main() printf("strcmp(a,c) : %d\n",strcmp(a,c)); printf("strcmp(a,d) : %d\n",strcmp(a,d)); } - -执行 +``` +执行结果 +``` strcmp(a,b) : 32 strcmp(a,c) :-31 strcmp(a,d) : 0 @@ -586,8 +605,9 @@ main() printf("before strcpy() :%s\n",a); printf("after strcpy() :%s\n",strcpy(a,b)); } - -执行 +``` +执行结果 +``` before strcpy() :string(1) after strcpy() :string(2) ``` @@ -622,8 +642,9 @@ main() printf("%d\n",strcspn(str,"/-")); printf("%d\n",strcspn(str,"1234567890")); } - -执行 +``` +执行结果 +``` 5 /*只计算到" "的出现, 所以返回"Linux"的长度*/ 33 /*计算到出现"/"或"-", 所以返回到"6"的长度*/ 30 /* 计算到出现数字字符为止, 所以返回"3"出现前的长度*/ @@ -659,7 +680,9 @@ main() b=strdup(a); printf("b[ ]=\"%s\"\n",b); } -执行 +``` +执行结果 +``` b[ ]="strdup" ``` @@ -691,8 +714,9 @@ main() char *str = "12345678"; printf("str length = %d\n", strlen(str)); } - -执行 +``` +执行结果 +``` str length = 8 ``` @@ -726,8 +750,9 @@ main() if(!strncasecmp(a,b)) printf("%s =%s\n",a,b); } - -执行 +``` +执行结果 +``` aBcDef=AbCdEf ``` @@ -761,12 +786,35 @@ main() printf("before strnact() :%s\n", a); printf("after strncat() :%s\n", strncat(a,b,6)); } - -执行 +``` +执行结果 +``` before strnact() : string(1) after strncat() : string(1) string ``` +--- +## strncmp +(比较字符申) + +**相关函数** +bcmp, encamp, strcasecmp, strncasecmp, strcoll + +**头文件** +`#include ` + +**定义函数** +`int strncmp(const char*s1, const char *s2, size_t n);` + +**函数说明** + `strncmp()`用来将参数`s1`中前`n`个字符和参数`s2`字符串作比较。 + +**返回值** +若参数`sl`和`s2`字符串相同则返回0。`s1`若大于`s2`则返回大于0的值。`s1`若小于`s2`则返回小于0的值。 + +**范例** +请参考 `strcmp()`。 + --- ## strncpy @@ -789,18 +837,23 @@ strncpy()会将参数src字符串拷贝前n个字符至参数dest所指的地址 **范例** ``` -#inclue -main() +#include +#include + +int main() { - char a[30]="string(1)"; - char b[]="string(2)"; - printf("before strncpy() : %s\n",a); - printf("after strncpy() : %s\n",strncpy(a,b,6)); + char dest[10]; + const char *src = "Hello, World!"; + + strncpy(dest , src, sizeof(dest) -1); + dest[sizeof(dest) - 1] = '\0';// 显式添加空字符 + printf("%s",dest); + return 0; } - -执行 -before strncpy() : string(1) -after strncpy() : string(1) +``` +执行结果 +``` +Hello, Wo ``` --- @@ -835,8 +888,9 @@ main() p=strprk(s,"4398");/*3 会最先在s 字符串中找到*/ printf("%s\n",p); } - -执行 +``` +执行结果 +``` 1.23E+29 ``` @@ -871,8 +925,9 @@ main() p=strrchr(s,'5'); printf("%s\n",p); } - -执行 +``` +执行结果 +``` 567890 ``` @@ -905,7 +960,9 @@ main() char *t1="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; printf("%d\n",strspn(str,t1)); } -执行 +``` +执行结果 +``` 5 /*计算大小写字母。不包含" ", 所以返回Linux的长度。*/ ``` @@ -939,7 +996,9 @@ main() p = strstr(s,"901"); printf("%s\n",p); } -执行 +``` +执行结果 +``` 9.01E+21 ``` @@ -975,7 +1034,8 @@ main() while((p=strtok(NULL,delim))) printf("%s ",p); printf("\n"); } - -执行 +``` +执行结果 +``` ab cd ef;gh i jkl;mnop;qrs tu vwx y;z /*-与:字符已经被\0 字符取代*/ ``` diff --git a/06.md b/06.md index b07046c..5355d48 100644 --- a/06.md +++ b/06.md @@ -28,9 +28,9 @@ main() answer = abs(-12); printf("|-12| = %d\n", answer); } - -执行 - +``` +执行结果 +``` |-12| = 12 ``` @@ -70,8 +70,9 @@ main() angle = acos(0.5); printf("angle = %f\n", angle); } - -执行 +``` +执行结果 +``` angle = 1.047198 ``` @@ -110,8 +111,9 @@ main() angle = asin (0.5); printf("angle = %f\n",angle); } - -执行 +``` +执行结果 +``` angle = 0.523599 ``` @@ -147,7 +149,9 @@ main() angle =atan(1); printf("angle = %f\n",angle); } -执行 +``` +执行结果 +``` angle = 1.570796 ``` @@ -184,8 +188,9 @@ main() angle = atan2(1,2); printf("angle = %f\n", angle); } - -执行 +``` +执行结果 +``` angle = 0.463648 ``` @@ -222,8 +227,9 @@ main() for (i=0;value[i]!=0;i++) printf("%f=>%f\n",value[i],ceil(value[i])); } - -执行 +``` +执行结果 +``` 4.800000=>5.000000 1.120000=>2.000000 -2.200000=>-2.000000 @@ -261,8 +267,9 @@ main() double answer = cos(0.5); printf("cos (0.5) = %f\n",answer); } - -执行 +``` +执行结果 +``` cos(0.5) = 0.877583 ``` @@ -297,10 +304,54 @@ main() double answer = cosh(0.5); printf("cosh(0.5) = %f\n",answer); } -执行 +``` +执行结果 +``` cosh(0.5) = 1.127626 ``` +--- +## div +(取得两整型数相除后的商及余数) + +**相关函数** +ldiv + +**头文件** +`#include ` + +**定义函数** +` div_t div(int numer, int denom);` + +**函数说明** +`div()`函数会计算参数 `numer`/`denom`,然后将相除后的商及余数由`div_t`结构返回。`div_t`结构定义如下: + +``` +typedef struct +{ + int quot; /*商数*/ + int rem; /*余数*/ + } div_t; + ``` + +**返回值** +返回`div_t结构,包含商数及余数。 + +**范例** +```/*计算67/4的商及余数*/ +#include +main() +{ + div_t answer; + answer = div(67, 4); + printf("Quotient = %d. remainder = %d\n",answer.quot,answer.rem); +} +``` +执行结果 +``` +Quotient = 16. remainder = 3 +``` + --- ## exp @@ -334,11 +385,45 @@ main() answer = exp (10); printf("e^10 =%f\n", answer); } - -执行 +``` +执行结果 +``` e^10 = 22026.465795 ``` +--- +## fabs +(计算浮点型数的绝对值) + +**相关函数** +abs,labs + +**头文件** +`#include ` + +**定义函数** +`double fabs( doubie x);` + +**函嶽说明** +`fabs()`用来计算浮点型数`x`的绝对值,然后将结果返回。 + +**返回值** +返回参数`x`的绝对值计算结果。 + +**范例** +``` +#include +main() +{ + double answer; + answer =fabs(-3.141592); + printf("|-3.141592| = %f\n", answer); +} +``` +执行结果 +``` +|-3.141592| = 3.141592 +``` --- ## frexp @@ -374,11 +459,48 @@ main() printf("exp = %d\n",exp); printf("fraction = %f\n", fraction); } - -执行 +``` +执行结果 +``` exp = 11 fraction = 0.500000 /* 0.5*(2^11)=1024*/ ``` +--- +## labs +(计算长整型数的绝对值) + +**相关函数** +abs,fabs + +**头文件** +`#include ` + +**定义函数** +`long int labs (long int j);` + +**函数说明** +`labs()`用来计算参数`j`的绝对值,然后将结果返回。 + +**返回值** +返回j的绝对值计算结果。 + +**附加说明** +使用GCC编译时请加入 -lm + +**范例** +``` +#include +main() +{ + long int answer; + answer = labs(-2000); + printf("|-2000|= %d\n", answer); +} +``` +执行结果 +``` +|-2000|= 2000 +``` --- @@ -415,11 +537,52 @@ main() answer = ldexp(3,2); printf("3*2^(2) = %f\n",answer); } - -执行 +``` +执行结果 +``` 3*2^(2) = 12.000000 ``` +--- +## ldiv +(取得两长整数相除后的商及余数) + +**相关函数** +div +**头文件** +`#include ` + +**定义函数** + `ldiv_t ldiv( long int numer, long int denom);` + +**函数说明** +`ldiv()`函数会计算参数 `numer`/`denom`,然后将相除后的商及余数由`ldiv_t`结构返回。 `ldiv_t`结构定义如下: +``` +typedef struct +{ + long int quot; /*商数*/ + long int rem; /*余数*/ + } ldiv_t; +``` + +**返回值** +返回 `ldiv_t`结构,包含商数及余数。 + +**范例** +``` +/*计算2653589/79323的商及余数 +#include +main() +{ + ldiv_t answer; + answer = ldiv(2653589,79323); + printf("Quotient =%d, remainder =%d\n", answer.quot, answer.rem); +} +``` +执行结果 +``` +Quotient =33, remainder =35930 +``` --- ## log @@ -455,7 +618,9 @@ main() answer = log (100); printf("log(100) = %f\n",answer); } -执行 +``` +执行结果 +``` log(100) = 4.605170 ``` @@ -495,10 +660,52 @@ main() answer = log10(100); printf("log10(100) = %f\n",answer); } -执行 +``` +执行结果 +``` log10(100) = 2.000000 ``` +--- +## modf +(将浮点型数分解成整数与小数) + +**相关函数** +frexp + +**头文件** +`#include ` + +**定义函数** +`double modf(double x, double *iptr);` + +**函数说明** +`modf()`用来将参数`x`的浮点型数分解成整数和小数。小数部分直接返回,整数部分则借参数`iptr`指针返回。 + +**返回值** +返回参数`x`的小数部分,整数部分则存于`iptr`指针所指的地址。 + +**附加说明** +使用GCC编译时请加入-lm。 + +**范例** +``` +/*分解3.141592的整数与小数部分*/ +#include +main() +{ + double integral; + double fractional; + fractional =modf(3.141592,&integral); + printf("integral =%f\n", integral); + printf("fractional = %f\n",fractional); +} +``` +执行结果 +``` +integral =3.000000 +fractional = 0.141592 +``` --- ## pow @@ -534,8 +741,9 @@ main() answer =pow(2,10); printf("2^10 = %f\n", answer); } - -执行 +``` +执行结果 +``` 2^10 = 1024.000000 ``` @@ -570,8 +778,9 @@ main() double answer = sin (0.5); printf("sin(0.5) = %f\n",answer); } - -执行 +``` +执行结果 +``` sin(0.5) = 0.479426 ``` @@ -607,8 +816,9 @@ main() double answer = sinh (0.5); printf("sinh(0.5) = %f\n",answer); } - -执行 +``` +执行结果 +``` sinh(0.5) = 0.521095 ``` @@ -648,7 +858,9 @@ main() root = sqrt (200); printf("answer is %f\n",root); } -执行 +``` +执行结果 +``` answer is 14.142136 ``` @@ -683,7 +895,9 @@ main() double answer = tan(0.5); printf("tan (0.5) = %f\n",answer); } -执行 +``` +执行结果 +``` tan(0.5) = 0.546302 ``` @@ -719,7 +933,8 @@ main() double answer = tanh(0.5); printf("tanh(0.5) = %f\n",answer); } - -执行 +``` +执行结果 +``` tanh(0.5) = 0.462117 ``` \ No newline at end of file diff --git a/07.md b/07.md index 76d3e0d..817ebf8 100644 --- a/07.md +++ b/07.md @@ -1,5 +1,41 @@ # 用户组篇 +## cuserid +(取得用户帐号名称) + +**相关函数** + getlogin + +**头文件** +`#include ` + +**定义函数** +`char *cuserid(char *string);` + +**函数说明** +`cuserid()`会将用户帐号名称复制到参数 `string`所指的字符串数组中,如果参数 `string`为空指针(`NULL`),`userid()`会自动配置一静态的字符串数组,然后将指向此字符串的指针返回,此自动配置的空间大小由定义在`stdio.h`中的 `L_cuserid`值决定(POSIX定义为9)。注意, `cuserid()`自动配置的字符串数组会由调用 `getlogin()`或再调用 `cuserid()`时所覆盖。 + +**返回值** +请尽量使用 `getpwuid(geteuid());`来取代此函数。 + +**附加说明** +返回指向用户帐号名称的字符串指针。 + +**范例** +``` +#include +main() +{ + printf("I am %s.\n",cuserid()); +} +``` +执行结果 +``` +I am root. /* 当使用root身份执行范例程序时 */ +``` +--- + + ## endgrent (关闭组文件) @@ -114,8 +150,9 @@ main() } fclose(stream); } - -执行 +``` +执行结果 +``` root:x:0:root, bin:x:1:root,bin,daemon daemon:x:2:root,bin,daemon @@ -173,8 +210,9 @@ main() printf("%s:%d:%d:%s:%s:%s\n",user->pw_name,user->pw_uid,user->pw_gid,user->pw_gecos,user->pw_dir,user->pw_shell); } } - -执行 +``` +执行结果 +``` root:0:0:root:/root:/bin/bash bin:1:1:bin:/bin: daemon:2:2:daemon:/sbin: @@ -220,8 +258,9 @@ main() { printf("egid is %d\n",getegid()); } - -执行 +``` +执行结果 +``` egid is 0 /*当使用root身份执行范例程序时*/ ``` @@ -252,8 +291,9 @@ main() { printf ("euid is %d \n",geteuid()); } - -执行 +``` +执行结果 +``` euid is 0 /*当使用root身份执行范例程序时*/ ``` @@ -284,8 +324,9 @@ main() { printf("gid is %d\n",getgid()); } - -执行 +``` +执行结果 +``` gid is 0 /*当使用root身份执行范例程序时*/ ``` @@ -340,8 +381,9 @@ main() } endgrent(); } - -执行 +``` +执行结果 +``` root:x:0:root, bin:x:1:root,bin,daemon, daemon:x:2:root,bin,daemon, @@ -399,8 +441,9 @@ main() while(data->gr_mem[i]) printf("%s ,",data->mem[i++]); printf("\n"); } - -执行 +``` +执行结果 +``` sys:x:3:root,bin,adm ``` @@ -439,7 +482,9 @@ main() while(data->gr_mem[i])printf("%s,",data->gr_mem[i++]); printf("\n"); } -执行 +``` +执行结果 +``` adm:x:4:root,adm,daemon ``` @@ -480,7 +525,9 @@ main() for(i=0;i` + +**定义函数** +`char* getlogin(void);` + +**函数说明** + `getlogin()`会从 `/var/run/utmp`中查找登录目前终端机的用户帐号名称,找不到相关数据就返回一空指针(`NULL`),如果找到帐号名称就自动配置一字符串数组,把帐号名称复制到此数组,最后将指向此字符串的指针返回。 +注意, `getlogin()`自动配置的字符串数组会由调用 `cuserid`或再调用 `getlogin()`时所覆盖。 + +**附加说明** +`getlogin()`会有潜在的安全性问题,使用时请留意!环境变量 `LOGNAME`同样也是取得登录的用户帐号名称。 + +**返回值** +返回指向用户帐号名称的字符串指针。 + +**范例** +``` +#include +main() +{ + printf("I am %s.\n",getlogin()); +} +``` +执行结果 +``` +I am root. /* 当使用root身份执行范例程序时 */ +``` + --- ## getpw @@ -525,7 +609,9 @@ main() getpw(0,buffer); printf("%s\n",buffer); } -执行 +``` +执行结果 +``` root:x:0:0:root:/root:/bin/bash ``` @@ -578,8 +664,9 @@ main() } endpwent(); } - -执行 +``` +执行结果 +``` root:0:0:root:/root:/bin/bash bin:1:1:bin:/bin: daemon:2:2:daemon:/sbin: @@ -635,7 +722,9 @@ main() printf("uid:%d\n",user->pw_uid); printf("home:%s\n",user->pw_dir); } -执行 +``` +执行结果 +``` name:root uid:0 home:/root @@ -707,7 +796,9 @@ main() { printf("uid is %d\n",getuid()); } -执行 +``` +执行结果 +``` uid is 0 /*当使用root身份执行范例程序时*/ ``` @@ -784,13 +875,14 @@ main() { struct utmp *u; while((u=getutent())){ - if(u->ut_type = = USER_PROCESS) + if(u->ut_type == USER_PROCESS) printf("%d %s %s %s \n",u->ut_type,u->ut_user,u->ut_line,u->ut_host); } endutent(); } - -执行 +``` +执行结果 +``` /* 表示有三个root账号分别登录/dev/pts/0, /dev/pts/1, /dev/pts/2 */ 7 root pts/0 7 root pts/1 @@ -828,7 +920,9 @@ main() printf("%d %s %s %s\n",u->ut_type,u->ut_user,u->ut_line,u->ut_host); } } -执行 +``` +执行结果 +``` 1 runlevel - ``` @@ -863,7 +957,9 @@ main() printf("%d %s %s %s \n",u->ut_type,u->ut_user,u->ut_line,u->ut_host); } } -执行 +``` +执行结果 +``` 7 root pts/1 ``` @@ -888,6 +984,44 @@ initgroups()用来从组文件(/etc/group)中读取一项组数据, 若该 **返回值** 执行成功则返回0, 失败则返回-1, 错误码存于errno。 +--- + +## logwtmp +(将一登录数据记录到wtmp文件) + +**相关函数** + updtmp, getutent + +**头文件** +`#include ;` + +**定义涵数** +`void logwtmp(const char *line, const char* name, const char *host);` + +**函数说明** +`logwtmp()`会依参数`line`、`name`和`host`所指定的装置名、帐号和远程主机等数据自动建立一`utmp`结构,然后调用 `updwtmp()`来将此记录写入到`wtmp`文件(`/var/log/wtmp`)。 + +**附加说明** +需要有wtmp文件的写入权限 + +**返回值** +无 + +**范例** +``` +#include +maln() +{ + logwtmp("pts/2","kids","www.gnu.org"); +} +``` +执行结果 +``` +/*表示有三个root帐号分别登录/dev/pts/0,/dev/pts/1,/dev/pts/2 */ +7 root pts/0 +7 root pts/1 +7 root pts/2 +``` --- ## pututline @@ -923,14 +1057,35 @@ main() strcpy(ut.ut_host,"www.gnu.org"); pututline(&ut); } -执行 +``` +执行结果 +``` /*执行范例后用指令who -l 观察*/ root pts/0 dec9 19:20 kids pts/1 dec12 10:31(www.gnu.org) root pts/2 dec12 13:33 ``` +--- ---- +## setegid +(设置有效的组识别码) + +**相关函数** + setgid, setregid, setfsgid + +**头文件** +`#include ` + +**定义函数** +`int setegid(gid_t egid);` + +**函数说明** +`setegid()`用来重新设置执行目前进程的有效组识别码。在 Linux下, `setegid(egid)`相当于 `setregid(-l,egid)`。 + +**返回值** +执行成功则返回0,失败则返回-1,错误代码存于`errno`。 + +--- ## seteuid (设置有效的用户识别码) @@ -1023,11 +1178,12 @@ getgid, setregid, getegid, setegid setgid()用来将目前进程的真实组识别码(real gid)设成参数gid值。如果是以超级用户身份执行此调用, 则real、effective与savedgid都会设成参数gid。 **返回值** -设置成功则返回0, 失败则返回-1, 错误代码存于errno中。 +设置成功则返回0, 失败则返回-1, 错误代码存于errno中。 + **错误代码** -EPERM 并非以超级用户身份调用, 而且参数gid 并非进程的effective gid或saved gid值之一。 -  +EPERM并非以超级用户身份调用, 而且参数gid 并非进程的effective gid或saved gid值之一。 + --- ## setgrent @@ -1050,7 +1206,7 @@ setgrent()用来将getgrent()的读写地址指回组文件开头。 **附加说明** 请参考setpwent()。 -  + --- ## setgroups @@ -1115,8 +1271,9 @@ main() user->pw_gecos,user->pw_dir,user->pw_shell); endpwent(); } - -执行 +``` +执行结果 +``` root:0:0:root:/root:/bin/bash bin:1:1:bin:/bin daemon:2:2:daemon:/sbin @@ -1213,6 +1370,51 @@ setutent()用来将getutent()的读写地址指回utmp文件开头。 --- +## updwtmp +(将一登录数据记录到wtmp文件) + +**相关函数** + logwtmp, pututline + +**头文件** +`#include ` + +**定义函数** +`void updwtmp( const char* wtmp_file, const struct utmp *ut);` + +**函数说明** +`updwtmp()`用来将先前 `logwtmp()`所建立的`utmp`结构写入到文件内。 +参数`ut`为 `logwtmp()`建立的`utmp`结构数据,参数`wtmp_file`则为欲写入的`wtmp`文件( `/var/log/wtmp`)。 + +**附加说明** +需要有`wmp`文件的写入权限 + +**返回值** +无 + +**范例** +``` +#include +#include +main() +{ + struct utmp ut; + ut.ut_type =USER_PROCESS; + ut.ut_pid= getpid(); + strcpy(ut.ut_user, "kids"); + strcpy(ut.ut_line, "pts/1"); + strcpy(ut.ut_host,"www.gnu.org"); + updwtmp("/var/log/wtmp",&ut); +} +``` +执行结果 +``` +/*利用指令last来观察*/ +kids pts/1 www.gnu.org Mon Dec 11 10: 31 still logged in +``` + +--- + ## utmpname (设置utmp 文件路径) diff --git a/08.md b/08.md index e132715..af4b2e5 100644 --- a/08.md +++ b/08.md @@ -102,7 +102,7 @@ main() base = data[0]; qsort(base,nmemb,size,compar); offset = (char *) bsearch(key,base,nmemb,size,compar); - if( offset = =NULL) + if( offset == NULL) { printf("%s not found!\n",key); strcpy(data[nmemb++],key); @@ -235,31 +235,30 @@ bsearch **范例** ``` -#define nmemb 7 +#include #include -int compar (const void *a ,const void *b) -{ - int *aa=(int * ) a,*bb = (int * )b; - if( * aa >* bb)return 1; - if( * aa == * bb) return 0; - if( * aa < *bb) return -1; + +int compare(const void *a, const void *b) { + return (*(int *)a - *(int *)b); } -main( ) -{ - int base[nmemb]={ 3,102,5,-2,98,52,18}; - int i; - for ( i=0; i main() { - if(vfork() = =0) + if(vfork() == 0) { printf("This is the child process\n"); }else{ @@ -705,7 +705,7 @@ main() { pid_t pid; int status,i; - if(fork()= =0){ + if(fork() == 0){ printf("This is the child process .pid =%d\n",getpid()); exit(5); }else{ @@ -911,8 +911,8 @@ main() --- -## sacnf -(格式化字符串输入) +## scanf +(格式化字符串输入,常用于从键盘读取用户输入的数据) **相关函数** fscanf, snprintf @@ -924,7 +924,7 @@ fscanf, snprintf `int scanf(const char * format, ...);` **函数说明** -scanf()会将输入的数据根据参数format字符串来转换并格式化数据。Scanf()格式转换的一般形式如下 +scanf()会将输入的数据根据参数format字符串来转换并格式化数据。scanf()格式转换的一般形式如下 `%[*][size][l][h]type` 以中括号括起来的参数为选择性参数, 而%与type则是必要的。 * 代表该对应的参数数据忽略不保存。 @@ -1000,7 +1000,7 @@ main() char * a="This is string A!"; char buf[80]; sprintf(buf,">>> %s<<<\n",a); - printf("%s".buf); + printf("%s",buf); } 执行 >>>This is string A!<<< @@ -1009,7 +1009,7 @@ main() --- ## sscanf -(格式化字符串输入) +(格式化字符串输入,在处理字符串数据或解析特定格式的文本时更为有用,例如从文件中读取的字符串或从网络接收的数据包) **相关函数** scanf, fscanf @@ -1021,7 +1021,7 @@ scanf, fscanf `int sscanf (const char *str, const char * format, ...);` **函数说明** -sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。 +sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据,格式转换形式请参考scanf(),转换后的结果存于对应的参数内。 **返回值** 成功则返回参数数目, 失败则返回-1, 错误原因存于errno中。 diff --git a/12.md b/12.md index d933d35..86a008a 100644 --- a/12.md +++ b/12.md @@ -900,7 +900,7 @@ main() while((ptr = readdir(dir))!=NULL) { offset = telldir(dir); - if(++i = =5) offset_5 =offset; + if(++i == 5) offset_5 =offset; printf("d_name :%s offset :%d \n",ptr->d_name,offset); } seekdir(dir offset_5); diff --git a/13.md b/13.md index dd96e1f..90666cc 100644 --- a/13.md +++ b/13.md @@ -199,7 +199,7 @@ main() sigaction(SIGUSR1,&act,&oldact); for(i=5;i<15;i++) { - printf("sa_handler of signal %2d =".i); + printf("sa_handler of signal %2d =",i); sigaction(i,NULL,&oldact); } } @@ -482,7 +482,7 @@ main() { FILE *fp; fp = fopen("/tmp/noexist","r+"); - if(fp = =NULL) perror("fopen"); + if(fp == NULL) perror("fopen"); } 执行 $ ./perror diff --git a/14.md b/14.md index 2c6d1ae..fa2eaf2 100644 --- a/14.md +++ b/14.md @@ -447,7 +447,7 @@ if(is_connected[fd]) FD_SET(fd,&readfds); if(!select(MAXSOCKFD,&readfds,NULL,NULL,NULL))continue; for(fd=0;fd