【问题标题】:Return "data type" in C在 C 中返回“数据类型”
【发布时间】:2020-06-16 03:02:26
【问题描述】:

我想要一个简单的

something Data() {
    return int;
}

或使用 char, long ... w/e

我该怎么办?

我不想返回数字,或者字符串,我想返回数据类型

我尝试过的另一个选项是使用宏

#define Data int

并使用不同的 if 和 else,我可以改用它,但我不能在宏中使用指针,所以这也是一个问题(我需要根据保存在指针中的数字返回数据类型) .

这是我遇到的确切问题,以及到目前为止我所做的:

//Read/write any type from memory
#define MemRead(type, offset) (*((type*)(memory + (offset))))
#define MemSet(type, offset, value) (*((type*)(memory + (offset))) = (value))

//Get the index for type (0 - char, 1 - short, 2 - int ...)
#define TypeIndex (MemRead(unsigned short, 0) % 4)
//#if TypeIndex == 0
//#define TYPE char
//#elif TypeIndex == 1
//#define TYPE short
//#endif

//#define TYPE SOMETHING HERE maybe an if-else ...
//#if TypeIndex == 0 doesn't work, because I can't use * in macros

char *memory = NULL;

void memory_init() {

    memory = (char*)ptr;

    //Create a list of pointers
    int numOfPointers = 1, tsize = size - 3 * IntSize - START;
    while (tsize > 64) {
        tsize /= 4;
        MemSet(int, numOfPointers++ * IntSize - 3, 0);
    }

    int typeIndex = 0;
    if (size < power(2, (sizeof(short) * 8) - 1)) {
        typeIndex = 1;
    }
    else if (size < power(2, (sizeof(int) * 8) - 1)) {
        typeIndex = 2;
    }
    else {
        typeIndex = 3;
    }

    MemSet(unsigned char, 0, numOfPointers * 4 + typeIndex);
    MemSet(int, HEADER - IntSize, 0);

    int memAvailable = size - HEADER - 3 * IntSize;
    setBoundaries(HEADER + IntSize, memAvailable, memAvailable);
    MemSet(int, size - IntSize, 0);

    //Set beginning pointer
    MemSet(int, HEADER - IntSize, HEADER + IntSize);

    //Set pointers inside the free block
    MemSet(int, HEADER + IntSize, NULL);
    MemSet(int, HEADER + 2 * IntSize, HEADER - IntSize);
}


int main() {

    char region[500];
    memory_init(region, 500);
}

我得到一些内存空间,将第一个 char 设置为一个索引,显示我将使用的数据类型以及列表上有多少指针(每个列表包含不同大小的空闲块),但我无法获得从 TYPE 中获取类型。

我可以在每个函数中使用一个开关来根据内存中的第一个索引处理不同的数据类型,但这很丑陋,也是我寻找更好解决方案的原因。

【问题讨论】:

  • 你不能。你为什么要这样做?
  • @SMAEL 函数要么返回对象,要么返回类型为 void。
  • 这是XY problem。您需要解决的实际问题是什么?为什么你认为你需要能够返回一个类型?也请花一些时间阅读How to Ask,以及this question checklist
  • Re“我不想返回数字,也不想返回字符串,我想返回数据类型”,没有这回事。 “数据类型”不是值的类型,所以不能将函数声明为返回“数据类型”类型的值,也不能返回“数据类型”类型的值。
  • 无论您认为通过“动态调整大小”整数获得的任何压缩都可能会被您用来跟踪其大小的额外字节所抵消。只需将大小存储为size_t(无符号整数或长整数)即可。否则,这是一个非常复杂的微优化才能正常工作。

标签: c types return


【解决方案1】:

如果没有选择 switch 或等效构造,您将无法做您想做的事情。在 C 中,数据类型不能像 Java 中的示例那样传递。没有反射。 C++ 有 RTTI 可能会有所帮助,或者模板,但使用它们将在幕后生成所有需要的机器代码。你清楚地要求一个 C 解决方案。与其后继者相比,C 是一种低级语言。

您最好的选择是接收所有必要参数并设置适当内存量的函数。

我敢肯定,在底层,那些支持您想要的语言的语言也会分派到不同的代码。你只是不需要写所有的行。

您还可以在第一个字节中编码内存的大小。但请注意,对以下字节的访问不会对齐。有些架构不允许这样做,您会遇到运行时错误。

使用联合怎么样?编译器将确保您的数据类型正确对齐。

typedef enum {
    T_CHAR, T_SHORT, T_INT,
} TYPE;

typedef struct {
    TYPE t;
    union {
        char c;
        short s;
        int i;
    }
} ENTRY;

void memory_init(ENTRY* memory) {
    // prepare as you like
    switch (memory.t) {
    case T_CHAR:
        memory.c = value;
        break;
    case T_SHORT:
        memory.s = value;
        break;
    case T_INT:
        memory.i = value;
        break;
    default:
        // error handling...
        break;
    }
}

【讨论】:

  • TBH,我看不出这基本上不是每个功能中都有开关的解决方案(我试图避免(这是可能的,但不是很好))。添加了更多代码来显示,我只使用 MemSet 和 MemRead,所以它会为每种数据类型复制整个代码几次
  • 在低级别上,你说得对,它的工作方式类似。但是正如其他人和我已经说过的那样,如果您尝试按照您向我们展示的方式管理内存,那么您会因为 UB 而导致灾难。 -- 我的回答包括一些提示和类型安全的建议,这就是区别。
  • 感谢您的帮助,我将研究内存对齐问题,并与我的讲师进行质询。所以,没有真正的方法可以做到我的好(但对齐方式错误),对吧? (添加如果我也尝试开始工作)
  • 好吧,即使你让它与你当前的编译器和目标集一起工作,让我们假设你找到了一个符合标准的方法,它仍然是hackish并且难以掌握。如果他/她努力达到精通,那么年轻的学徒不应该学习做什么。 ;-) 源代码主要由人类阅读,这些应该理解您的意图。相信编译器会尽最大努力将其转换为最佳机器代码。
  • 感谢您的帮助,我可能会在一两年后了解您想说的话,但不是现在,这是肯定的。我想我现在不会得到几个奖励积分(或者做我丑陋的开关无处不在的解决方案)。再次感谢您参与尝试帮助我找到我不知道我需要的解决方案,但应该会更好。
【解决方案2】:

因此,与其尝试获取类型的宏,我可以使用函数将所需的数字写入标志设置为的任何类型:

void MemRead(int offset) {
    switch(flag something something) {
        case 1 //for char
        case 2 //for short etc etc
    }
}

就这么简单

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2017-02-28
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多