精华内容
下载资源
问答
  • 最近通过帮朋友解答c++的一道笔试题,学到了不少东西,在此记录下。...这就要从static变量初始化的阶段谈起了,首先我们先了解一下c++中关于静态变量的三条规则: 在C++中,全局static变量和class的stat

    最近通过帮朋友解答c++的一道笔试题,学到了不少东西,在此记录下。
    题目如下:
    在这里插入图片描述
    看到这道题,大部分人都能意识到这道题考的是 static 关键字的相关知识,static 关键字定义的变量只会初始化一次,并且值会在作用域内共享。到此大部分分人直接选D选项就接啥这道题了。
    但是细心的人可能会问,调用三次fun()函数,a被定义了三次,为什么不会报编译错误呢?这就要从static变量初始化的阶段谈起了,首先我们先了解一下c++中关于静态变量的三条规则:

    1. 在C++中,全局static变量和class的static成员变量在main函数之前初始化,main函数之后销毁
    2. 函数内部的局部static变量在该函数第一次被调用时初始化,在main函数之后销毁
    3. 对于static数据即使是函数内部的对象则存放在全局数据区,全局数据区的数据并不会因为函数的退出就将空间释放。

    根据上边三条规则可知,函数内部static变量的初始化发生在函数第一次被调用之前,换句话说函数内部定义静态变量的代码会被单独拿出来,并在函数第一次调用之前被统一执行,这解释了为什么无法用变量对静态变量赋值。因此,多次执行fun()函数并不会重复定义类内的静态变量。

    此外,在不同作用域内,可以定义多个同名的静态变量,例如函数内和函数外可以定义两个同名的静态变量。这些不同作用域内的同名静态变量有着不同的内存地址,在引用时也会遵循就近原则,不会彼此影响。

    展开全文
  • 为什么可以在同一个函数内定义次静态同名变量呢?这很违反我之前的认知,以为变量名就相当于我分配的这块地址的入口一样,定义3个同名变量不会搞出大事吗?编译器还不报错,无语..... 我加了很多的printf来测试,...

    今天在做深圳茁壮网络公司的笔试题时遇到一个令我非常困惑的问题,在网上找了好久没有找到满意的答案,所以只好自己总结下,如果写得有错误,希望大家指出了,毕竟是新手,写得不好勿怪。

     

    为什么可以在同一个函数内定义多次静态同名变量呢?这很违反我之前的认知,以为变量名就相当于我分配的这块地址的入口一样,定义3个同名变量不会搞出大事吗?编译器还不报错,无语.....

    我加了很多的printf来测试,发现了一些规律,在这个程序中我总共定义了四个a,哈哈,一个全局变量,3个局部静态变量,通过printf输出可知,3个局部变量都满足就近原则,毕竟计算机也想偷偷懒啊,大家应该都知道,额,还是给大家说明一下吧,以下内容是我复制过来的....讲得还比较简单易懂

     

    (1) 静态局部变量在静态存储区内(data段(初始化)/.bss段(未初始化))分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,存储在动态存储区空间(而不是静态存储区空间),函数调用结束后即释放。 
    (2) 为静态局部变量赋初值是在编译时进行值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。而为自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。 
    (3) 如果在定义局部变量时不赋初值的话,对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符型变量)。而对自动变量来说,如果不赋初值,则它的值是一个不确定的值。这是由于每次函数调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元中的值是不确定的。 
    (4) 虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的,也就是说,在其他函数中它是“不可见”的

     

    其实这些不是重点,重点是怎么在同一函数中分配3个同名的变量的,md,不怕出事吗?

    度娘没有帮助我找到答案,垃圾度娘,只好使出无敌神器GDB来打印4个a的地址,看是不是同一地址,这要是同一地址肯定炸锅了

    GDB调试结果:全局变量的地址是 0x804a018(当然每个人的都肯定不一样啦)

                                函数进口那个a是0x804a020

                               else里面那一个是0x804a028

                                if里面那一个是0x804a024   

    虽然不能说明分配的一定是连续的地址,但是肯定可以说是按定义的先后顺序来分配地址的,而且是在程序运行前就已经分配好了的

     

     

     

    以下是源码:

     

    #include<stdio.h>
    
    int a=2;
    int j =1; //只是用来区分第几次运算
    int f(int n)
    {
    	
    	printf("================%d===============\n",j++);
    	static int a=3;
    	int t=0;
    	if(n%2)
    	{
    		printf("1-------a=%-3dt=%-3d\n",a,t);
    		static int a=4;
    		printf("1plus---a=%-3d t=%-3d\n",a,t);
    		t+=a++;
    		printf("2-------a=%-3dt=%-3d\n",a,t);
    	}
    	else
    	{
    		printf("3-------a=%-3dt=%-3d\n",a,t);
    		static int a=5;
    		printf("3plus---a=%-3dt=%-3d\n",a,t);
    		t+=a++;
    		printf("4-------a=%-3dt=%-3d\n",a,t);
    	}
    	printf("5---a=%-3dt=%-3d\n",a,t);
    	
    	return t+a++;
    }
    
    int main(void)
    {
    	int s=a,i;
    	for(i=0;i<3;i++)
    	{
    		s+=f(i);
    	    printf("s===%d\n",s);
    		printf("\n");
    	}
    	printf("%d\n",s);
    	
    	return 0;
    }
    
    

     

    下面是运行结果:

     

    展开全文
  • 当我们希望一个变量的作用域不仅仅是作用域某个类的某个对象,而是作用域整个类的时候,这时候就可以使用静态变量。 static static修饰的变量,是一个私有的全局变量。 C或者Java中static关键字修饰的变量,可以...

    静态变量

    当我们希望一个变量的作用域不仅仅是作用域某个类的某个对象,而是作用域整个类的时候,这时候就可以使用静态变量。

    static
    static修饰的变量,是一个私有的全局变量。
    C或者Javastatic关键字修饰的变量,可以使用类名直接拿到这个变量对象,在其他类中可以进行修改。但是在OCstatic修饰的变量是不能通过类名直接访问的,它只作用于它声明所在的.m文件中。
    static修饰的变量必须放在@implementation外面或方法中,它只在程序启动初始化一次。

    static int num;

    静态常量

    const
    const修饰的变量是不可变的,如果需要定义一个时间间隔的静态常量,就可以使用const修饰。

    static const NSTimeInterval LMJTimeDuration = 0.5;

    如果试图修改TimeDuration编译器则会报错。

    如果我们定义一个字符串类型的静态常量就要注意了,这两种写法是一样的,而且是可以修改的

    static NSString const * LMJName = @"iOS开发者公会";
    static const NSString * LMJName = @"iOS开发者公会";

    这两种写法cons修饰的是* LMJName*是指针指向符,也就是说此时指向内存地址是不可变的,而内存保存的内容时可变的
    所以我们应该这样写:

    static NSString * const LMJName = @"iOS开发者公会";

    当我们定义一个对象类型常量的时候,要将const修饰符放到*指针指向符后面。

    全局变量

    extern
    extern修饰的变量,是一个全局变量。

    extern NSString * LMJName = @"iOS开发者公会;

    extern修饰的变量也可以添加const进行修饰:

    extern NSString * const LMJName = @"iOS开发者公会;

    此时全局变量只能被初始化一次
    extern定义的全局常量的用法和宏定义类似,但是还是有本质上的不同的。 extern定义的全局常量更不容易在程序中被无意窜改。


    作者:MajorLMJ
    链接:http://www.jianshu.com/p/aec2e85b9e84
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    展开全文
  • 头文件中定义static静态变量的利弊

    千次阅读 2018-01-19 19:40:22
    频繁使用其实效率更高,如果定义静态变量不用,那就会浪费内存,因为全局数据区生命周期是从程序运行到结束。 局部变量:每次栈上都要为局部变量分配空间,因此局部变量太多会影响效率,但是其回收方便,

    转自:http://blog.csdn.net/caiqinghua0201/article/details/6076333

    对于存储位置:静态变量的效果和全局变量的效果是一样的,他们都保存在全局数据区。频繁使用其实效率更高,如果定义的静态变量不用,那就会浪费内存,因为全局数据区生命周期是从程序运行到结束。

    局部变量:每次栈上都要为局部变量分配空间,因此局部变量太多会影响效率,但是其回收方便,对于稳定性要求高的系统来说,这样的操作会更可靠。

    全局变量(包含静态变量):其空间会在程序启动时分配好,因此不用不停的分配,频繁使用更好(当然多线程下要同步则会更复杂)。另一点就是它会实实在在的一直占用内存,如果需要太大的内存,同时又不会频繁使用,则建议使用堆变量(特别是嵌入式下内存往往不够用)

    堆变量:可动态回收的内存,这样可以实现内存使用效率最大化,但是内存的分配和管理是需要付出时间的代价,而且使用要比较谨慎,否则容易内存泄露,管理很困难。

    函数内的静态变量,说明只有这个函数才用到。只暴露给需要用的人,是一个编码的好习惯。

    问:

    一般来说,静态全局变量只应该定义在实现文件中,但有时由于一些特殊的目的,也可能定义在头文件中。比如在有些标准库的实现中,就用这种方法来初始化标准流cin, cout,或者在在tr1库中,也用这种方法来定义占位符。每一个包含该头文件的实现文件中都拥有该变量的一份拷贝,这些变量放在运行体的data段或者bss段。
    比如下面这个变量定义在一个头文件中:
    static int data[1024*1024];
    我把这个文件同时包含在几个cpp文件中,按我的理解,这个程序占用的内存应该显著增大,但是,从实际运行结果来看,并没有变化,生成的exe文件大小也没有变化,这是因为延迟加载呢,还是被编译器优化掉了?有没有明白的达人解释一下。

    答:
    这不是编译器的问题,而是OS的virtual memeory管理机制导致的。数据在实际使用之前,是不会占用内存的——缺页异常处理程序会为数据分配需要的内存。

    要理解static,就必须要先理解另一个与之相对的关键字,很多人可能都还不知道有这个关键字,那就是auto,其实我们通常声明的不用static修饰的变量,都是auto的,因为它是默认的,就象short和long总是默认为int一样;我们通常声明一个变量:
    int a;
    string s;
    其实就是:
    auto int a;
    auto string s;
    而static变量的声明是:
    static int a;
    static string s;
    这样似乎可以更有利于理解auto和static是一对成对的关键字吧,就像private,protected,public一样;
    对于static的不理解,其实就是对于auto的不理解,因为它是更一般的;有的东西你天天在用,但未必就代表你真正了解它;auto的含义是由程序自动控制变量的生存周期,通常指的就是变量在进入其作用域的时候被分配,离开其作用域的时候被释放;而static就是不auto,变量在程序初始化时被分配,直到程序退出前才被释放;也就是static是按照程序的生命周期来分配释放变量的,而不是变量自己的生命周期;所以,像这样的例子:
    void func()
    {
    int a;
    static int b;
    }
    每一次调用该函数,变量a都是新的,因为它是在进入函数体的时候被分配,退出函数体的时候被释放,所以多个线程调用该函数,都会拥有各自独立的变量a,因为它总是要被重新分配的;而变量b不管你是否使用该函数,在程序初始化时就被分配的了,或者在第一次执行到它的声明的时候分配(不同的编译器可能不同),所以多个线程调用该函数的时候,总是访问同一个变量b,这也是在多线程编程中必须注意的!
    static的全部用法:
    1.类的静态成员:
    class A
    {
    private:
    static int s_;
    };
    在cpp中必须对它进行初始化:
    int A::s_ = 0;// 注意,这里没有static的修饰!
    类的静态成员是该类所有实例的共用成员,也就是在该类的范畴内是个全局变量,也可以理解为是一个名为A::s_的全局变量,只不过它是带有类安全属性的;道理很简单,因为它是在程序初始化的时候分配的,所以只分配一次,所以就是共用的;
    类的静态成员必须初始化,道理也是一样的,因为它是在程序初始化的时候分配的,所以必须有初始化,类中只是声明,在cpp中才是初始化,你可以在初始化的代码上放个断点,在程序执行main的第一条语句之前就会先走到那;如果你的静态成员是个类,那么就会调用到它的构造函数;
    2.类的静态函数:
    class A
    {
    private:
    static void func(int );
    };
    实现的时候也不需要static的修饰,因为static是声明性关键字;
    类的静态函数是在该类的范畴内的全局函数,不能访问类的私有成员,只能访问类的静态成员,不需要类的实例即可调用;实际上,它就是增加了类的访问权限的全局函数:void A::func(int);
    静态成员函数可以继承和覆盖,但无法是虚函数;
    3.只在cpp内有效的全局变量:
    在cpp文件的全局范围内声明:
    static int g_ = 0;
    这个变量的含义是在该cpp内有效,但是其他的cpp文件不能访问这个变量;如果有两个cpp文件声明了同名的全局静态变量,那么他们实际上是独立的两个变量;
    如果不使用static声明全局变量:
    int g_ = 0;
    那么将无法保证这个变量不被别的cpp共享,也无法保证一定能被别的cpp共享,因为要让多个cpp共享一个全局变量,应将它声明为extern(外部)的;也有可能编译会报告变量被重复定义;总之不建议这样的写法,不明确这个全局变量的用法;
    如果在一个头文件中声明:
    static int g_vaule = 0;
    那么会为每个包含该头文件的cpp都创建一个全局变量,但他们都是独立的;所以也不建议这样的写法,一样不明确需要怎样使用这个变量,因为只是创建了一组同名而不同作用域的变量。
    这里顺便说一下如何声明所有cpp可共享的全局变量,在头文件里声明为extern的:
    extern int g_; // 注意,不要初始化值!
    然后在其中任何一个包含该头文件的cpp中初始化(一次)就好:
    int g_ = 0; // 初始化一样不要extern修饰,因为extern也是声明性关键字;
    然后所有包含该头文件的cpp文件都可以用g_这个名字访问相同的一个变量;
    4.只在cpp内有效的全局函数:
    在cpp内声明: static void func();
    函数的实现不需要static修饰,那么这个函数只可在本cpp内使用,不会同其他cpp中的同名函数引起冲突;道理和如果不使用static会引起的问题和第3点一样;不要在头文件中声明static的全局函数,不要在cpp内声明非static的全局函数,如果你要在多个cpp中复用该函数,就把它的声明提到头文件里去,否则在cpp内部声明需要加上static修饰;在C语言中这点由为重要!

    展开全文
  • static的三种用法,定义静态变量,静态函数,静态代码块!
  • 全局变量、全局静态变量、局部变量、局部静态变量区别
  • 定义静态成员变量:人数2.定义构造方法:对成员变量进行初始化。3.定义多个方法:分别显示相应的属性值,例如getName(){System.out.print("名称="+name+";"); }4.定义一个方法“成长”:实现年龄的增加,每执行一...
  • C# static静态变量用法

    千次阅读 2017-04-25 15:05:41
    定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量。 特点:  A、该变量在全局数据区分配内存。B、初始化:如果不显式初始化,那么将被隐式初始化为0。  静态局部变量 定义:在...
  • 静态变量 static

    千次阅读 2016-04-07 11:30:41
    静态变量一个非常重要的知识点,无论笔试面试,都是一个高频的考点!确实也十分重要,这里简单的总结一下,它C与C++中的作用!!以备后用! 变量的生命周期与作用域 静态变量属于静态存储方式,其存储空间为内存中...
  • 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。 2. 静态局部变量 静态局部变量属于静态存储方式,它具有以下特点: (1)静态局部变量...
  • static--静态变量与普通变量的区别

    万次阅读 多人点赞 2019-03-12 09:59:09
    静态变量与普通变量的区别 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽...
  • 静态局部变量静态全程变量static。

    万次阅读 多人点赞 2019-01-01 13:28:04
    我们知道在函数内部定义变量,当程序执行到它的定义处时,编译器为它在栈上分配空间,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一调用时,如何...
  • 在函数体内定义一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。但有的时候我们需要在两次调用之间对变量的值进行保存。通常的想法...
  • 全局变量、文件域的静态...局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义类型的对象。 class B{ public: B() { cout ; } ~B() { cout << "B
  • 外部变量和静态变量

    千次阅读 2013-12-05 20:08:31
     外部变量是在函数外部定义的全局变量,它的作用域是从变量定义处开始,到本程序文件的结尾。在此作用域内,全局变量可为各个函数所引用。编译时将外部变量分配在静态存储区。有时需要在其他文件中使用extern来...
  • Java静态变量、静态常量、静态方法

    万次阅读 2016-11-17 17:24:17
    Java静态变量、静态常量、静态方法  静态变量和静态方法都属于静态对象。在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态...
  • 静态变量浅析

    千次阅读 2009-02-10 15:12:00
    静态变量静态变量存放在内存中的静态存储区。...如果希望在一个文件中定义的外部变量的作用域仅局限于此文件中,而不能被其它文件所访问,则可以在定义此外部变量的类型说明符的前面使用static关键字。如:static f
  • Java中类变量(静态变量)和实例变量区别

    千次阅读 多人点赞 2018-04-14 16:01:34
    成员变量:把类内、方法体外定义的变量... 二是有static修饰的,称为类变量(静态变量)。类变量和实例变量的区别是:类变量在内存中只存份,在程序运行时,系统只为类变量分配一次内存,只进行一次的初始化。...
  • 那么这个类就只会 有这一个变量,称它是静态变量,它是属于这个类的,是类的专有的静态变量,而不是属于类的实例(对象)的。那么,属于这个类的静态变量,与该类之下对象的关系是什么呢?很容易想到,作为类专有的...
  • matlab中的静态变量和全局变量

    千次阅读 2018-05-02 12:25:22
    如果想保留这变量的值(供该函数下一次调用),可以把这变量声明为静态变量静态变量不能在声明的时候赋值,而且只能在function里声明,且只有这function才能认识它(main函数也不行)。x声明后是[],就是...
  • 全局变量和静态变量的区别

    千次阅读 2014-06-08 23:15:11
    静态变量不具有外部连接性,即同一工程中其它文件中不可以引用。 如: //cpp1.cpp extern int x=10; static int y=5; //cpp2.cpp #include  void main() {  extern int x;  extern int y;  co
  • C语言 静态变量与自动变量的区别

    万次阅读 多人点赞 2017-10-19 13:18:18
    C语言中使用auto 关键字声明自动变量,使用static关键字声明静态变量
  • 在C++语言中,变量有且只能有一次定义,但是可以声明多,使用变量前必须定义或声明。 再说到这些变量的声明与定义前,要知道这些变量的链接性: 外部全局变量 外部连接性 可以被extern 静态全局变量(static) ...
  • 静态变量和全局变量的区别

    千次阅读 2015-03-30 11:30:26
    全局变量与静态变量 static 声明的变量在C语言中有方面的特征: 1.变量被放在程序的全局存储区中,这样在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。 2.变量用static告知...
  • 静态变量,局部变量,全局变量

    千次阅读 2012-07-19 01:25:46
    静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。...
  • 分析:全局变量,局部变量,自动变量,静态变量标签:C语言 变量by 小威威1.全局变量&&局部变量全局变量指在函数体之外定义的变量; 局部变量指在函数体内部定义的变量。想必大家应该能分清这两个变量,我就不再...
  • 3、静态局部变量只在定义它的函数内有效,且程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。 4、全局变量和静态变量如果没有手工初始化,则由编译...
  • C#中的static静态变量的用法

    千次阅读 2019-02-16 21:16:31
    定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量。 特点:  A、该变量在全局数据区分配内存。  B、初始化:如果不显式初始化,那么将被隐式初始化为0。   静态局部变量 定义:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 386,205
精华内容 154,482
关键字:

定义一个静态变量两次