2010-04-09 61 views

回答

20

一般來說,你不能。在某些情況下,如果有關於p點的保證,您可以查看該地址處及其後的內容以查找。通常,你的函數應該知道它傳遞的是什麼,除非它只是傳遞它。

C中的數據和函數參數只是一堆集中在一起的數據。除非您使用其中一些位來告訴您這些位是什麼,否則沒有一致的方式來識別它。

+6

表決這個......你知道,因爲你已經確定了你的程序其餘部分的類型。如果這聽起來很脆弱,那是因爲它很脆弱。歡迎來到C.儘可能使用不易碎的系統。 – 2010-04-09 03:03:35

+0

我記得一些Motif(所有東西)的代碼,在那裏你會得到一個指針,你會看指針後的第一個字節來確定類型是什麼,然後你恰當地處理這種類型。真是一團糟。 – WhirlWind 2010-04-09 03:05:25

+0

我不會在實踐中這樣做。我只是好奇這可以做到的方式。另外,一個GNU C擴展提供了typeof()運算符,我認爲這個運算符能夠確定解除引用的類型(即typeof(* p)),但我還沒有使用它。 – Yktula 2010-04-09 03:09:56

5

簡答 - 你不能。

在C語言中沒有運行時間信息除非你提供給它,但看printf(3)家庭,看看它是多麼容易搬起石頭砸自己不匹配的格式規範,實際的參數類型的腳。

類型系統是你的朋友。用它。

5

當然可以,而且也很簡單。這是C,做你想做的,你想要的。

製作一個類型系統。把你傳入的所有東西都放到一個結構體中,使第一或第二個字符成爲一個幻數,以確定除了幻數之外的結構。

做一些函數來創建/獲取/設置/銷燬「類型變量」。

使一些其他功能在運行時添加和註冊新類型。

創建一些定義,以便更容易閱讀和類型化結構。

你知道它之前,你將有你可以使用你的項目的一個很好的專有類型的系統,它會一直做的正是你想要的和需要的,因爲你做到了。

你可能會發瘋,並將其發展成像系統一樣的完整對象。或者保存自己的工作,並使用所有其他已經發瘋的人的工作 - http://en.wikipedia.org/wiki/GObject

+0

那麼,當你編寫的函數被你不控制的代碼調用時,它是如何工作的? – WhirlWind 2010-04-09 03:53:20

+2

如果函數是由您不控制的代碼調用的,那麼您正在創建API /庫,因此您必須記錄接口以及創建/獲取/設置/銷燬類型化變量的函數。 如果由於某種原因被調用者是受控制的人,並且他們不希望/拒絕使用自定義的「輸入」系統,那麼你的運氣不好。你必須讓他們決定他們將如何傳遞你輸入的信息,然後編碼。 – Antebellum 2011-06-29 03:05:31

1

我遇到了類似的問題,我發現自己不得不爲編程語言項目編寫指令集。我想到了這個問題,因爲我有一個指向函數的指針數組,以便可以枚舉函數並在for循環中運行(例如,聯機幫助和語法等)。例如:

struct List_Str *(*InstructionSet[])(struct List_Str *ContextPrefix,struct List_Str *ContextSuffix)= 
{ 

    AAVF,Add,AddEmotions,AddEmoDebug,AddScope,... 

}; 

現在你可以很容易地做同樣的事情用的char *而不是結構List_Str *類型,然後使用snprintf的和的atoi和ATOF等轉換函數的所有數據轉換成字符串格式。如果你做一個:

man isalpha 

這說明你很多的ctype.h中的功能,可以讓你的想法如何確定哪些類型的數據字符串內舉行。

將所有類型摺疊爲「連續」格式允許極大的靈活性和規律性,但自動將數據從字符串轉換爲整數,浮點等等,這是艱難的,但是一旦例程被librified,就會產生效果。

如果你打算保存二進制數據,那麼你不能使用字符串,因爲0字符可以在二進制數據中,這會混淆strlen函數。此外,一旦它離開作用域,你不知道malloc'd的長度,因此在char *的前幾個字節中推薦數據之前存儲解除引用的數據的長度。

最後一件事,我不建議將數據存儲在void *中,它太含糊。我建議使用char *,因爲它更具體一些,可以包含void *所能包含的所有內容,並且如果任何內容看起來很腥,編譯器會事先告訴您。

+2

如果您使用'char *'作爲通用數據指針,那麼在沒有先轉換爲正確類型的情況下,意外取消引用指針就太容易了。 – 2013-05-23 00:10:26