我对C初始化器有疑问。如果我们使用初始化程序,如:
int a[2] = {1, 3};
在静态存储变量中,我理解(认为)编译器会自动将该数据放入elf文件的.data中。但是当我们在函数内部执行此操作以初始化将在堆栈中的变量时会发生什么?编译器是否生成了#34;填充"那个变量在运行时?如果是这样的话,我们为什么不能这样做:
struct mystruct {
int x;
int y;
};
int main(){
struct mystruct foo;
foo = {1, 2};
return 0;
}
答案 0 :(得分:2)
这只是语法问题。
从C99开始,你可以做到这一点,但你需要一个显式的强制转换,以告诉编译器后面的{...}块是什么:
test("Stackoverflow post: Try and for-comprehensions.") {
val iae = new IllegalArgumentException("IAE")
val rt = new RuntimeException("RT")
import scala.util.{Try, Success, Failure}
def fooA(x1: Int) : String = {
println("fooA")
if (x1 == 1) "x1 is 1" else throw iae
}
def fooB(x2: Int) : String = {
println("fooB")
if (x2 == 1) "x2 is 1" else throw rt
}
def tryFooA(x1: Int) : Try[String] = {
Try {
println("tryFooA")
if (x1 == 1) "x1 is 1" else throw iae
}
}
def tryFooB(x2: Int) : Try[String] = {
Try {
println("tryFooB")
if (x2 == 1) "x2 is 1" else throw rt
}
}
def call( x1: Int, x2: Int ) : Try[String] = {
val res: Try[String] = Try{
val a = fooA(x1)
val b = fooB(x2)
a + " " + b
}
res
}
def tryCall( x1: Int, x2: Int ): Try[String] = {
for {
a <- tryFooA(x1)
b <- tryFooB(x2)
} yield (a + " " + b)
}
assert( call(0,0) === tryCall(0,0))
assert( call(0,1) === tryCall(0,1))
assert( call(1,0) === tryCall(1,0))
assert( call(1,1) === tryCall(1,1))
}
请注意,以上是分配,而不是初始化。所以以下内容也是合法的:
foo = (struct mystruct){1, 2};
答案 1 :(得分:-1)
您需要区分功能不同的代码和语法不同的代码。编译器和语言设计者和编写者首先关注提供静态数据和本地(堆栈)等功能....
次要考虑因素是'语法糖',它是用于执行已经完成的事情的简化语法
在你的例子中
struct mystruct foo;
foo = {1, 2};
与
相同 struct mystruct foo;
foo.x = 1;
foo.y = 2;
你可以说第一个更简单,更清晰,但显然不够普遍。注意一种语言确实改变了语法。 C ++将您的示例更改为
mystruct foo;
foo.x = 1;
foo.y = 2;
因为typedef结构很常见,c ++决定自动生成结构和类类型。
编辑:我注意到有人为你的初始化程序输入了正确的语法。我的观点是,这并不是很简单:语法有点复杂的事实迫使读者管道中出现泡沫。它也不会节省很多打字