初始化与C中的赋值

May*_*rma 3 c language-lawyer

我的导师最近告诉C中的数组初始化有两种方式,即:

  1. 手动喜欢 int a[5]={1,2,3,4,5};
  2. 使用scanf()int a[5], i; for(i=0;i<5;i++) scanf("%d", &a[i]);

在我看来,第二种"方式"是一种分配而不是初始化的方式.所以我决定检查这里的人们对此有何看法.我偶然发现了这个帖子,其中一个回答称:

如果您要问的是术语(*从您的问题中并不是很清楚),那么变量的"初始化"实际上是第一次为其赋值.这个术语来自于你给变量它的"初始"值.

这应该(显然)在第一次使用之前发生.

int x=5; 是一个声明和初始化,实际上只是方便的简写

int x; x=5;

如果我要遵循这个特定答案声称的内容,那么第二种"初始化"方式是正确的,因为在scanf()语句之前没有赋值.但是,由于我对静态变量的了解,我脑子里出现了一个新的疑问.请考虑以下代码:

#include <stdio.h>

void first_way(){
    static int x[2]={1,2};
    printf("first_way called %d time(s)\n",++x[0]);
}

void second_way(){
    int i;
    static int x[2];
    for(i=0;i<2;i++)scanf("%d",&x[i]);
    printf("second_way called %d time(s)\n",++x[0]);
}

int main(void){
    int i;
    for(i=0;i<3;i++)
        first_way();
    printf("\n#######\n");
    for(i=0;i<3;i++)
        second_way();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它的输出是这样的:

first_way called 2 time(s)
first_way called 3 time(s)
first_way called 4 time(s)

#######
1 2
second_way called 2 time(s)
1 2
second_way called 2 time(s)
1 2
second_way called 2 time(s)
Run Code Online (Sandbox Code Playgroud)

这个输出再次让我认为scanf()版本更像是赋值版本而不是初始化,即使x[]scanf()语句之前没有赋值给元素.回到原点.

那么,第二个版本是否真的像我的导师声称的初始化或仅仅是一个任务(我相信)?

编辑:

有人指出后,我觉得我的static数组示例很差,因为static无论如何变量都被隐式初始化为0.然后,有人向我指出const变量.

考虑const int x = 2;这里可以初始化x,但是在初始化之后不能为它分配任何值.但这与声称的答案相矛盾(我再次引用它):

int x = 5; 是一个声明和初始化,实际上只是方便的简写 int x; x=5;

那么,在这之后,scanf()版本是否有资格作为初始化程序?

M.M*_*M.M 7

在C标准中,只有选项(1)是初始化.

在编程术语中,两者都可以被认为是初始化.你的问题实际上是在询问单词的含义.

人们使用具有各种常见含义的单词,而不是为特定语言切换术语是正常的.另一个例子是"通过引用传递".C是否通过引用传递?有些人认为它只是通过值传递,其他人则认为通过指针传递实现"按引用传递"的概念.

然后我们可以谈谈深拷贝与浅拷贝(C标准根本没有提到),或术语"堆栈"和"堆"(C标准也没有提到,但C程序员常用) ), 等等.

如果你说{ int b; b = 5; }不是初始化(因为C标准说它不是)那么,为了保持一致,你还应该说这b不是一个堆栈变量.