![](/img/trans.png)
[英]dereferencing function pointer to function returning void throws error: void value not ignored as it ought to be
[英]warning: dereferencing ‘void *’ pointer [enabled by default] and error: void value not ignored as it ought to be help c
我對這些錯誤感到困惑。 str1 是一個正在傳遞的字符串,但我在比較時收到警告,在 if 語句中出現錯誤
int stringcmp(void* str1, void* str2) {
int a = strlen(str1);
int b = strlen(str2);
int x;
if ( a < b ) {
x = a;
} else {
x = b;
}
int c = 0;
while ( c < x ) {
if (str1[c] < str2[c]) { //errors happen here
return 0;
}
if (str1[c] > str2[c]) {
return 1;
}
c++;
}
if ( a == x ) {
return 0;
}
return 1;
}
您的函數接收void*
參數,因此在您指出的行中,您正在取消引用指向void
指針,這就是您收到警告的原因。 我不確定為什么您收到的value not ignore as it ought to be
因為這意味着您正在分配一個返回 void 的函數的值,而 strlen 的情況並非如此(這是您正在調用的唯一函數) )。
並且您還應該在向 strlen 傳遞void*
參數時在調用中收到錯誤。
所以你必須將函數的簽名更改為
int stringcmp(const char* str1, const char* str2);
抑制警告並能夠在字符串上調用 strlen 。
void *
引用void *
永遠沒有意義。 在 C 中, void
表示“無類型”/“無”,如果你有void *p;
, *p
應該是什么?
在 C 中, void *
用作通用指針類型,“指向任何東西的指針”。 要使用上面的p
,您必須將其強制轉換為它指向的對象的類型(以其他方式傳遞,編譯器不知道)。 例如:
int i;
void *p = (void *) &i;
...
int j = *(int *)p;
你知道p
指向什么,編譯器不知道。
void *
類型通常用於傳遞不透明數據,或編寫通用函數(如qsort
,它獲取未指定元素的數組和比較它們的函數)。
也就是說,作為(被誤導的)擴展 GCC 允許對void *
進行指針運算,因此p + 1
就像((char *)p + 1)
,它指向下一個char
位置。
您的錯誤源於您試圖在空指針上使用數組符號str1[c]
。 要理解為什么這是錯誤的,我們需要看看 C 中數組符號的實際含義。
讓我們假設我們定義了char* str1
。 這里我們說過str1
是內存中某個有char
地方的地址。 要獲取存儲在str1
所指地址上的數據,我們可以使用*str1
。 這相當於說:“轉到str1
持有的地址,並給我存儲在該地址上的內容”。
當我們使用數組表示法時,我們可以使用str1[0]
,這將是從內存中某個位置獲取的值,該位置存在與str1
定義為相同類型的元素。 這與說*str1
相同(轉到str1
指向的地址並給我存儲在那里的值)。
數組只是存儲在內存中的一系列數據,而字符串只是大小正好為 1 個字節的字符數組,它們立即一個接一個地存儲。 當我們說str1[1]
我們告訴編譯器移動str1
定義為指向的類型的大小,在本例中為 1 字節( char
),然后獲取存儲在該位置的任何內容。 在字符串的情況下,這應該是另一個char
。
現在,當我們將str1
定義為void*
,編譯器如何知道它應該在內存中移動多少才能獲得數組中的下一個元素? 因為 void 沒有大小,所以這是不可能的。
希望您現在了解在這一行中需要更改哪些內容以消除錯誤
int stringcmp(void* str1, void* str2)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.