2017-02-11 27 views
3

我有這樣的代碼,所述函數strtol接收雙指針,並假設字符串「prueba」是指向字符串的第一個元素的存儲器地址(這是相同的存儲器地址的指針整個鏈條),那麼這是因爲如果它被傳遞指針的目錄,我不知道如果我解釋了,反正這是行不通的:/在這裏發出警告爲什麼我不能傳遞鏈的地址? strtol將

ret = strtol(str, &prueba, 10); 

長整型與strtol (const char * str,char ** endptr,int base)

strtol將str中字符串的起始部分轉換爲long int va按照給定的基數進行。 「endptr」他是參考類型char *的一個目的,其值由該函數的數值後設置爲下一個字符在str中。

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

int main() 
{ 
    char str[30] = "2030300 This is test"; 
    char prueba[20]; 
    char *ptr; 
    long ret; 
    printf("\nLa cadena inicial es: %c%s%c\n",34,str,34); 


    ret = strtol(str, &ptr, 10); 
    printf("\nThe number(unsigned long integer) is %ld\n", ret); 
    printf("String part is |%s|\n", ptr); 

    ret = strtol(str, &prueba, 10); 
    printf("\nProbando: %c%s%c\n",34,prueba,34); 

    return(0); 
+0

'&prueba'是指向的20'char's陣列。 –

+0

'&prueba'不是'char **'。它是一個char(*)[20]'。也就是說,它是一個指向數組的指針。你需要聲明爲:'char * prueba;' – kaylum

+0

但如果我聲明char * prueba它是一個指向數組的指針。像char prueba [20] – EmiliOrtega

回答

3

我在這裏看到一個很大的誤解,認爲需要加以解決:指針是不一樣的陣列。指針是告訴你如何找到別的東西的東西;別的東西可能是單一的東西,或者是足夠未初始化的空間來容納一個東西,或者是一堆東西。一個數組是一塊東西,而且非常特別的是而不是指向一塊東西的指針。你可以在每個事件之後放置[0],並且結束一件事情與本次討論無關。

爲什麼它衰變簡化版,爲char *表示其第一個元素的地址,像它會如果傳遞給函數,甚至分配?因爲C標準認爲它不會 - 它定義了「數組衰減成指向其第一個元素」規則的三個例外。其中之一是當數組是&操作者的操作,讓你獲得一個指向你問的事,而不是其他哪個,雖然相關的,是不是那個東西。

正因爲如此,你不能傳遞一個char **strtol。你傳遞一個指向數組的指針。雖然在某些情況下這可能是確定的,但它不在這裏,因爲函數想要放一個char *,讓它放置一個;如果你試圖說「把它放在這char[]」,它不會做你想做的。它會嘗試將char *填入您的char[],並且您會收到未定義的行爲。

有關進一步閱讀,請參閱comp.lang.c常見問題問題6.26.3


哦,順便說一下,GCC會發出警告,如果你告訴它:通過-Wincompatible-pointer-types或者更好的是,像-Wall -Werror(取決於你的編譯器的建議),編譯器 - 它會產生這樣的警告:

/path/to/main.c: In function 'main': 
/path/to/main.c:17:23: warning: passing argument 2 of 'strtol' from incompatible pointer type [-Wincompatible-pointer-types] 
    ret = strtol(str, &prueba, 10); 
        ^
In file included from /usr/include/stdio.h:29:0, 
       from /path/to/main.c:1: 
/usr/include/stdlib.h:166:6: note: expected 'char ** restrict' but argument is of type 'char (*)[20]' 
long _EXFUN(strtol,(const char *__restrict __n, char **__restrict __end_PTR, int __base)); 

當然,確切的文本可能會有所不同,但它的要點將是相同的。

+0

當你「問」它:你不能應用索引運算符(RESP,+或 - )到一個數組。它只是**看起來像as-if(聽起來像挑剔,但一旦你理解了這一點,你就可以理解C中的數組)。它不起作用的原因(除了類型的問題)僅僅是因爲你不能改變數組本身的值(數組本身沒有值,就像指針一樣,它只是元素)。最後:C信息頁列出推薦的警告。這些包括'-Wall -Wtratra-Wconversion'。就個人而言,我會推薦更多。 – Olaf

+0

'長_EXFUN(......'??呵呵,從來沒有見過這樣的信息 – Olaf

+0

@Olaf是啊,我有點不那麼嚴格正確(也就是說我是從一個語法POV說的 - 'int a [2]; a [0];'是有效的語法,就像'int * a; a [0];'。我認爲相似性是造成混淆的原因,但是我會做出明確的說明WRT爲什麼它不起作用 - 哎呀,是的,我應該明確地說明這一點,這就是我將它放在這個'char []'中「的原因,但它並沒有真正實現...... WRT'long _EXFUN' - - 這就是我編譯代碼時我的編譯器輸出的內容,我不知道它來自哪裏。 –

相關問題