【问题标题】:How define array to fit negative indexes?如何定义数组以适应负索引?
【发布时间】:2015-05-01 02:46:56
【问题描述】:

我正在尝试编写函数,当我在其参数中传递错误时将返回正确的字符串。但是我不清楚如何为字符串分配负索引(对应于枚举FILE_ERRORS_t),你能澄清一下吗?

typedef enum {
    FOPEN_ERROR=-1,
    FREAD_ERROR=-2,
    FWRITE_ERROR=-3,
    FSEEK_ERROR=-4,
    FCLOSE_ERROR=-5
    } FILE_ERRORS_t;
#define printErr (const char*[5]){"Cannot open file", "Cannot read file", "Cannot write file", "fseek fail", "fclose fail" }

【问题讨论】:

  • 反转enum。现在使用索引[ERROR+5]

标签: c string c-preprocessor


【解决方案1】:

你不能创建一个带有负索引的数组,但你可以创建一个指向数组中间的指针,这样当你将它与一个负索引组合时,你会得到一个“常规”C数组的有效元素。方法如下:

static char * real_errors[] = {
    "fclose fail"       // -5
,   "fseek fail"        // -4
,   "Cannot write file" // -3
,   "Cannot read file"  // -2
,   "Cannot open file"  // -1
};
static char **errors = &real_errors[5]; // Point one element past the end

现在你可以这样写了:

printf("%s\n", errors[FCLOSE_ERROR]);

它会起作用,因为它相当于

printf("%s\n", real_errors[5+FCLOSE_ERROR]);

Demo.

注意:这只有在错误指向数组内部或超出数组末尾时才被明确定义。否则,这将是未定义的行为。

【讨论】:

  • 是的,请继续教导人们混淆他们的来源... |-S
  • @alk 一旦他们知道诀窍,它就不再被视为混淆。这对于理解指针和数组的关系非常有用,即使它们在现实生活中从未使用过。
  • 可以用于教育目的...... - 很公平;-)
  • 可能值得指出的是,从技术上讲,这只有在 errors 指向数组内部或指向数组末尾时才明确定义。如果错误代码是 -6 到 -2,则类似的解决方案在技术上将是未定义的行为!
【解决方案2】:

尝试按照here 所述取绝对值,然后减一。然后 -1 将变为 0,-2 将变为 1,依此类推。这应该按照您的意愿进行映射。所以这个函数可能看起来像这样:

int errorCodeToIndex(FILE_ERRORS_t errorCode) {
    return abs(errorCode) - 1

您可能需要将errorCode 转换为int 并记住#include <stdlib.h>

【讨论】:

    【解决方案3】:

    您可以使用负索引来反转字符串的顺序:

    #include <stdio.h>
    
    typedef enum {
        FOPEN_ERROR=-1,
        FREAD_ERROR=-2,
        FWRITE_ERROR=-3,
        FSEEK_ERROR=-4,
        FCLOSE_ERROR=-5
        } FILE_ERRORS_t;
    
    #define sup ((const char *[]){"fclose fail", "fseek fail", "Cannot write file" ,"Cannot read file", "Cannot open file", ""} + 5)
    
    int main(void)
    {
        puts(sup[FSEEK_ERROR]);
        return 0;
    }
    

    输出:

    fseek fail
    

    【讨论】:

    • 更令人困惑,但是我喜欢复合语句......! ;-) 1+
    【解决方案4】:

    只需使用类似函数的宏和指定的初始化器

    #define printErr(E) (const char*const[]){[-FOPEN_ERROR] = "Cannot open file", ... }[-E]
    

    这使数组尽可能大,并确保每个字符串都放置在其中的正确位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 2018-04-27
      • 2019-06-02
      相关资源
      最近更新 更多