精华内容
下载资源
问答
  • 以下变量初始化合法的是
    2020-10-11 11:33:45

    首先是指针变量的定义:指针是一种保存变量地址的变量。
    指针中最容易出现理解错误的地方就是指针为什么一定要先初始化,下面我将递进式的讨论这个问题。

    一,先说明只要是指针类型如果不利用已有的指针变量赋初始值,则必须要进行初始化,不然会出现会出现很多问题。
    如果是普通的指针变量,则可以用 指针变量名=&普通变量名 赋初始值,如果是结构体指针,则需要用new动态分配内存空间。
    其实我之前写过java中的引用和c/c++中的指针差不多里面都存了一个指向数据的地址,只不过c中的指针是自己主动定义的,而java中的引用是有固定的的数据类型(对象,数组,接口),而且java中引用必须要用new分配实体。
    二,首先定义指针*p1;此时p1中保存的必须是一个地址,下面这段代码是非法的,因为赋初始值时p1必须指向一段地址。

    	int a=5;
    	int *p1;
    	p1=a;
    

    三,下面这段代码和和上面代码的区别就是让*p1=a,而不是p1=a,按照优先级也就是(p1)=a,这里就牵扯到指针最难理解的地方。p1内存放的是一段地址,而*""**的含义则是指向p1内存放的地址中的数据。当我们定义p1时它没有被初始化(此时指针被叫做悬浮指针或野指针),那么程序就不知道它指向哪里,它可能指向一个非法地址,这时,程序会报错。它也可能指向一个合法地址,这种情况更危险,你的程序或许能正常运行,但是这个没有被初始化的指针所随机指向的那个位置的值可以被修改,而你可能并无意去修改它。
    所以下面的代码会出现两种情况
    第一种情况:p存放的是一个非法地址,此时**"*p"也就是将a赋值给p1内存放的地址中的数据,此时程序是不合法的(大部分是这种情况)
    第二种情况:p指向的是一个随机的合法地址,此时
    "*p"**就是将a赋值给p1内存放的地址中的数据,此时程序虽然是合法的,但你有可能修改了其他你不想修改的数据数据。
    所以综上所述下面这段代码也是不合法的。什么时候这段代码就是合法的了呢?请看四。

    	int a=5;
    	int *p1=a;
    

    四,那么正确的写法是下面

    int a=5;
    	int *p1;
    	p1=&a;
    //或
    	int *p1=&a;
    

    这段代码不用多解释,就是先定义指针*p,然后将a的地址赋给p1;
    要说明的是,当你给指针初始化以后下面的代码就合法了,此时p里存放的是a的地址,*p指向a地址内的数据,也就是将a的值变为了6。

    	int a=5;
    	int *p1;
    	p1=&a;
    	int *p1=6;
    

    五,当我们初始化完指针变量之后,之前的第二个问题中的代码就合法了

    1int a=5,b=6;
    2	int *p1;
    3	p1=&a;
    4	*p1=b;
    

    上面的代码我们第三行对指针进行了初始化,然后第四行让*p1=b,此时代码是合法的,因为对指针进行初始化之后,第四行的意思就是将b的值6覆盖p1中存放的地址中原来的数据5,但p1中存放的地址并没有改变(还是初始时a的地址),但地址里的数据也就是a的值却改变了,变成了b里的数据。你们可以思考一下次数输出a,b,&a,&b,p1,&p1的值是多少,有哪些是相等的

    六,最后再来说一个例子
    数据结构顺序栈入栈代码如下

    1Status Push(Sqstack &S,Elemtype e)
    2{//入栈 
    3	if(S.top-S.base==stacksize)		//判断栈满
    4	return OVERFLOW;				
    5	*S.top++=e; 
    }
    

    其中的第五行代码就是把e的值赋给S.top中存放的内存指向的数据,之所以可以使用这句话就是因为之前栈的初始化已经给top进行了初始化。

    更多相关内容
  • 答案是既有编译时,也可能会有运行时(seriously), 从语言的层面来说,全局变量初始化可以认为分成以下两个阶段(c++11 N3690 3.6.2):  static initialization: 静态初始化指的是用常量来对变量进行初始化,...
  • C++静态成员变量初始化

    千次阅读 2021-06-17 10:35:00
    静态成员变量初始化 静态成员变量可以初始化,但只能在类体外进行初始化。如: long long student::number = 13926572996; //在类体外对静态成员变量赋值 其一般形式为: 数据类型 类名::静态成员变量名 = ...

    静态成员变量初始化

           静态成员变量可以初始化,但只能在类体外进行初始化。如:

    long long student::number = 13926572996;    //在类体外对静态成员变量赋值

    其一般形式为:

    数据类型 类名::静态成员变量名 = 初值;

    不必在初始化赋值语句中加 static。

           注意:不可以在构造函数的参数初始化表中对静态成员变量初始化,例如:

        student(char* pn, char* pa, int n):number(n)

        {

            strcpy(name, pn);

            strcpy(addr, pa);

        }

           在构造函数中,对static类型的number成员进行初始化,是错误的操作。

    如果未对静态成员变量赋值,则编译系统会自动赋初值为0。

    如果一个成员变量定义为const类型,同时,也是static类型,那么,应该怎么样初始化?有如下的分析:

    (1) static类型的成员变量,需要在类外进行初始化;

    (2) const类型的成员变量,需要在构造函数的初始化列表进行初始化;

           那么,const类型的static成员变量,不可以在构造函数的初始化列表中进行初始化,例如:

           程序编译错误,如下:

           提示 student::number成员变量是static类型,仅仅在定义的时候可以初始化。所以,不可以在构造函数列表中初始化。所以,在类外对static类型的成员变量进行初始化,程序测试代码如下:

           程序运行结果如下:

           所以,可以在类外对const类型的静态成员变量进行初始化。

           注意:对于const 类型的static成员变量,可以在定义它的时候进行初始化,如下:

           在student类内对number成员进行初始化。这是合法的语句。

    韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip

    展开全文
  • C/C++ --- 全局变量初始化总结

    千次阅读 2017-10-27 14:51:17
    根据 C++ 标准,全局变量初始化要在 main 函数执行前完成,常识无疑,但是这个说法有点含糊,main 函数执行前到底具体是什么时候呢?是编译时还是运行时?答案是既有编译时,也可能会有运行时(seriously), 从语言...

    注意:本文所说的全局变量指的是 variables with static storage,措词来自 c++ 的语言标准文档。

    什么时候初始化

    根据 C++ 标准,全局变量的初始化要在 main 函数执行前完成,常识无疑,但是这个说法有点含糊,main 函数执行前到底具体是什么时候呢?是编译时还是运行时?答案是既有编译时,也可能会有运行时(seriously), 从语言的层面来说,全局变量的初始化可以划分为以下两个阶段(c++11 N3690 3.6.2):

    static initialization: 静态初始化指的是用常量来对变量进行初始化,主要包括 zero initialization 和 const initialization,静态初始化在程序加载的过程中完成,对简单类型(内建类型,POD等)来说,从具体实现上看,zero initialization 的变量会被保存在 bss 段,const initialization 的变量则放在 data 段内,程序加载即可完成初始化,这和 c 语言里的全局变量初始化基本是一致的。

    dynamic initialization:动态初始化主要是指需要经过函数调用才能完成的初始化,比如说:int a = foo(),或者是复杂类型(类)的初始化(需要调用构造函数)等。这些变量的初始化会在 main 函数执行前由运行时调用相应的代码从而得以进行(函数内的 static 变量除外)。

    需要明确的是:静态初始化执行先于动态初始化! 只有当所有静态初始化执行完毕,动态初始化才会执行。显然,这样的设计是很直观的,能静态初始化的变量,它的初始值都是在编译时就能确定,因此可以直接 hard code 到生成的代码里,而动态初始化需要在运行时执行相应的动作才能进行,因此,静态初始化先于动态初始化是必然的。

    初始化的顺序

    对于出现在同一个编译单元内的全局变量来说,它们初始化的顺序与他们声明的顺序是一致的(销毁的顺序则反过来),而对于不同编译单元间的全局变量,c++ 标准并没有明确规定它们之间的初始化(销毁)顺序应该怎样,因此实现上完全由编译器自己决定,一个比较普遍的认识是:不同编译单元间的全局变量的初始化顺序是不固定的,哪怕对同一个编译器,同一份代码来说,任意两次编译的结果都有可能不一样[1]。

    因此,一个很自然的问题就是,如果不同编译单元间的全局变量相互引用了怎么办?

    当然,最好的解决方法是尽可能的避免这种情况(防治胜于治疗嘛),因为一般来说,如果出现了全局变量引用全局变量的窘况,那多半是程序本身的设计出了问题,此时最应该做的是回头重新思考和修改程序的结构与实现,而不是急着穷尽技巧来给错误的设计打补丁。

    —- 说得轻松。

    几个技巧

    好吧,我承认总有那么一些特殊的情况,是需要我们来处理这种在全局变量的初始化函数里竟然引用了别的地方的全局变量的情况,比如说在全局变量的初始化函数里调用了 cout, cerr 等(假设是用来打 log, 注意 cout 是标准库里定义的一个全局变量)[2],那么标准库是怎样保证 cout 在被使用前就被初始化了呢? 有如下几个技巧可以介绍一下。

    (1)Construct On First Use

    该做法是把对全局变量的引用改为函数调用,然后把全局变量改为函数内的静态变量:

    int get_global_x()
    {
       static X x;
       return x.Value();
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5

    这个方法可以解决全局变量未初始化就被引用的问题,但还有另一个对称的问题它却没法解决,函数内的静态变量也属于 variables with static storage, 它们析构的顺序在不同的编译单元间也是不确定的,因此上面的方法虽然必然能保证 x 的初始化先于其被使用,但却没法妥善处理,如果 x 析构了 get_global_x() 还被调用这种可能发生的情况。

    (2)一个改进的做法是把静态变量改为如下的静态指针:

    int get_global_x()
    {
       static X* x = new X;
       return x->Value();
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5

    这个改进可以解决前面提到的 x 析构后被调用的问题,但同时却也引入了另一个问题: x 永远都不会析构了,内存泄漏还算小问题或者说不算问题,但如果 x 的析构函数还有事情要做,如写文件清理垃圾什么的,此时如果对象不析构,显然程序的正确性都无法保证。

    (3)Nifty counter.

    完美一点的解决方案是 Nifty counter, 现在 GCC 采用的就是这个做法[3][7]。假设现在需要被别处引用的全局变量为 x, Nifty counter 的原理是通过头文件引用,在所有需要引用 x 的地方都增加一个 static 全局变量,然后在该 static 变量的构造函数里初始化我们所需要引用的全局变量 x,在其析构函数里再清理 x,示例如下:

    // global.h
    
    #ifndef _global_h_
    #define _global_h_
    
    
    extern X x;
    
    class initializer
    {
       public:
         initializer()
         {
            if (s_counter_++ == 0) init();
         }
    
         ~initializer()
          {
            if (--s_counter_ == 0) clean();
           }
    
       private:
          void init();
          void clean();
    
          static int s_counter_;
    };
    
    static initializer s_init_val;
    
    #endif
    相应的 cpp 文件:
    
    // global.cpp
    
    #include "global.h"
    
    static X x;
    
    int initializer::s_counter_ = 0;
    
    void initializer::init()
    {
        new(&x) X;
    }
    
    void initializer::clean()
    {
       (&x)->~X();
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    代码比较直白,所有需要引用 x 的地方都需要引用 global.h 这个头文件,而一旦引入了该头文件,就一定会引入 initializer 类型的一个静态变量 s_init_val, 因此虽然不同编译单元间的初始化顺序不确定,但他们都肯定包含有 s_init_val,因此我们可以在 s_init_val 的构造函数里加入对 x 的初始化操作,只有在第一个 s_init_val 被构造时才初始化 x 变量,这可以通过 initializer 的静态成员变量来实现,因为 s_counter_ 的初始化是静态初始化,能保证在程序加载后就完成了。

    初始化 x 用到了 placement new 的技巧,至于析构,那就是简单粗暴地直接调用析构函数了,这一段代码里的技巧也许有些难看,但都是合法的,当然,同时还有些问题待解决:

    首先,因为 x 是复杂类型的变量,它有自己的构造函数,init() 函数初始化 x 之后,程序初始化 x 所在的编译单元时,x 的构造函数还会被再调用一次,同理 x 析构函数也会被调用两次,这显然很容易引起问题,解决的方法是把 x 改为引用:

    // global.cpp
    
    #include "global.h"
    
    // need to ensure memory alignment??
    static char g_dummy[sizeof(X)];
    
    static X& x = reinterpret_cast<X&>(g_dummy);
    
    int initializer::s_counter_ = 0;
    
    void initializer::init()
    {
        new(&x) X;
    }
    
    void initializer::clean()
    {
       (&x)->~X();
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    其中 static X& x = reinterpret_cast

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    转载自:http://blog.csdn.net/zhufenglonglove/article/details/52401939

    展开全文
  • (1)C语言从语法上规定全局变量只能用常量表达式来初始化,因此下面这种全局变量初始化是不合法的: int minute = 360; int hour = minute / 60; (2)如果全局变量在定义时不初始化则初始值是0,如果局部...

    (1)C语言从语法上规定全局变量只能用常量表达式来初始化,因此下面这种全局变量初始化是不合法的:

    int minute = 360;
    int hour = minute / 60; 
    

    虽然在编译时计算出 hour 的初始值是可能的,但是 minute / 60 不是常量表达式,不符合语法规定,所以编译器不必想办法去算这个初始值。

    (2)全局变量在定义时不初始化则初始值是0,局部变量在定义时不初始化则初始值是不确定的。
    所以,局部变量在使用之前一定要先赋值,如果基于一个不确定的值做后续计算肯定会引入Bug。

    (3)关于形参和实参
    记住这条基本原理:形参相当于函数中定义的变量,调用函数传递参数的过程相当于定义形参变量并且用实参的值来初始化

    (4)关于局部变量和临时变量
    假设写了一个如下的返回布尔值的函数

    int is _even(int x)
    {
    	if(x%2==0)
    		return 1;
    	else
    		return 0;
    }
    与之等价的,可以直接写成:
    int is even(int x)
    {
    	return !(x%2);
    }
    

    例如上面的函数调用相当于这样的过程:
    在这里插入图片描述

    参考:<Linux C 一站式编程>

    展开全文
  • C++ 语言变量的定义、声明和初始化

    千次阅读 2020-02-24 14:15:44
    C++ 语言变量的定义、声明和初始化 1. 定义变量 每种变量都存储一种特定的数据,在定义了变量后,它可以存储的数据类型就是固定的。存储整数的变量,就不能存储小数。 1.1 命名变量 变量的名称可以是任意字母和数字...
  • zero initialization 的变量会被保存在 bss 段,const initialization 的变量则放在 data 段内,程序加载即可完成初始化,这和 c 语言里的全局变量初始化基本是一致的。 dynamic initialization:动态初始化...
  • 结构体变量初始化和引用

    千次阅读 2021-01-21 18:28:37
    结构体变量初始化和引用 任务描述 本关任务:从键盘输入两个学生的学号,姓名和成绩(整数),分别存入结构体中,输出成绩较高的学生的学号,姓名和成绩。 相关知识 结构体类型用于描述由多个不同数据类型的数据...
  • C语言编程规范中,一个争论已久的问题,就是变量是否该在定义时进行初始化。 针对这个问题,谈谈我的个人想法。 相比于变量定义时初始化,本人更倾向于变量按需初始化。 当然,变量按需初始化并不是不要在定义时初始...
  • 定义结构体的时候,不能对里面的变量同时初始化。 因为定义结构体时,并未给其分配内存,所以初值是无法存储的。 应该声明结构体变量后,手工赋值。 struct sstring { int a; int date[2]; }sst[2]={{10,{1,2}},{20,...
  • C++类成员变量初始化位置

    千次阅读 2015-09-08 11:29:16
    static: static表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而... 在C++中,static静态成员变量不能在类的内部初始化。在类的内部只是声明,定义必须在类定义体的外部,通常在类的实现文件中初始
  • 指针变量定义和初始化

    千次阅读 2019-04-17 08:16:47
    1.指针定义和初始化 2.指向数组的指针 指针数组 指针定义 ...指针变量初始化 语法形式 存储类型 数据类型*指针名=初始地址; 例: int *pa = &a; 注意事项 用变量地...
  • 变量初始化引起错误

    千次阅读 2019-09-09 15:22:08
    内置类型变量是否自动初始化取决于变量定义...问题出在未初始化变量事实上都有一个值,编译器吧该变量放到内存中的某个位置,而把这个位置无论哪种位模式都当成是变量初始的状态,当被解释成整型值时,任何位模式都...
  • 静态(statis)变量只在第一次被调用时声明并初始化,此后保存在堆上。而对于类的静态成员来说,同样是所有类共享一个静态成员,需要注意的是静态成员的初始化 如下面代码 class A { public: static int a; // ...
  • c语言结构体学习整理(结构体初始化,结构体指针)

    万次阅读 多人点赞 2018-11-01 20:22:12
    首先我们为什么要用到结构体,我们都已经学了很多int char …等类型还学到了同类型元素构成的数组,以及取上述类型的指针,在一些小应用可以灵活使用,然而,在我们实际应用中,每一种变量进行一次声明,再结合起来...
  • 本节介绍Tensorflow中的变量创建和初始化操作。 初始化操作包含三种: 1. 给特定的变量单独初始化 2. 直接给所有变量初始化 3. 用其他的变量给一个变量初始化
  • 主要介绍了Java类加载连接和初始化原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 全局变量初始化

    千次阅读 2014-08-24 20:08:31
    注:以下例子仅是讨论C++语法,绝非推荐在实践中利用它们。 例1 extern int y; int x = y; int y = x; int main() ...{} 例2 extern int y; int x = y; int y = 3; int main() ...{...
  • 初始化数组成员变量:似乎没有比较简单的办法在初始化列表里初始化数组成员。建议在构造函数的函数体内赋值。不过可以用模板实现: #include #include class A { public: template A(Args... args) : x_...
  • Python判断变量名是否合法的方法示例问题:变量名是否合法:1.变量名可以由字母,数字或者下划线组成2.变量名只能以字母或者下划线开头s = 'hello@'判断变量名的第一个元素是否为字母或者下划线 s[0]如果第一个元素...
  • c语言结构体指针初始化

    千次阅读 2021-05-21 07:15:48
    今天终于看完了C语言深度剖析这本书,对C语言有了进一步的了解与感悟,突然发觉原来自己学C语言的时候学得是那样的迷糊,缺少深入的...定义了指针变量,没有为指针分配内存,即指针没有在内存中指向一块合法的内存...
  • 在了解指针变量初始化之前,首先要弄清楚一点:什么是指针?1、指针的内容实际上是一个地址,我们只要给指针赋值一个地址,它将会指向这个地址表示的内存空间,这也是指针的作用,我们要访问某个地址时,这个指针...
  • bootloader中关于flash擦除写和ram初始化的有关问题
  • C++变量初始化规则

    2013-07-29 19:23:23
    当我们定义一个没有初始化式的变量时,系统有时候会帮我们初始化变量,有时候又不会帮我们初始化变量。这主要取决于三点:(1)变量的类型;(2)变量的位置;(3)特殊的关键字。 1、 内置类型变量初始化 内置...
  • 如果是静态(static)生存期(函数外声明的变量和静态存储变量)的未初始化变量,可以确保整形初始化为0,浮点型初始化为0.0,指针初始化为null 。 如果是自动(automatic)生存期的变量(即非静态存储类型的局部...
  • 2.1详解变量的定义、初始化与赋值

    千次阅读 2017-01-16 15:39:34
    这一节我们将继续《1.3变量初探》的内容。 在前的课程中我们谈到,变量其实就是一块内存空间的名称。简要地说,计算机拥有可供程序使用的随机存取存储器(RAM),当一个变量被定义时,一部分内存就会被预留给这个...
  • 对于JAVA中类的初始化是一个很基础的问题,其中的一些问题也是易被学习者所忽略。当在编写代码的时候碰到时,常被这些问题引发的错误,感觉莫名其妙。而且现在许多大公司的面试题,对于这方面的考查也是屡试不爽。...
  • 指针变量的赋值指针变量同普通变量一样,使用之前不仅要定义说明, 而且必须赋予具体的值。未经赋值的指针变量不能使用, 否则将造成系统混乱,甚至死机。指针变量的赋值只能赋予地址, 决不能赋予任何其它数据,...
  • 一、没有为指针分配内存定义了指针变量,但是没有为指针分配...1、结构体成员指针未初始化struct student { char *name; int score; }stu,*pstu; int main() { strcpy(stu.name,"Jimy"); stu.score = 99; return ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 146,164
精华内容 58,465
关键字:

以下变量初始化合法的是