C指针原理(24)-C指针基础
取自netbsd中的源碼,檢查運算溢出,用C語言實現(xiàn),方法很精妙
/*
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。這樣能容納的時間數(shù)更大。
L是long,LL是long long
定義了bintime的結(jié)構(gòu),以及其加減運算。uint64_t類型的frac是無符號整數(shù),下面要用到這個特性
#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++;
}
數(shù)據(jù)是以補碼方式存放在內(nèi)存中!無符號整數(shù)溢出表現(xiàn)為: x + y < x 就表示溢出了.,因此,上面才有
if (u > bt->frac)
bt->sec++;
這樣的判斷,很巧妙的想法,溢出了就進位。
下面演示了加法的溢出
因為上面編譯器進行編譯時,char是有符號的,即signed char。
在C/C++語言中,char變量為一個字節(jié),8位,signed char表示的范圍:-128~127【-128在內(nèi)存中的二進制表示為1000 0000,127在內(nèi)存中的表示為0111 1111】;unsign char表示的范圍:0000 0000~1111 1111,即0~255;
root@xxxx:~/test/asb# gcc test1.c
root@xxxx:~/test/asb# ./a.out
-46
-30
110
root@xxxx:~/test/asb#
很明顯,90+120已經(jīng)溢出了,因為無法表達210這個有符號數(shù),用一個8位的字節(jié)。而a+c則正常計算。
下面繼續(xù)分析。
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個時間結(jié)構(gòu)類型的加法,同樣通過溢出檢查來實現(xiàn)進位。
下面是2個時間結(jié)構(gòu)類型的減法。
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){//打開文件,如果出現(xiàn)錯誤,則顯示錯誤信息FILE *input=fopen(*argv,"r");if (input==NULL){perror(*argv);exit_status=EXIT_FAILURE;continue;}printf ("\n%s內(nèi)容如下:\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讀取命令行參數(shù)中的文本文件,將它們內(nèi)容輸出
dp@dp:~/test1 % cc test2.c -o mytest
dp@dp:~/test1 % ./mytest test1.c
test1.c內(nèi)容如下:
#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內(nèi)容如下:
#include <stdio.h>int main(int argc,int **argv){printf ("%s","abcdefgh"+2);}hello.txt內(nèi)容如下:
你好,各位朋友,很高興認識大家。 Google是一家美國的跨國科技企業(yè),致力于互聯(lián)網(wǎng)搜索、云計算、廣告技術(shù)等領(lǐng)域,開發(fā)并提供大量基于互聯(lián)網(wǎng)的產(chǎn)品與服務(wù),其主要利潤來自于AdWords等廣告服務(wù)。也可以使用fgets函數(shù)來讀取
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){//打開文件,如果出現(xiàn)錯誤,則顯示錯誤信息FILE *input=fopen(*argv,"r");if (input==NULL){perror(*argv);exit_status=EXIT_FAILURE;continue;}printf ("\n%s內(nèi)容如下:\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內(nèi)容如下:
你好,各位朋友,很高興認識大家。
Google是一家美國的跨國科技企業(yè),致力于互聯(lián)網(wǎng)搜索、云計算、廣告技術(shù)等領(lǐng)域,開發(fā)并提供大量基于互聯(lián)網(wǎng)的產(chǎn)品與服務(wù),其主要利潤來自于AdWords等廣告服務(wù)。
test3.c內(nèi)容如下:
#include <stdio.h>int main(int argc,int **argv){printf ("%s","abcdefgh"+2);}dp@dp:~/test1 %
下面的例子展示了從鍵盤輸入文字增加到文本文件后面,如果輸入%end%表示輸入結(jié)束。
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){//打開文件,如果出現(xiàn)錯誤,則顯示錯誤信息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函數(shù)不會讀取換行符,因此加上換行符fputc(ch,output);}else break;}if (fclose(output)!=0){perror(*argv);exit_status=EXIT_FAILURE;}}return exit_status;}執(zhí)行結(jié)果如下
dp@dp:~/test1 % cc test2.c -o mytest2
dp@dp:~/test1 % ./mytest2 hello.txt
hello.txt內(nèi)容如下:
你好,各位朋友,很高興認識大家。
Google是一家美國的跨國科技企業(yè),致力于互聯(lián)網(wǎng)搜索、云計算、廣告技術(shù)等領(lǐng)域,開發(fā)并提供大量基于互聯(lián)網(wǎng)的產(chǎn)品與服務(wù),其主要利潤來自于AdWords等廣告服務(wù)。
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內(nèi)容如下:
你好,各位朋友,很高興認識大家。
Google是一家美國的跨國科技企業(yè),致力于互聯(lián)網(wǎng)搜索、云計算、廣告技術(shù)等領(lǐng)域,開發(fā)并提供大量基于互聯(lián)網(wǎng)的產(chǎn)品與服務(wù),其主要利潤來自于AdWords等廣告服務(wù)。
你好,今天天氣如何?
今天天氣不錯!
謝謝!
dp@dp:~/test1 %
總結(jié)
以上是生活随笔為你收集整理的C指针原理(24)-C指针基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机专业怎样提升竞争力,新形势下如何提
- 下一篇: python英文字典小程序_python