初始化_初始化数组 - CSDN
精华内容
参与话题
  • C语言各种变量的初始化

    万次阅读 多人点赞 2018-10-07 23:22:27
    数值类变量初始化 整型、浮点型的变量可以在定义的同时进行初始化,一般都初始化为0。 int inum = 0; float fnum = 0.00f; double dnum = 0.00; 字符型变量初始化 字符型变量也可在定义的同时进行初始化...

    数值类变量初始化

    整型、浮点型的变量可以在定义的同时进行初始化,一般都初始化为0

        int  inum  = 0;
        float fnum = 0.00f;
        double  dnum = 0.00;
    

    字符型变量初始化

    字符型变量也可在定义的同时进行初始化,一般初始化为'\0'

    char ch = '\0';  
    

    字符串初始化

    字符串初始化的方法比较多,我这里简单介绍三种,因为字符串本质上是由一个个字符组成的字符数组,所以其初始化的最终目的,就是将字符数组里面的一个个字符都初始化为'\0'

    方法一:使用空的字符串""

    char str[10] = "";
    

    方法二:使用memset

    char str[10];
    memset(str, 0, sizeof(str));
    

    方法三:写一个循环。

    char str[10];
    for(int i = 0; i < 10; i++)
    {
        str[i] = '\0';
    }
    

    这里比较推荐的是第二种初始化方法。也即使用memset进行初始化。

    很多人对memset这个函数一知半解,只知道它可以初始化很多数据类型的变量,却不知道其原理是什么样的,这里做一下简要的说明:memset是按照字节进行填充的。
    先看下面的一段代码:

    int num;
    memset(&num, 0, sizeof(int));
    printf("step1=%d\n", num);
    memset(&num, 1, sizeof(int));
    printf("step2=%d\n", num);
    

    在讨论之前,我们先看一下运行结果

    chenyc@DESKTOP-IU8FEL6:~/src$ gcc -o memset memset.c -g
    chenyc@DESKTOP-IU8FEL6:~/src$ ./memset
    step1 = 0
    step2 = 16843009
    chenyc@DESKTOP-IU8FEL6:~/src$
    

    看到这个运行结果,是不是和你想象中的不一样呢?
    step1 = 0 相信大家都好理解,可 step2 = 16843009 很多人就不能理解了。按照一般的惯性思维,不是应该 = 1 才对么?
    这就是我要说的,memset是按照字节进行填充的。
    我们知道,int 型是4个字节(每个字节有8位),按二进制表示出来就应该是:

    00000000 00000000 00000000 00000000
    

    按照按字节填充的原则,step1 的结果就是将4个字节全部填充0,所以得到的结果仍然是0:

    00000000 00000000 00000000 00000000 
    

    而 step2 则是将每个字节都填充为1 (注意是每个字节,而不是每个byte位) ,所以相对应的结果就应该是:

    00000001 00000001 00000001 00000001
    

    大家可以自己将上面那个二进制数转换成十进制看看,看看是不是16843009
    所以严格来说,memset函数本身并不具有初始化的功能,而是一个单纯的按字节填充函数,只是人们在使用的过程中,扩展出了初始化的作用。

    字符串初始化有一个小窍门,我们知道字符串本质上是字符数组,因此它具有两个特性,

    • 字符串在内存里是连续的,
    • 字符串遇'\0'结束。
      所以我们在初始化的时候,总是愿意给字符串本身长度加1的长度的内存进行初始化。
    char year[4+1];
    memset(year, 0, sizeof(year));
    strcpy(year,"2018");
    

    指针初始化

    一般来说,指针都是初始化为NULL

    int *pnum = NULL;
    int num = 0;
    pnum = &num;
    

    指针是个让人又爱又恨的东西,一般的整形、字符串等,初始化之后就可以直接拿来用了,可指针如果初始化为NULL后,没有给该指针重新分配内存,则会出现难以预料的错误(最最常见的就是操作空指针引起的段错误)。

    在动态内存管理中,由于变量的内存是分配在堆中的,所以一般用malloccalloc等函数申请过动态内存,在使用完后需要及时释放,一般释放掉动态内存后要及时将指针置空,这也是很多人容易忽略的。

    char *p = NULL;  
    p=(char *)malloc(100);  
    if(NULL == p)
    {  
        printf("Memory Allocated at: %x\n",p);  
    }
    else
    { 
        printf("Not Enough Memory!\n");  
    } 
    free(p);  
    p = NULL;   //这一行给指针置空必不可少,否则很可能后面操作了这个野指针而不自知,从而导致出现严重的问题
    

    很多人经常会犯的一个错误,我们知道,在指针作为实参进行参数传递时,该指针就已经退化成了数组,所以很多人就想到用memset来对该指针进行初始化:

    void fun(char *pstr)
    {
      memset(pstr, 0, sizeof(pstr));
      ...
    }
    

    这种写法是不正确的。我们姑且不管指针能不能用memset来进行初始化,指针首先保存的是一个4字节的地址,所以sizeof(pstr)永远只能 = 4,这样的初始化就毫无意义。

    结构体初始化

    结构体的初始化就比较简单了,基本也都是采用memset的方式。

    typedef struct student
    {
        int id;
        char name[20];
        char sex;
    }STU;
    STU stu1;
    memset((char *)&stu1, 0, sizeof(stu1));
    

    关于初始化结构体的长度问题,也即memset的第三个参数,一般来说,传入数据类型和变量名效果是一样的,上例中,下面写法是等价的效果:

    memset((char *)&stu1, 0, sizeof(STU));
    

    但是对于结构体数组的初始化,长度就需要注意一下了,还是以上例来做说明:

    STU stus[10];
    memset((char *)&stus, 0, sizeof(stus)); //正确,数组本身在内存里就是连续的,sizeof取出的就是数组的字节长度
    memset((char *)&stus, 0, sizeof(STU));  //错误,只会初始化第一个STU结构体,后面还有9个STU元素并未初始化
    memset((char *)&stus, 0, sizeof(STU)*10);  //正确,效果与第一个是一样的
    

    有些人习惯将memset的第二个参数写成以下形式:

    memset((char *)&stu1, 0x00, sizeof(stu1));
    

    只要理解了memset是按字节进行填充的,就知道这样写也是正确的,完全没有问题。

    展开全文
  • Java类的初始化、变量的初始化

    千次阅读 2018-06-02 15:21:23
    Java类的初始化、变量的初始化知识点Java常量, final 修饰,值被设定后不能再被修改静态变量里, static 修饰,顾名思义,无须创建对象,便可在内存中申请一个存储空间进行存储成员变量, 也称实例变量,它随着当前...

    Java类的初始化、变量的初始化


    知识点

    • Java常量,   final 修饰,值被设定后不能再被修改
    • 静态变量里,  static 修饰,顾名思义,无须创建对象,便可在内存中申请一个存储空间进行存储
    • 成员变量,  也称实例变量,它随着当前对象的建立而建立,随着对象的销毁而销毁,存在于对象所在的堆内存
    • 构造器,创建class对象时执行
    • 静态初始化块  ,执行优先级高于非静态的初始化块,它会在对象装载到 jvm的时候执行一次,执行完成便销毁,只能初始化 static 修饰的变量
    • 非静态初始化块,执行的时候如果有静态初始化块,先执行静态初始化块再执行非静态初始化块,在每个对象生成时都会被执行一次,它可以初始化类的实例变量。但它会在构造函数执行之前被执行

    类的初始化顺序

    Java中类初始化顺序,依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。。


    Java变量的初始化问题探究


    对于java的变量,我们知道有成员变量局部变量。

    关于他们的初始化,基本上所有书上都会写。成员变量,java会帮助你初始化,局部变量,则需要程序员自己初始化。

    对于类的成员变量。不管程序有没有显示的初始化,Java  虚拟机都会先自动给它初始化为默认值。

    规则为:

    1、整数类型(byte、short、int、long)的基本类型变量的默认值为0。

    2、单精度浮点型(float)的基本类型变量的默认值为0.0f。

    3、双精度浮点型(double)的基本类型变量的默认值为0.0d。

    4、字符型(char)的基本类型变量的默认为 “/u0000”。

    5、布尔性的基本类型变量的默认值为 false

    6、引用类型的变量是默认值为 null。

    7、数组引用类型的变量的默认值为 null。春关键数组变量的实例后,如果没有没有显示的为每个元素赋值,Java 就会把该数组的所有元素初始化为其相应类型的默认值。

    局部变量初始化

    局部变量声明以后,Java 虚拟机不会自动的为它初始化为默认值。因此对于局部变量,必须先经过显示的初始化,才能使用它。

    如果编译器确认一个局部变量在使用之前可能没有被初始化,编译器将报错。

    那么,加了修饰的java成员变量是如何初始化的呢在何时?在程序中的什么位置?

    下面看个小程序。

    [java] view plain copy
    1. public class TestC {  
    2.     /* 
    3.      * 定义成员变量 
    4.      * 尾数为1表示定义时进行初始化赋值 
    5.      * 尾数为2表示在代码块中进行初始化赋值 
    6.      * 尾数为3表示在构造函数中进行初始化赋值 
    7.      * 尾数为4表示在静态代码块中进行初始化赋值 
    8.      * 尾数为5表示不初始化赋值 
    9.      */  
    10.     /* 
    11.      * 普通成员变量  
    12.      */  
    13.     int field_a1 = 5;  
    14.     int field_a2;  
    15.     int field_a3;  
    16.     //报错:不能再静态代码块中使用非静态变量。 Cannot make a static reference to the non-static field field_a4  
    17.     //int field_a4;  
    18.     int field_a5;  
    19.     /* 
    20.      * final 成员变量 
    21.      */  
    22.     final int  field_b1 = 5;  
    23.     final int  field_b2;  
    24.     final int  field_b3;  
    25.     //报错:不能再静态代码块中使用非静态变量。Cannot make a static reference to the non-static field field_b4  
    26.     //final int  field_b4;  
    27.     //报错:未初始化 。The blank final field field_b5 may not have been initialized  
    28.     //final int  field_b5;  
    29.     /* 
    30.      * static成员变量 
    31.      */  
    32.     static int field_c1 = 5;  
    33.     static int field_c2;  
    34.     static int field_c3;  
    35.     static int field_c4;  
    36.     static int field_c5;  
    37.     /* 
    38.      * static final 成员变量 
    39.      */  
    40.     static final int field_d1 = 5;  
    41.     //报错:未初始化 。The blank final field field_d2 may not have been initialized  
    42.     //static final int field_d2;  
    43.     //报错:未初始化 。The blank final field field_d3 may not have been initialized  
    44.     //static final int field_d3;  
    45.     static final int field_d4;  
    46.     //报错:未初始化 。The blank final field field_d5 may not have been initialized  
    47.     //static final int field_d5;  
    48.       
    49.     //代码块  
    50.     {  
    51.           
    52.         field_a2 = 5;  
    53.         field_b2 = 5;  
    54.         field_c2 = 5;  
    55.         //field_d2 = 5;  
    56.     }  
    57.       
    58.     //静态代码块  
    59.     static{  
    60.         //field_a4 = 5;  
    61.         //field_b4 = 5;  
    62.         field_c4 = 5;  
    63.         field_d4 = 5;  
    64.     }  
    65.       
    66.     //构造函数  
    67.     public TestC(){  
    68.         field_a3 = 5;  
    69.         field_b3 = 5;  
    70.         field_c3 = 5;  
    71.         //field_d3 = 5;  
    72.           
    73.     }  
    74. }  

    然后我们对这个程序生成的.class文件进行反编译,看看他是如何运行的。

    下面是TestC.jad文件。反编译文件

    [java] view plain copy
    1. public class TestC  
    2. {  
    3.   
    4.     public TestC()  
    5.     {  
    6.         field_a1 = 5;  
    7.         field_a2 = 5;  
    8.         field_c2 = 5;  
    9.         field_a3 = 5;  
    10.         field_c3 = 5;  
    11.     }  
    12.   
    13.     int field_a1;  
    14.     int field_a2;  
    15.     int field_a3;  
    16.     int field_a5;  
    17.     final int field_b1 = 5;  
    18.     final int field_b2 = 5;  
    19.     final int field_b3 = 5;  
    20.     static int field_c1 = 5;  
    21.     static int field_c2;  
    22.     static int field_c3;  
    23.     static int field_c4 = 5;  
    24.     static int field_c5;  
    25.     static final int field_d1 = 5;  
    26.     static final int field_d4 = 5;  
    27.   
    28. }  

    看到这里我们就很有清晰的思路了。

    对于不加修饰的普通成员变量,无论我们在什么地方对其进行初始化赋值,系统都会默认在构造函数中进行赋值。

    对于final变量,无论我们在什么地方进行赋值,系统会默认final变量是在类中进行初始化

    对于static,系统会根据我们的需求,而在不同位置进行初始化。


    通过报错,我们可以发现。

    final变量必须进行初始化。否则就会报编译错误。The blank final field field_d5 may not have been initialized

    static成员变量的初始化发生在类被类加载器(classLoader)加载的时候系统会对没有初始化的静态成员变量在静态区进行默认赋值。

    普通成员变量的初始化发生在JVM为类生成实例开辟空间的时候进行默认初始化赋值


    参考博文:https://blog.csdn.net/wlcw16/article/details/8506846


    展开全文
  • 初始化三种方式

    2019-07-10 16:20:38
    数组的初始化方式总共有三种:静态初始化、动态初始化、默认初始化。下面针对这三种方式分别讲解。 1. 静态初始化 除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。 ...

    数组的初始化方式总共有三种:静态初始化、动态初始化、默认初始化。下面针对这三种方式分别讲解。

    1. 静态初始化

          除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

    【示例7-4】静态初始化数组

    1

    2

    int[] a = { 123 };// 静态初始化基本类型数组;

    Man[] mans = { new Man(11), new Man(22) };// 静态初始化引用类型数组;

    2.动态初始化

          数组定义与为数组元素分配空间并赋值的操作分开进行。

    【示例7-5】动态初始化数组

    1

    2

    3

    int[] a1 = new int[2];//动态初始化数组,先分配空间;

    a1[0]=1;//给数组元素赋值;

    a1[1]=2;//给数组元素赋值;

    3.数组的默认初始化

          数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

    【示例7-6】数组的默认初始化

    1

    2

    3

    int a2[] = new int[2]; // 默认值:0,0

    boolean[] b = new boolean[2]; // 默认值:false,false

    String[] s = new String[2]; // 默认值:null, null

    展开全文
  • c++中的初始化列表详解

    万次阅读 多人点赞 2018-05-18 18:15:04
    与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。 class foo { public: foo(string s, int i):name(s), id(i){} ; //...

    目录:

    定义

    与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。

    class foo
    {
    public:
    foo(string s, int i):name(s), id(i){} ; // 初始化列表
    private:
    string name ;int id ;
    };

    从概念上来讲,构造函数的执行可以分成两个阶段,初始化阶段和计算阶段,初始化阶段先于计算阶段.

    初始化阶段
    所有类类型(class type)的成员都会在初始化阶段初始化,即使该成员没有出现在构造函数的初始化列表中.

    计算阶段
    一般用于执行构造函数体内的赋值操作。

    下面的代码中,其中Test1有构造函数,拷贝构造函数及赋值运算符,为的是方便查看结果,Test2是个测试类,它以Test1的对象为成员,我们看一下Test2的构造函数是怎么样执行的。

    class Test1
    {
    public:
    Test1() // 无参构造函数
    {cout << "Construct Test1" << endl ;}
    Test1(const Test1& t1) // 拷贝构造函数
    {cout << "Copy constructor for Test1" << endl ;this->a = t1.a ;}
    Test1& operator = (const Test1& t1) // 赋值运算符
    {cout << "assignment for Test1" << endl ;this->a = t1.a ;return *this;}
    int a ;
    };
    class Test2
    {
    public:
    Test1 test1 ;
    Test2(Test1 &t1)
    {test1 = t1 ;}
    };

    调用代码:
    Test1 t1 ;
    Test2 t2(t1) ;
    输出:
    Construct Test1
    Construct Test1
    assignment for Test1

    解释一下:
    第一行输出对应调用代码中第一行,构造一个Test1对象
    第二行输出对应Test2构造函数中的代码,用默认的构造函数初始化对象test1 // 这就是所谓的初始化阶段
    第三行输出对应Test2的赋值运算符,对test1执行赋值操作 // 这就是所谓的计算阶段

    使用初始化列表的原因

    初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值操作。
    主要是性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表,为什么呢?由下面的测试可知,使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。同样看上面的例子,我们使用初始化列表来实现Test2的构造函数。

    class Test2
    {
    public:
    Test1 test1 ;
    Test2(Test1 &t1):test1(t1){}
    }

    使用同样的调用代码,输出结果如下:
    Construct Test1
    Copy constructor for Test1

    第一行输出对应 调用代码的第一行
    第二行输出对应Test2的初始化列表,直接调用拷贝构造函数初始化test1,省去了调用默认构造函数的过程。
    所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表.

    必须使用初始化列表的时候

    除了性能问题之外,有些时候合初始化列表是不可或缺的,以下几种情况时必须使用初始化列表
    1.常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
    2.引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
    3. 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化

    class Test1
    {
    public:
    Test1(int a):i(a){}
    int i;
    };
    class Test2
    {
    public:
    Test1 test1 ;
    Test2(Test1 &t1)
    {test1 = t1 ;}
    };

    以上代码无法通过编译,因为Test2的构造函数中test1 = t1这一行实际上分成两步执行:
    1. 调用Test1的默认构造函数来初始化test1
    由于Test1没有默认的构造函数,所以1 无法执行,故而编译错误。正确的代码如下,使用初始化列表代替赋值操作

    class Test2
    {
    public:
    Test1 test1 ;
    Test2(int x):test1(x){}
    }

    成员变量的顺序

    成员是按照他们在类中出现的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的,看代码:

    class foo
    {
    public:
    int i ;int j ;
    foo(int x):i(x), j(i){}; // ok, 先初始化i,后初始化j
    };

    再看下面的代码:

    class foo
    {
    public:
    int i ;int j ;
    foo(int x):j(x), i(j){} // i值未定义
    };

    这里i的值是未定义的因为虽然j在初始化列表里面出现在i前面,但是i先于j定义,所以先初始化i,而i由j初始化,此时j尚未初始化,所以导致i的值未定义。一个好的习惯是,按照成员定义的顺序进行初始化。

    展开全文
  • 初始化和默认初始化的区别

    千次阅读 2019-03-13 20:55:38
    参考资料[1]P185指出,如果局部变量没有显式的初始化值,它将执行值初始化(不是默认初始化!),内置类型的局部静态变量初始化为0 1 背景 参考资料[1]P39提到,在C++语言中,初始化与赋值并不是同一个概念:...
  • 当页面打开时我们需要执行一些操作,下面为大家介绍三种不错的方法,大家可以参考下 当页面打开时我们需要执行一些操作,这个时候如果我们选择使用jquery的话,需要重写他的3中方法,自我感觉没什么区 ...
  • 初始化列表

    2018-07-23 16:11:18
    构造函数初始化时必须采用初始化列表一共有三种情况:  需要初始化的数据成员是对象(继承时调用基类构造函数)  需要初始化const修饰的类成员  当成员属于某种类类型且该类没有定义默认构造函数时,也必须将这...
  • 页面加载初始化3种方式及区别

    万次阅读 2017-06-12 10:36:34
    1 $(function () { });//jquery 2 $(document).ready(function () { });//jquery 3 window.onload = function () { };//javascript ...第一种和第二种效果一样,是页面结构加载完成后执行;...第三种和前两种效果不同...
  • Java类的初始化顺序

    万次阅读 多人点赞 2018-07-05 10:03:23
    对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)&gt;(变量、初始化块)&gt;构造器。初始化顺序图示:我们也可以通过下面的测试代码来验证这一点:...
  • 前言:深度学习的初始化参数指的是在网络训练之前,对各个节点的权重和偏置进行初始化的过程,很多时候我们以为这个初始化是无关紧要的,不需要什么讲究,但是实际上,一个参数的初始化关系到网络能否训练出好的结果...
  • 类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化各数据... 情况一、需要初始化的数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);
  • gitinit git remote add origin xxxx (gitLab刚刚创建的工程地址) gitadd . (不要忘记点.) gitcommit -m 'init' gitpush -u origin master 以上就是master git checkout -b develop ...git push orig...
  • 初始化

    2019-06-28 10:12:16
    程序中有很多变量,需要给他们赋值,但是赋值的时间有前后,所以呢就出现了初始化顺序,下面我来总结一下我看过几篇初始化知识后的内容。 变量如果在一个类中,想要初始化类中的变量,必须要实例化该类,然后类便...
  • c语言结构体学习整理(结构体初始化,结构体指针)

    万次阅读 多人点赞 2019-07-28 20:58:11
    c语言中交换两个结构体的值(结构体指针) 1关于语言的结构体: 首先我们为什么要用到结构体,我们都已经学了很多int char …等类型还学到了同类型元素构成的数组,以及取上述类型的指针,在一些小应用可以灵活...
  • C++ 结构体初始化与赋值

    万次阅读 多人点赞 2020-07-24 12:39:28
    1.CC++结构体的初始化今天看到项目中对自定义结构体初始化方式有点陌生,特在此罗列一下可用的结构体初始化的方式。对结构体struct A { int b; int c; }有几种初始化方式:第一种:struct A a = { .b = 1, ...
  • 面试题: 如下两个类的代码 /*父类对象*/ public class Father{ private int i = test(); private static int j = method(); static{ System.out.print("(1)"); } Father(){ ... System.out.pr
  • C++数组初始化

    千次阅读 2018-12-28 11:19:39
    C++数组初始化 定义: int *pia = new int[10]; // array of 10 uninitialized ints 此 new 表达式分配了一个含有 10 个 int 型元素的数组,并返回指向该数组第一个元素的指针,此返回值初始化了指针 pia...
  • 深入理解Java对象的创建过程:类的初始化与实例化

    万次阅读 多人点赞 2017-05-22 08:05:02
    在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的。在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完成类的初始化。...
  • 不久前,在博客上发表了一篇文章——提高程序运行效率的10个简单方法,对于其中最后一点,多使用直接初始化,有很多读者向我提出了疑问,并写了一些测试程序,来说明直接初始化与复制初始化是同一件事。让我了解到...
  • SpringBoot重点详解--初始化

    万次阅读 2019-03-28 21:51:47
    目录 ...自定义初始化器 Springboot定义的初始化器 DelegatingApplicationContextInitializer ContextIdApplicationContextInitializer ConfigurationWarningsApplicationContextInitializer ...
1 2 3 4 5 ... 20
收藏数 3,758,203
精华内容 1,503,281
关键字:

初始化