2017-10-14 139 views
3

我對C很新,我很難得到所有這些指針的掛起。換句話說,取消引用操作符和&符號操作符。我相信,在盯着他們一段時間之後,我開始明白他們是如何工作的。例如:函數返回一個指針

int x = 1;   //this creates an integer variable called x and assigns one to it 
    int *pointer;  //this creates a pointer variable that will point to an integer 
    pointer = &x;  //now the variable pointer points to x 
    *pointer = 0  //the value that pointer points to is now zero 

我很確定我明白這是如何工作的。
我正在通過Kernighan和Ritchie的「The C Programming Language」閱讀,但是我對第5.4節(地址算術)中的一些代碼感到困惑。我應該指出,我瞭解地址算術,所以我的問題與此無關。下面的函數中的代碼也不是我的問題。在線搜索有關此代碼的問題會生成大量帖子,人們不知道if/else語句中的代碼如何運行。無論如何,我的問題是關於函數名稱本身。

#define ALLOCSIZE 1000 
    static char allocbuf[ALLOCSIZE]; 
    static char *allocp = allocbuf; 

    char *alloc(int n) /*return pointer to n charachters*/ 
    { 
      if (allocbuf + ALLOCSIZE - allocp >=n) 
      { 
      allocp += n; 
      return allocp - n; 
      } 
      else 
      return 0; 
    } 

同樣,據我所知在函數的代碼,但如何做

*alloc 

工作?我明白這個函數返回一個指針。這是否意味着通過讓函數名稱成爲一個指針,我們將返回一個指向char類型的指針?如果是這樣,它指向什麼?在我之前的例子中,我們有

int x = 1; 
    int *pointer; 
    pointer = &x; 

這裏變量「指針」指向x變量。然而。在函數alloc中不指向任何東西。任何幫助,將不勝感激。

+0

但'char * allocp' **是一個指針,它指向'allocbuf'。 「missing」'&'在這裏解釋[數組名稱是一個指針嗎?](https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer) –

回答

0

char *alloc(int n)意味着alloc是一個返回指向char的指針的函數。在這種情況下,它是一個指向數組的第一個元素的指針,表示由alloc預訂的內存塊。把*放在alloc旁邊可能會有點誤導,可以把它看作char* alloc(int n)

函數名不是一個指針,它返回的是 - 就像你會寫int fun(int x) - 除了這裏的返回值不是int而是char *

+0

Thank you.l Your按照運營商的順序,這樣做確實使它更加清晰。 – EFiore

+0

不客氣,我經歷了同一本書;) – atru

0

這只是說,無論何時調用函數,它都會返回一個指向char的指針。

例如,當這個函數被調用,你可能會看到這樣的事情:

char* x; 
x = alloc(5); 
2

此功能

char *alloc(int n) /*return pointer to n charachters*/ 

將返回一個指向一個字符

它可能會更容易以瞭解它是否是這樣寫的:

char* alloc(int n) //subtle, but this change in format can help 

現在,至於指針實際指向什麼。以前,在這條線上;

#define ALLOCSIZE 1000 
static char allocbuf[ALLOCSIZE]; 

創建了大小爲1000的字符數組。我們有一個包含1,000個字符的數組,名稱'allocbuf'指向數組中的第一個元素。 接下來,在這條線上;

static char *allocp = allocbuf; 

我們爲1,000個char數組(allocbuf)的第一個元素創建一個指針(allocp)。 數組和指針都是全局變量。他們可以在程序中的任何地方訪問。在你發佈的例子中,這些變量將被用在alloc函數中。

在我們繼續之前,定義函數的用途是有意義的。目的是使用先前定義的1000個char數組(它可以幫助您將char看作單個字節)來分配內存。所以這個函數會跟蹤已經使用了什麼內存。並返回一個指向可以使用的大小爲'n'的塊的指針(如果沒有足夠的內存,則返回空值'0')。

不要關心在這個例子中如何釋放內存。我重讀了你從這個例子中拉出來的部分,它後來定義了一個叫做'afree'的方法來釋放這個函數分配的內存。

每次請求存儲器時,該函數都會追蹤'alloc'(指向1000個字符的數組的指針)'n'(請求的大小)所使用的內存。然後,當函數的用戶請求更多的內存時,它會檢查以確保這些行可以滿足請求;

if (allocbuf + ALLOCSIZE – allocp >= n) 
    … 
else{ 
    return 0; 
} 

如果請求的大小不合適,則返回null。該函數利用'allocp'的當前位置來確定以前的調用是否有足夠的內存。 如果要求的尺寸確實合適,則會發生這種情況;

allocp += n; 
return allocp – n; 

這是做什麼是增加'allocp'無論多少內存被請求。該指針用於跟蹤該功能請求了多少內存。由於該功能可以滿足內存請求,因此它現在認爲所請求的內存正在使用中。因此,指針現在指向1000 char數組中未使用的第一個字符。 然後,在增加指針後,該函數返回一個指向內存塊的第一個char的指針,該指針是通過從'allocp'的當前位置減去'n'(所請求的大小)而得到的。

縱觀所有這些,沒有人知道這個內存的價值究竟是什麼。沒有人知道allocbuf [13]或allocbuf [314]包含什麼。這個功能只管理什麼內存是空閒的,什麼是內存,它並不關心實際存儲在內存中的內容。

如果用戶要求的4個字節,像這樣

char* 4bytes = alloc(4) 

存儲32位int在它像這樣;

//don’t ever actually do this!!! 
int* 4bytesInt = (int*)4bytes; 
*4bytesInt = 2,147,483,647; 

那麼allocbuf的前四個元素包含該整數。 如果你釋放內存;

afree(4bytes); 

然後指針仍然工作,並且allocbuf的前4個元素仍然包含該整數。沒有什麼實際改變這些字節的值。 如果再次請求內存,但是

char* 4bytesAgain = alloc(4); 

然後ALLOC將返回相同的4個字節「4bytesAgain」那它返回「4字節」!由於內存被釋放,'alloc'函數可以自由地重用它。所以,如果你現在用這個名字填充這四個字節,

4bytesAgain[0] = ‘C’; 
4bytesAgain[1] = ‘A’; 
4bytesAgain[2] = ‘R’; 
4bytesAgain[3] = ‘L’; 

那麼這將改變原來的'4bytes'和'4bytesInt'指向的值。

+0

謝謝。你的詳細解釋會幫助你很多。 – EFiore

+1

「allocbuf」指向第一個元素「:不是。它命名數組,在許多情況下(但並非所有情況下),數組的名稱將衰減爲指向第一個元素的指針,這是在初始化「static char * allocp = allocbuf;'中發生的情況。另外,「4bytes」和「4bytesAgain」不是有效的標識符。 – aschepler