11.06.2015

Linux C getc(), putc()

int getc(FILE *stream);

int putc(int c, FILE *stream);

getc(), putc()的操作方法,完全和fgetc(), fputc()一模一樣,可以拿之前的案例來做修改:Linux C fgetc(), fputc()
// getc_putc.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int 
main()
{
    FILE *fp0 = (FILE *)NULL, *fp1 = (FILE *)NULL;
    char cKey = '\0';

    fp0 = fopen("GET.TXT", "r");
    if (ferror(fp0) != 0) {
        fclose(fp0);
        return 1;
    }

    fp1 = fopen("PUT.TXT", "w+");
    if (ferror(fp1) != 0) {
        fclose(fp1);
        return 1;
    }

    while((cKey = getc(fp0)) != EOF)
        putc(cKey, fp1);

    fclose(fp0);
    fclose(fp1);

    return 0;
}
那它們彼此之間的差異在那?? 書本上是這麼說的:「getc(), putc()為巨集 (Micro / 宏)定義,並非真正地函式呼叫。

但自己很無聊地追了一下原始碼,發現以下這兩段:

/usr/include/stdio.h (Fedora Linux 13; 原本的比較亂,我稍微排版一下)
// /usr/include/stdio.h

__BEGIN_NAMESPACE_STD
/*  Read a character from STREAM.

    These functions are possible cancellation points and th-
    erefore not marked with __THROW.
*/
extern int fgetc (FILE *__stream);
extern int getc (FILE *__stream);

/*  Read a character from stdin.

    This function is a possible cancellation point and th-
    erefore not marked with __THROW.
*/
extern int getchar (void);
__END_NAMESPACE_STD

/*  The C standard explicitly says this is a macro, so we 
    always do the optimization for it.
*/
#define getc(_fp) _IO_getc (_fp)

/*
    Other source code....
*/
__BEGIN_NAMESPACE_STD
/*  Write a character to STREAM.

    These functions are possible cancellation points and th-
    erefore not marked with __THROW.

    These functions is a possible cancellation point and th-
    erefore not marked with __THROW.
*/
extern int fputc (int __c, FILE *__stream);
extern int putc (int __c, FILE *__stream);

/*  Write a character to stdout.

    This function is a possible cancellation point and th-
    erefore not marked with __THROW.
*/
extern int putchar (int __c);
__END_NAMESPACE_STD

/*  The C standard explicitly says this can be a macro, so 
    we always do the optimization for it.
*/
#define putc(_ch, _fp) _IO_putc (_ch, _fp)
發現fgetc(), fputc(), getc(), putc()全部都是函式呼叫 (包括getchar()putchar()也是);只不過getc()和putc()又多定義了一份巨集,讓它們又可以直接呼叫到底層的_IO_getc()_IO_putc()

那麼函式呼叫和巨集定義的差別在哪?? 巨集定義的執行速度比函式呼叫要來得快!!

為何巨集定義的執行速度比函式呼叫要來得快?? 並不是這裡討論的重點。

不過,就現今處理器 (CPU)的執行速度來看,這裡的快或慢,就沒有太大的差異了。

沒有留言:

張貼留言