1. 程式人生 > >C指標原理(24)-C指標基礎

C指標原理(24)-C指標基礎

取自netbsd中的原始碼,檢查運算溢位,用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;

[email protected]:~/test/asb# gcc test1.c
[email protected]:~/test/asb# ./a.out
-46
-30
110
[email protected]:~/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、檔案指標

[email protected]:~/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讀取命令列引數中的文字檔案,將它們內容輸出

[email protected]:~/test1 % cc test2.c -o mytest

[email protected]:~/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;

}

也可一次向命令列指定更多文字檔案

[email protected]:~/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函式來讀取

[email protected]:~/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;

}

[email protected]:~/test1 % cc test2.c -o mytest

[email protected]:~/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);

}

[email protected]:~/test1 %

下面的例子展示了從鍵盤輸入文字增加到文字檔案後面,如果輸入%end%表示輸入結束。

[email protected]:~/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;

}

執行結果如下

[email protected]:~/test1 % cc test2.c -o mytest2

[email protected]:~/test1 % ./mytest2 hello.txt

hello.txt內容如下:

你好,各位朋友,很高興認識大家。

Google是一家美國的跨國科技企業,致力於網際網路搜尋、雲端計算、廣告技術等領域,開發並提供大量基於網際網路的產品與服務,其主要利潤來自於AdWords等廣告服務。

[email protected]:~/test1 %

[email protected]:~/test1 % cc test5.c -o mytest5

[email protected]:~/test1 % ./mytest5 hello.txt

請輸入文字:你好 ,今天天氣如何?

請輸入文字:今天天氣不錯!

請輸入文字:謝謝!

請輸入文字:%end%

[email protected]:~/test1 % ./mytest2 hello.txt

hello.txt內容如下:

你好,各位朋友,很高興認識大家。

Google是一家美國的跨國科技企業,致力於網際網路搜尋、雲端計算、廣告技術等領域,開發並提供大量基於網際網路的產品與服務,其主要利潤來自於AdWords等廣告服務。

你好,今天天氣如何?

今天天氣不錯!

謝謝!

[email protected]:~/test1 %