【问题标题】:Ternary operation with a string output in CC中输出字符串的三元运算
【发布时间】:2012-10-02 16:16:25
【问题描述】:

谁能解释一下为什么这个简单的三元运算在 C 语言中甚至无法编译?

void main(int argc, char *argv[]){
    int a = atoi(argv[1]);
    char foo[] = (a == 1) ? "bar1" : "bar2";
}

这似乎是特别是字符串的问题。

【问题讨论】:

  • 等一下,用 C 语言?如果你在 C 中工作,为什么你的主要回报是无效的?它应该是一个 int。
  • 允许但不推荐返回 void。有一个空主..
  • 微软的编译器会很乐意接受它,其他人不会,但这不可能是微软第一次做他们曾经做过的事情。请参阅 stackoverflow.com/questions/4207134/… 以获得关于此的非常好的讨论。

标签: c ternary-operator string-literals


【解决方案1】:

字符串文字"bar"在表达式中使用时(在这种情况下,在三元运算符内部)是指向预分配内存的指针。您不能使用指向数据的指针来初始化数组,只能使用文字("..."{...})。

相反,您可以将其分配给char *

const char *foo = (a == 1) ? "bar1" : "bar2";

不会复制文字而是指向它,所以你不应该修改foo 的元素。如果需要副本,可以使用memcpy,前提是你知道声明数组有多大:

char foo[5];
memcpy(foo, (a == 1) ? "bar1" : "bar2", sizeof foo);

如果您特别希望能够分配内容,那么有一个技巧可以做到这一点;无论struct 包含什么内容,都可以使用赋值隐式复制 struct 的内容(以及从函数中返回,等等),您可以将struct 中的字符数组:

typedef struct { 
  char contents[5];
} mystring;

mystring foo = (a == 1) ? (mystring){"bar1"} : (mystring){"bar2"};
// You can also use assignments.
foo = (mystring){"baz"};

就像第二个选项一样,当您这样做时,您必须在struct 声明中为数组选择一个固定大小。如果你有无限长度的字符串,那么你必须使用指针。

【讨论】:

  • 哦,我今天学到了一些东西!我不知道它在预先分配的内存中!
  • 您可以直接使用"bar1""bar2" 初始化char foo[]。但是你不能通过表达式来做到这一点。标准说:“一个字符类型的数组可以由一个字符串字面量初始化,可选地用大括号括起来。” ?: 表达式不是字符串文字,尽管在大多数其他上下文中 "bar1"1?"bar1":"bar2" 的类型和值将完全相同。
【解决方案2】:

您的三元运算很好,但您无法使用“bar1”和“bar2”所在的预分配内存来初始化数组。

int a = atoi(argv[1]);
char foo[5];
memcpy(foo,((a == 1) ? "bar1" : "bar2"), 5); 

这可能是一种继续做你正在做的事情的方法。

【讨论】:

  • 为什么不strcpy
猜你喜欢
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2012-05-24
  • 2011-12-18
  • 2011-02-15
  • 2021-10-25
相关资源
最近更新 更多