簡體   English   中英

澄清C中的char指針

[英]Clarification of char pointers in C

我正在研究K&R第二版,第5章。

在頁87,引入字符數組的指針如下:

char *pmessage;
pmessage = "Now is the time";

如何知道pmessage是指向字符數組的指針,而不是指向單個字符的指針?

要擴展,請在第94頁上定義以下函數:

/* month_name: return the name of the n-th month */
char *month_name(int n)
{
    static char *name[] = {
        "Illegal month",
        "January", "February", "March",
        ...
    };

    return (n < 1 || n > 12) ? name[0] : name[n];
}

如果只提供了上面的函數聲明,那么如何知道是返回單個字符還是字符數組?

如果假設從month_name()返回是一個字符數組並迭代它直到遇到NULL ,但返回實際上是單個字符,那么是否有可能出現分段錯誤?

有人可以演示一個指向單個字符與字符數組的指針的聲明和賦值,它們對函數的使用以及已經返回的標識?

所以你擁有的是一個字符串文字,它是一個具有靜態存儲持續時間的char數組:

"Now is the time"

在大多數情況下,數組會衰減成指向第一個元素的指針,這是在這里發生的事情:

pmessage = "Now is the time";

您需要以這樣一種方式設計和記錄您的界面,使您知道輸入和輸出的期望。 沒有運行時信息來說明所指出的內容的性質。

例如,如果我們查看strtok手冊頁,它會告訴我們:

每次調用strtok()都會返回一個指向包含下一個標記的以null結尾的字符串的指針。

因此程序員確切地知道預期的結果並相應地處理結果。

如果你有一個指向單個字符的指針而不是像C樣式字符串,那么你將有未定義的行為,因為你將訪問超出范圍的內存。 分段錯誤是一種可能,但未定義僅意味着結果是不可預測的。

是什么

char *pmessage;
pmessage = "Now is the time";  

意思?
char *pmessage; 表示您將pmessage聲明為char的指針
pmessage = "Now is the time"; 意味着pmessage現在指向字符串文字的第一個字符 Now is the time

從函數返回pmessage時,將返回指向字符串文字的指針。
如果您將使用%c說明符打印pmessage ,那么它將打印N ,如果您將使用%s打印它,那么它將打印整個字符串文字。

printf("%c\n", *N);     // 'N' will be printed
printf("%s\n", N);      //  "Now is the time" will be printed 

看起來很奇怪,C信任程序員的智慧。 如果我看到如下功能:

/* month_name: return the name of the n-th month */
char *month_name(int n)
{
    static char *name[] = {
        "Illegal month",
        "January", "February", "March",
        ...
    };

    return (n < 1 || n > 12) ? name[0] : name[n];
}

我查看文檔並讀取它返回一個NUL終止的字符串,該字符串是指向靜態分配的內存的指針。 這足以讓我按照自己的意願對待回報值。

如果函數的創建者將未來版本中的返回值更改為不同類型的字符串,則他們最好大聲喊出它,更改函數名稱,或者使其非常清楚,否則它們的行為非常糟糕。

另一方面,如果我沒有正確處理返回值,即使它被正確記錄,那么我也不會那么聰明,也許可能會成為一名Java開發人員。

最后,如果沒有記錄該功能,找到它的主人並燒毀他的房子。 1

1 如果它在庫中,則會被釋放 一旦他們開始編寫圖書館,就不要燒人的房子! ^ _ ^

如何知道pmessage是指向字符數組的指針,而不是指向單個字符的指針?

你沒有。 至少,沒有辦法從指針值本身告訴它是指向單個char還是char數組的第一個元素。 它可以任何一種方式使用。

您必須依賴上下文或明確指定如何使用指針。 例如, scanf使用不同的轉換說明符來確定指針是否指向單個char

char single_char;
scanf( " %c", &single_char );

char數組:

char array_of_char[N];
scanf( "%s", &array_of_char[0] );

請記住,當它不是sizeof或一元&運算符的操作數或用於在聲明中初始化另一個數組的字符串文字時,將轉換“N元素數組T ”的表達式(“衰減”)表達式為“指向T指針”,表達式的值將是數組第一個元素的地址,因此最后一行也可以寫入

scanf( "%s", array_of_char );

由於該轉換規則,無論何時將數組表達式傳遞給函數,函數實際接收的是指針值。 實際上,函數聲明

void foo( char str[N] );

void foo( char str[] );

相當於

void foo( char *str );

這三個都將str視為指向char的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM