C指針原理(24)-C指針基礎
/*
? hide bintime for _STANDALONE because this header is used for hpcboot.exe,
? which is built with compilers which don‘t recognize LL suffix.
?* http://mail-index.NetBSD.org/tech-userlevel/2008/02/27/msg000181.html
?*/
下面這段使用了LL後綴,要檢查一下編譯器是否支持,如果支持,則定義_STANDALONE。這樣能容納的時間數更大。
L是long,LL是long long
定義了bintime的結構,以及其加減運算。uint64_t類型的frac是無符號整數,下面要用到這個特性
#if !defined(_STANDALONE)
struct bintime {
time_t sec;
uint64_t frac;
};
static __inline void
bintime_addx(struct bintime *bt, uint64_t x)
{
uint64_t u;
u = bt->frac;
bt->frac += x;
if (u > bt->frac)
bt->sec++;
}
數據是以補碼方式存放在內存中!無符號整數溢出表現為: x?+?y?<?x?就表示溢出了.,因此,上面才有
if (u > bt->frac)
bt->sec++;
這樣的判斷,很巧妙的想法,溢出了就進位。?
下面演示了加法的溢出
因為上面編譯器進行編譯時,char是有符號的,即signed char。
在C/C++語言中,char變量為一個字節,8位,signed char表示的範圍:-128~127【-128在內存中的二進制表示為1000 0000,127在內存中的表示為0111 1111】;unsign char表示的範圍:0000 0000~1111 1111,即0~255;
root@myhaspl:~/test/asb# gcc test1.c
root@myhaspl:~/test/asb# ./a.out
-46
110
root@myhaspl:~/test/asb#
很明顯,90+120已經溢出了,因為無法表達210這個有符號數,用一個8位的字節。而a+c則正常計算。
下面繼續分析。
static __inline void
bintime_add(struct bintime *bt, const struct bintime *bt2)
{
uint64_t u;
u = bt->frac;
bt->frac += bt2->frac;
if (u > bt->frac)
bt->sec++;
bt->sec += bt2->sec;
}
?bintime_add也完成2個時間結構類型的加法,同樣通過溢出檢查來實現進位。?
下面是2個時間結構類型的減法。
static __inline void
bintime_sub(struct bintime *bt, const struct bintime *bt2)
{
uint64_t u;
u = bt->frac;
bt->frac -= bt2->frac;
if (u < bt->frac)
bt->sec--;
bt->sec -= bt2->sec;
}
9、文件指針
dp@dp:~/test1?%?vim?test2.c
#include?<stdio.h>
#include?<stdlib.h>
int?main(int?argc,char?**argv){
????????int?exit_status=EXIT_SUCCESS;
????????while?(*++argv!=NULL)
????????{
????????????????//打開文件,如果出現錯誤,則顯示錯誤信息
????????????????FILE?*input=fopen(*argv,"r");
????????????????if?(input==NULL){
????????????????????????perror(*argv);
????????????????????????exit_status=EXIT_FAILURE;
????????????????????????continue;
????????????????}
????????????????printf?("\n%s內容如下:\n",*argv);
????????????????int?ch;
????????????????while((ch=fgetc(input))!=EOF){
????????????????????????printf("%c",ch);
????????????????????????}
????????????????if?(fclose(input)!=0){
????????????????????????perror(*argv);
????????????????????????exit_status=EXIT_FAILURE;
????????????????}
????????}
????????return?exit_status;
}
上面程序使用fgetc讀取命令行參數中的文本文件,將它們內容輸出
dp@dp:~/test1?%?cc?test2.c?-o?mytest
dp@dp:~/test1?%?./mytest?test1.c
test1.c內容如下:
#include?<stdio.h>
int?add(int?a,int?b);
int?main(void){
????????int?(*myfunc)(int?a,int?b);
????????myfunc=add;
????????int?x=myfunc(12,36);
????????printf("%d",x);
????????return?1;
}
int?add(int?a,int?b){
????????return?a+b;
}
也可一次向命令行指定更多文本文件
dp@dp:~/test1?%?./mytest?test1.c?test3.c?hello.txt
#include?<stdio.h>
int?add(int?a,int?b);
int?main(void){
????????int?(*myfunc)(int?a,int?b);
????????myfunc=add;
????????int?x=myfunc(12,36);
????????printf("%d",x);
????????return?1;
}
int?add(int?a,int?b){
????????return?a+b;
}
test3.c內容如下:
#include?<stdio.h>
int?main(int?argc,int?**argv){
????????printf?("%s","abcdefgh"+2);
}
hello.txt內容如下:
你好,各位朋友,很高興認識大家。
Google是一家美國的跨國科技企業,致力於互聯網搜索、雲計算、廣告技術等領域,開發並提供大量基於互聯網的產品與服務,其主要利潤來自於AdWords等廣告服務。
也可以使用fgets函數來讀取
dp@dp:~/test1?%?vim?test2.c
#include?<stdio.h>
#include?<stdlib.h>
int?main(int?argc,char?**argv){
????????int?exit_status=EXIT_SUCCESS;
????????while?(*++argv!=NULL)
????????{
????????????????//打開文件,如果出現錯誤,則顯示錯誤信息
????????????????FILE?*input=fopen(*argv,"r");
????????????????if?(input==NULL){
????????????????????????perror(*argv);
????????????????????????exit_status=EXIT_FAILURE;
????????????????????????continue;
????????????????}
????????????????printf?("\n%s內容如下:\n",*argv);
????????????????char?mytext[500];
????????????????while(fgets(mytext,500,input)!=NULL){
????????????????????????printf("%s",mytext);
????????????????}
????????????????if?(fclose(input)!=0){
????????????????????????perror(*argv);
????????????????????????exit_status=EXIT_FAILURE;
????????????????}
????????}
????????return?exit_status;
}
dp@dp:~/test1?%?cc?test2.c?-o?mytest
dp@dp:~/test1?%?./mytest?hello.txt?test3.c
hello.txt內容如下:
你好,各位朋友,很高興認識大家。
Google是一家美國的跨國科技企業,致力於互聯網搜索、雲計算、廣告技術等領域,開發並提供大量基於互聯網的產品與服務,其主要利潤來自於AdWords等廣告服務。
test3.c內容如下:
#include?<stdio.h>
int?main(int?argc,int?**argv){
????????printf?("%s","abcdefgh"+2);
}
dp@dp:~/test1?%
下面的例子展示了從鍵盤輸入文字增加到文本文件後面,如果輸入%end%表示輸入結束。
dp@dp:~/test1?%?vim?test5.c
#include?<string.h>
#include?<stdio.h>
#include?<stdlib.h>
int?main(int?argc,char?**argv){
????????int?exit_status=EXIT_SUCCESS;
????????while?(*++argv!=NULL)
????????{
????????????????//打開文件,如果出現錯誤,則顯示錯誤信息
????????????????FILE?*output=fopen(*argv,"a");
????????????????if?(output==NULL){
????????????????????????perror(*argv);
????????????????????????exit_status=EXIT_FAILURE;
????????????????????????continue;
????????????????}
????????????????char?mytext[500];
????????????????int?ch=‘\n‘;
????????????????while?(1){
????????????????????????printf("請輸入文字:");
????????????????????????scanf("%s",&mytext);
????????????????????????if?(strcmp(mytext,"%end%")!=0){
????????????????????????????????fputs(mytext,output);
????????????????????????????????//scanf函數不會讀取換行符,因此加上換行符
????????????????????????????????fputc(ch,output);
????????????????????????}
????????????????????????else?break;
????????????????}
????????????????if?(fclose(output)!=0){
????????????????????????perror(*argv);
????????????????????????exit_status=EXIT_FAILURE;
????????????????}
????????}
????????return?exit_status;
}
執行結果如下
dp@dp:~/test1?%?cc?test2.c?-o?mytest2
dp@dp:~/test1?%?./mytest2?hello.txt
hello.txt內容如下:
你好,各位朋友,很高興認識大家。
Google是一家美國的跨國科技企業,致力於互聯網搜索、雲計算、廣告技術等領域,開發並提供大量基於互聯網的產品與服務,其主要利潤來自於AdWords等廣告服務。
dp@dp:~/test1?%
dp@dp:~/test1?%?cc?test5.c?-o?mytest5
dp@dp:~/test1?%?./mytest5?hello.txt
請輸入文字:你好?,今天天氣如何?
請輸入文字:今天天氣不錯!
請輸入文字:謝謝!
請輸入文字:%end%
dp@dp:~/test1?%?./mytest2?hello.txt
hello.txt內容如下:
你好,各位朋友,很高興認識大家。
Google是一家美國的跨國科技企業,致力於互聯網搜索、雲計算、廣告技術等領域,開發並提供大量基於互聯網的產品與服務,其主要利潤來自於AdWords等廣告服務。
你好,今天天氣如何?
今天天氣不錯!
謝謝!
dp@dp:~/test1?%
C指針原理(24)-C指針基礎