【问题标题】:Can the following be made simpler / more efficient?可以使以下内容更简单/更有效吗?
【发布时间】:2010-11-28 17:11:09
【问题描述】:

我正在尝试将一些代码从动态类型语言转换为 C。请 请耐心等待,因为我还没有 C 的实际经验。

我有一个调度程序函数,它决定如何转换它的输入基于 标志参数的值。

void output_dispatcher(char *str, int strlen, int flag) {
    char output[501];
    char *result;

    switch (flag) {
        /* No conversion */
        case 0:
            result = str;
            break;
        case 1:
            result = convert_type1(output, str, strlen);
            len = strlen(result);
            break;
        /* ... */
    }
    /* do something with result */
}

我目前有 5 种不同的输出转换器,它们全部(甚至未来 个)保证只产生 300-500 个字符。根据我的阅读,它 最好使用堆变量而不是动态分配空间 堆栈,如果可能的话。一个的函数声明如下:

static char * convert_type1(char *out, const char *in, int inlen);

我想避免调度程序中的 strlen,因为它是不必要的 重新计算输出大小,因为输出转换器知道 构造输出。另外,因为我传递了一个指向输出的指针 变量,我不应该需要返回结果指针,对吧?所以我修改 它到以下,但得到一个“不兼容的类型”编译错误。

void output_dispatcher(char *str, int strlen, int flag) {
    char output[501];

    switch (flag) {
        /* No conversion */
        case 0:
            output = str;  /* ERROR: incompatible type */
            break;
        case 1:
            strlen = convert_type1(output, str, strlen);
            break;
        /* ... */
    }
    /* do something with result */
}

这种方法可行吗,还是有更好的方法?

【问题讨论】:

    标签: c


    【解决方案1】:

    为避免重新计算,您的输出转换器需要有这样的原型:

    static char * convert_type1(char *out, const char *in, int *len);
    

    这样称呼:

    result = convert_type1(output, str, &strlen);
    

    在内部,输出转换器需要读取现在包含字符串长度的 指针 的内容,并在返回之前覆盖该指针的内容。

    在堆与栈的问题上,确实需要使用堆,因为分配在栈上的变量会在函数结束时消失。

    【讨论】:

      【解决方案2】:

      行:

      output = str;
      

      给你带来了问题,因为虽然数组和指针很相似,但它们并不相同。

      “输出”是一个数组,而不是一个指针。

      str = output;
      

      会起作用,因为 char ptr 很像数组变量。

      但恰恰相反,因为“输出”变量不仅仅是指向数组的指针,而是数组本身。

      例如,如果您有:

      char output[501];
      char output1[501];
      

      你做到了:

      output1 = output;
      

      这样没问题,C 会将输出数组的内容复制到 output1 数组中。

      所以,您只是对数组和 ptrs 有点困惑。

      【讨论】:

      • 第二个例子 (output1 = output;) 不起作用,因为 C 对不允许这种直接赋值的数组有特殊情况规则。不过memcpy(&output1, &output, sizeof output) 有效。
      【解决方案3】:

      字符输出[501]; 输出 = str; /* 错误:不兼容的类型 */

      =>

      strncpy(输出, str, sizeof(输出));

      注意,你应该检查'output'是否足够大以容纳'str'

      【讨论】:

        【解决方案4】:

        这种情况下的错误是有道理的。 output 是一个缓冲区,将保存 char 数据,而 str 是指向内存中其他区域的指针。您不想分配 str 指向输出的地址,对吗?如果您想采用这种方法,我认为只需将 str 指向的数据复制到输出中即可。如果不需要转换,最好只使用 str 。

        【讨论】:

          【解决方案5】:

          C 不允许通过直接赋值来修改数组 - 您必须单独修改数组成员。因此,如果要将str指向的字符串复制到数组output中,则必须使用:

          strcpy(output, str);
          

          或许

          memcpy(output, str, strlen + 1);
          

          (在这两种情况下,首先检查strlen < sizeof output之后)。

          请注意,将局部变量命名为 strlen,从而掩盖该名称的标准函数,这对于稍后查看您的代码的人来说会有点混乱。我会选择另一个名字。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多