首页 > 代码库 > Do you really know what means initialization? “初始化 定义 赋值” 之间的联系与区别

Do you really know what means initialization? “初始化 定义 赋值” 之间的联系与区别


“初始化 定义 赋值” 之间的联系与区别

 

           本来很早之前就想写个blog,说说这三个家伙的区别和联系,三者之间各种联系,很难比较清楚的讲明白,感觉当时好像分析思路还不够“完整”。今天遇到别人抛出来的一个问题。根本的问题是和初始化和赋值有关系,于是留下这个blog。


#include <stdio.h>

struct _ANIBMP
{

        int FirstNumber;
        int Count;

}ANIBMP;

ANIBMP Swallow = {4,5};
ANIBMP Dove = {4,3};
ANIBMP Peacock = { 14, 5};
ANIBMP Eagle = { 19, 5};
ANIBMP Rabbit = { 24, 5};
ANIBMP Monkey = { 29, 5};
ANIBMP Panda = { 34, 5};
ANIBMP Lion = { 39, 5};
ANIBMP GoldShark = { 44, 4};
ANIBMP SilverShark = { 48, 4};


ANIBMP ShowAnimal = Swallow;

int main(void)
{

        printf("%d   %d\n", Swallow.FirstNumber, Swallow.Count);
        printf("%d   %d\n", ShowAnimal.FirstNumber, ShowAnimal.Count);

        return 0;
}

他发给我的代码如上.

gcc 给出的报错是这样的:

ubuntu2@ubuntu:~/Desktop$ cc ./test.c
./test.c:24:1: error: initializer element is not constant


嗯。说是初始化的元素不是个常数。

先别急,一开始我也晕了,我记得结构体是可以直接赋值的。我自己测试了一下别的代码。没错。于是我把代码稍微调整一下,把Showanimal = Swallow放在main里面了。


如下:

#include <stdio.h>

typedef struct _ANIBMP
{

        int FirstNumber;
        int Count;

}ANIBMP;


ANIBMP Swallow = {4,5};
ANIBMP Dove = {4,3};
ANIBMP Peacock = { 14, 5};
ANIBMP Eagle = { 19, 5};
ANIBMP Rabbit = { 24, 5};
ANIBMP Monkey = { 29, 5};
ANIBMP Panda = { 34, 5};
ANIBMP Lion = { 39, 5};
ANIBMP GoldShark = { 44, 4};
ANIBMP SilverShark = { 48, 4};

//ANIBMP ShowAnimal = Swallow;

int main(void)
{

        ANIBMP ShowAnimal = Swallow;

        printf("%d   %d\n", Swallow.FirstNumber, Swallow.Count);
        printf("%d   %d\n", ShowAnimal.FirstNumber, ShowAnimal.Count);

        return 0;
}

风平浪静 。。。。0 错误 0 警告



问题出来了,为什么?!


问题的根本在于初始化的概念和赋值是有不同的。


下面是wiki的解释

C family of languages

Initializer

        In C/C99/C++, an initializer is an optional part of a declarator.  It consists of the ‘=‘ character followed by an expression or a comma-separated list of expressions placed in curly brackets (braces). The latter list is sometimes called the "initializer list"  or  "initialization list",although the term "initializer list" is formally reserved for initialization of class/struct members in C++, see below. A declaration which includes initialization is commonly called definition.

        Many find it convenient to draw a distinction between the terms "declaration" and"definition", as in the commonly seen phrase "the distinction between a declaration and definition...", implying that a declaration merely designates a data object (or function). In fact, according to the C++ standard a definition is a declaration.Still, the usage "declarations and definitions", although formally incorrect, is common 



我来说一下吧,当然带上测试代码,不然没代码没真相


初始化是要分变量作用域的。

全局变量的初始化,必须是 变量 = const 常量;

局部变量的初始化则没有要求右值必须是常量,常量变量都行。


#include <stdio.h>

int a = 1;

int b = a;

int main(void)
{
        int c = 10;

        int d = c;

        return 0;
} 


ubuntu2@ubuntu:~/Desktop$ cc ./test.c
./test.c:5:1: error: initializer element is not constant

可以看懂啊只有第5行有报错。其他的木有

全局变量的初始化,必须是 变量 = const 常量;

局部变量的初始化则没有要求右值必须是常量,常量变量都行。


赋值嘛,还是很简单的,= 有这个东东的就是赋值。它叫做assignment operator


最后,讲讲定义

#include <stdio.h>

int a = 1;

int b = 2;

a = 10;

b = a;

int main(void)
{
        int c = 5;

        int d = 6;

        d = c;

        d = 100;

        return 0;
}

ubuntu2@ubuntu:~/Desktop$ cc ./test.c
./test.c:7:1: warning: data definition has no type or storage class [enabled by default]
./test.c:7:1: error: redefinition of ‘a’
./test.c:3:5: note: previous definition of ‘a’ was here
./test.c:9:1: warning: data definition has no type or storage class [enabled by default]
./test.c:9:1: error: redefinition of ‘b’
./test.c:5:5: note: previous definition of ‘b’ was here
./test.c:9:1: error: initializer element is not constant


第7行和第9行发生了重定义。


全局变量是不允许发生第二次赋值操作的,只允许在定义的之后赋值,即初始化。

局部变量定义一次,之后可以随意赋值 ,局部变量的第一次赋值,也可以叫做局部变量的初始化


对于初始化,是有限定的,要说明变量的作用域,局部变量还是全局变量。




最后对于那个同学遇到的结构体“不能赋值"的问题,其实就已经解决了。把结构体赋值给另外同类型的结构体的操作仅限于局部变量,这是赋值,而全局变量的初始化必须是const常量。