2014-01-21 55 views
3

我在The UNIX Programming Environment(1984年版權日期發佈)中發現此代碼塊。關於C語言的這個陳述的困惑?

chp8-> hoc3-> symbol.c

char *emalloc(n) /* check return from malloc */ 
unsigned n; 
{ 
char *p, *malloc(); 

p = malloc(n); 
if (p == 0) 
    execerror("out of memory", (char *) 0); 
return p; 
} 

什麼意思:

char *p, *malloc(); 

這真的很奇怪嗎?

+2

這是舊的「Kernigan&Ritchie」C. C標準自此發展了很多。 –

+1

[K&R C函數聲明](http://en.wikipedia.org/wiki/K%26R_C#K.26R_C) –

+4

如果有更新的版本,請更改您閱讀的書籍或更新版本,因爲它的日期很久。它不使用函數原型,這是C89或ANSI C的最重要特性。 – legends2k

回答

3
char *p, *malloc(); 

被聲明一個指針char名爲p和名爲malloc功能(在這K個& R C天,void*不存在)。

這是舊的Kernigan &裏奇C(從20世紀80年代)。自那時以來,C標準已經發生了重大變化。目前的C標準是C11,其以前的版本C99使用非常廣泛。

今天不要這樣編碼。 malloc<stdlib.h>中定義,它可能在那裏有一些inlined function(但通常不是)。

您的功能今天通常通常被稱爲xmalloc;你需要在你的文件(因爲mallocexit<stdlib.h>聲明並EXIT_FAILURE定義那裏,perror<stdio.h>聲明)開始添加

#include <stdlib.h> 
#include <stdio.h> 

,並會被定義爲

void* xmalloc(size_t sz) { 
    void* p = malloc(sz); 
    if (!p) { 
     perror("malloc"); 
     exit(EXIT_FAILURE); 
    }; 
    return p; 
} 

,並在你的一些頭與

void* xmalloc(size_t sz); 
聲明210

我建議閱讀一本新書。在Linux上,至少考慮Advanced Linux Programming(從2001年開始)。

如果使用GCC,您可以將function attributes添加到您的函數聲明中。

+0

但它仍然在c99有效? – tristan

+1

@tristan:此答案中的特定行在C99中有效,但不包含原始問題中發佈的代碼段。 – dreamlax

+0

@dreamlax:是'char * malloc();'有效嗎? 「malloc」的原型不同嗎? – legends2k

2

大部分的混淆來自使用舊版本的舊書,它使用了一個非常舊的C版本(稱爲K&R C)。我將列出他們

1.標準功能宣稱不必要

char *p, *malloc();

可分爲

char *p; 
char *malloc(); 

後者聲明瞭一個名爲malloc函數返回一個char*,有沒有關於所需參數類型的信息。在現代C(C11C99甚至C89),你會做

#include <stdlib.h> 

,並開始使用malloc而不用擔心它的聲明,這將是void* malloc(size_t size);這是從包含的頭。

2.函數聲明和使用的定義是過時的

說你一個函數中添加兩個整數,根據古老的書,你已經,它會聲明爲int add();(或者也許不是聲明它在所有的,因爲默認類型被視爲未申報int時),並把它定義爲

int add(x, y) 
    int x; 
    int y; 
{ 
    return x + y; 
} 

而在現代的C,你會做它聲明爲int add(int, int);並將其定義爲

int add(int x, int y) 
{ 
    return x + y; 
} 

這些都是標準化的並稱爲ANSI CISO CC89(非正式)。 K&R's C book有2個版本,舊版本受到您的書中相同的問題;因此建議使用ANSI C上編寫的第二版。

+0

這真的是一個很好的答案。你和Basile Starynkevitch都非常棒。所以,我必須接受最古老的答案。無論如何,許多thx。 – songhir

+0

沒問題:)) - – legends2k

+0

請注意,第二項是不準確的;它們根本不是函數原型 - 請不要濫用準確的術語「原型」來掩蓋它們。它們是舊式(或非原型)函數定義;並且'malloc()'的聲明是舊式函數聲明。 –