我想實作一個函式,它以 int 或 char 指標作為輸入,然后將其存盤為 void 指標,但我也想存盤已傳遞的指標的型別,所以有沒有辦法找到型別指標的
uj5u.com熱心網友回復:
我想實作一個以 int 或 char 指標作為輸入的函式
你不能。你可以實作一個接受 void 指標的函式,或者一個接受包含 int 指標和 char 指標成員的聯合的函式,或者一個接受一個 int 指標和一個 char 指標作為單獨引數的函式,或者兩個函式,一個接受一個 int指標,另一個是 char 指標,但您無法實作通過相同引數接受 int 指標或 char 指標選擇的指標。這兩種指標型別不兼容。
如果您選擇 void 指標引數,那么您將從任何物件指標型別(不僅僅是 int 指標和 char 指標)到 void 指標的隱式轉換中受益,但這只會移動您的實際問題的軌跡:
然后將其存盤為空指標,但我也想存盤已傳遞的指標的型別,所以有沒有辦法找到指標的型別
如果將一種型別的指標轉??換為不同的指標型別,則結果不包含有關原始型別的任何資訊。如果您需要此類資訊,則需要單獨傳送和存盤它。使用 void 指標選項,這將意味著傳遞附加資訊的函式的另一個引數。每個可用的選項都需要某種形式的。
uj5u.com熱心網友回復:
如果您使用的是符合 C11 的編譯器,您可以使用 _Generic 宏對型別執行排序多載,但型別必須單獨存盤,無論是void*帶有某種標記的a還是聯合。
最接近你想要的東西是這樣的:
#include <stdio.h>
#include <assert.h>
struct TaggedUnion
{
void* contents;
/* union {int* i;char* c;} contents; */
enum Type {CHAR_TYPE, INT_TYPE} type;
};
struct TaggedUnion storeI(int* x)
{
struct TaggedUnion ret = {.contents =x, .type=INT_TYPE};
return ret;
}
struct TaggedUnion storeC(char* x)
{
struct TaggedUnion ret = {.contents =x, .type=CHAR_TYPE};
return ret;
}
#define storeTagged(x) _Generic((x),\
int*: storeI,\
char*: storeC)(x)
int* getInt(const struct TaggedUnion x)
{
return x.type == INT_TYPE ? x.contents : NULL;
}
char* getChar(const struct TaggedUnion x)
{
return x.type == CHAR_TYPE ? x.contents : NULL;
}
void fi(int* arg)
{
printf("i\n");
}
void fc(char* arg)
{
printf("c\n");
}
#define ff(x) _Generic((x),\
int*: fi,\
char*: fc)(x)
int main(int argc, const char* argv[])
{
printf("entry\n");
int* i;
char* c;
ff(i);
ff(c);
struct TaggedUnion ti = storeTagged(i);
struct TaggedUnion tc = storeTagged(c);
assert(ti.type == INT_TYPE);
assert(tc.type == CHAR_TYPE);
return 0;
}
https://godbolt.org/z/5dcrc84fo
uj5u.com熱心網友回復:
如果您使用的是 C11 編譯器,那么您可以使用_Generic在int*和之間調度型別識別符號char*。
typedef enum {
VT_INT,
VT_CHAR,
} void_type_id;
typedef struct {
void_type_id id;
void *ptr;
} void_typed;
void_typed make_void_typed_impl(void_type_id id, void* ptr) {
return (void_typed) { .id = id, ptr = ptr };
}
// returns type id from the pointer type
#define vt_id(ptr) _Generic((ptr), char*: VT_CHAR, int*: VT_INT)
#define make_void_typed(ptr) \
make_void_typed_impl(vt_id(ptr), ptr)
示例用法:
#include <stdio.h>
int main() {
char *c_ptr = 0;
int *i_ptr = 0;
void_typed vc = make_void_typed(c_ptr);
void_typed vi = make_void_typed(i_ptr);
printf("vc=(%d, %p)\n", (int)vc.id, vc.ptr);
printf("vi=(%d, %p)\n", (int)vi.id, vc.ptr);
}
印刷:
vc=(1, (nil))
vi=(0, (nil))
此解決方案可以輕松擴展以支持其他型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/384366.html
上一篇:未初始化的區域變數使用C
下一篇:指向僅回傳0的結構的指標的元素
