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 给出的报错是这样的:

[email protected]:~/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;
} 

[email protected]:~/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;
}

[email protected]:~/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常量。

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

时间: 2024-08-01 00:05:30

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

C语言指针的初始化和赋值

1.指针的初始化 指针初始化时,"="的右操作数必须为内存中数据的地址,不能够是变量,也不能够直接用整型地址值(可是int*p=0;除外,该语句表示指针为空).此时,*p仅仅是表示定义的是个指针变量,并没有间接取值的意思. 比如: int a = 25; int *ptr = &a; int b[10]; int *point = b; int *p = &b[0]; 假设:int  *p; *p = 7; 则编译器(vs2008)会提示The variable 'p'

c++类中对数据成员进行初始化和赋值的区别

在c++中定义一个类 ,对于构造函数 我们经常是这么写的: class test { public: test(int n_x , int n_y) { x = n_x; y = n_y; } private: int x , y; }; 这中写法虽然是合法的但比较草率 在构造函数 test(int n_x , int n_y)中 , 我们这样实际上不是对数据成员进行初始化 , 而是进行赋值. 正确的是初始化应该是这样的: class test { public: test() {} test(

GO学习笔记 - 变量在定义时没有明确的初始化时会赋值为“零值 ”。

官方教程:https://tour.go-zh.org/basics/12 变量在定义时没有明确的初始化时会赋值为 零值 . 零值是: 数值类型为 0 , 布尔类型为 false , 字符串为 "" (空字符串). 官方示例: package main import "fmt" func main() { //下面声明的变量没有被初始化,但是也具有值,就是默认的零值 var i int var f float64 var b bool var s string fm

动态申请 二维数组 以及初始化、 赋值

二维堆数组 可以利用指针的指针 例如 int ** array = new int[i][j]; 但是这样不能通过编译,因为堆数组不像基于栈数组那样工作,为其分配的内存是不连续的,因此堆数组分配足够的内存是不对的,应当先分配基于堆数组第一维数组下标分配一个连续的数组.该数组的每一个元素实际上是指向一个数组的指针. 一个测试小例: #include <iostream> #include <stdio.h> #include <cstring> using namespa

c++总结之类型,对象的定义和声明,对象的初始化和赋值

一.对象的类型 对象的类型决定了对象占用内存空间的大小,和内存的布局,内存中可存储值的范围以及对该对象可以进行的操作,由于对象的类型决定可以对其执行的操作,因此const属性也可以看做对象类型的组成部分.类型又分为静态类型和动态类型,对于普通对象,静态类型和动态类型一般是一致的:对于指针和引用类型,静态类型和动态类型可以相同也可以不同,静态类型是指针和引用定义时声明的类型,而动态类型是指程序运行时实际绑定的类型.当静态类型和动态类型不同时,一般来说有两种情况:一是指涉到常量的指针和引用绑定了一个

C语言结构体数组内带字符数组初始化和赋值

1.首先定义结构体数组: typedef struct BleAndTspRmtCmd{ char terminal[3]; char note[3]; char rmtCmd[10]; char cmdPropt[24];}; BleAndTspRmtCmd为结构体名,可以通过这个结构体名定义其他结构体变量,struct BleAndTspRmtCmd variable: 或者定义结构体数组变量,struct BleAndTspRmtCmd variable[]: 2.或者定义全局结构体变量,

extern关键字用法总结(顺带初始化和赋值的区别)

1.初始化和赋值的区别 初始化的含义是创建变量时赋予其一个初始值. 赋值是把对象的当前值擦除,用新值代替. 2.extern关键字的作用 C++的分离式编译机制可以让程序分为多个文件独立编译,如果要在多个文件中使用同一个变量,如果重复定义将发生程序错误,需要使用extern关键字来声明在另一个文件中已经定义过的变量.(如果为extern关键字声明的变量赋初值将抵消掉extern的作用,函数体内这样做将引发错误) 1 int a=0: //定义 2 3 extern int a: //声明 4 5

c++构造函数问题,初始化和赋值问题

默认构造函数(就是没有参数的构造函数) The Default ConstructorThe default constructor is the constructor used to create an object when you don't provide explicit initialization values. That is, it's the constructor used for declarations like this: Stock stock1;  // use

字符串的基本操作,初始化和赋值之类的区别,和数据名是一个常量指针不可以改变和赋值(盲点众多)

#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> //一级指针的典型用法 //数组 int a[10] //字符串 //1 C语言的字符串 以零结尾的字符串 //2 在C语言中没有字符串类型 通过字符数组 来模拟字符串 //3 字符串的内存分配 堆上 栈上 全局区 (很重要) //字符数组 初始化 void main51() { //1 指