精华内容
下载资源
问答
  • 局部变量&全局变量

    2019-11-28 22:45:40
    局部变量 局部变量只在本函数范围内有效 不同函数可以使用相同名字的变量 函数的形参也是局部变量 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效 全局变量 全局变量可以为本文件内...
    局部变量
    1. 局部变量只在本函数范围内有效
    2. 不同函数可以使用相同名字的变量
    3. 函数的形参也是局部变量
    4. 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效
    全局变量
    1. 全局变量可以为本文件内其他函数所共用,作用范围:从定义变量的位置到本源文件结束,这样来看,同一源文件内变量定义越早,生命周期越长
    2. 设置全局变量的作用是增加了函数间数据联系的渠道
    3. 同一源文件内,若外部变量与局部变量同名,则在局部变量作用的范围内,外部变量不起作用。(强龙压不过地头蛇)

    例子:

    #include <stdio.h>
    #include <stdlib.h>
    int a=3,b=666;
    int main()
    {
    	int max(int,int);
    	int a=999;
    	printf("%d",max(a,b));
    	return 0;
    }
    int max(int x,int y)
    {
    	return x>y?x:y;
    }
    
    结果:999
    
    展开全文
  • 定义一个函数如下: test() { char a; char b[10]; } 编译后test的入口地址假设为0x5000; 改写后 test() { ...但是这样改写后: ...为什么会有这样的区别,数据和char变量的初始化不一样吗?
  • 今天在写一个简单的嵌套函数时,需要在f2()中修改上层函数f1()的局部变量 def f1(): i=1 def f2(): i=i+1 return f2() 程序报错 UnboundLocalError: local variable 'i' referenced before assignment 一查,...

    今天在写一个简单的嵌套函数时,需要在f2()中修改上层函数f1()的局部变量

    def f1():
        i=1
        def f2():
            i=i+1 
        return f2()

    程序报错

    UnboundLocalError: local variable 'i' referenced before assignment

    一查,大概是局部变量作用域的问题

    f2 在 f1 之内,其作用域的范围等同于闭包,因此 x 实际上是在父函数 f1的作用域内,f2调用它类似于 f1调用全局变量,只能读取而不能直接改写 x。

    但是如果你使用列表对象的 x,则 x[0] 并非 x对象 ,而是 x 的元素,因此可以被改写。

    def f1():
        i=[1]
        def f2():
            i[0]=i[0]+1
        return f2()

    其实这是 python 2 的一个bug,在 python 3 中引入了 nonlocal语句,其类似于 global 语句,只不过是用来声明某个变量是父函数的那个变量,以便于子函数可以直接改写该变量。

    在python 2 中,只有用列表对象了,不过在 python 3 中可以这么写:

    def f1():
        i=1
        def f2():
            nonlocal i      #加上这一句声明这里的 i 是父函数的 i,之后便可以直接改写 i
            i=i+1

    转载于:https://www.cnblogs.com/velscode/p/10592793.html

    展开全文
  • C语言中局部变量的地址覆盖问题

    千次阅读 2017-10-19 15:37:58
     在C语言的一个函数中定义了几个局部变量如A,B,C。当对其中一个变量A取地址并对该地址赋值时,如果赋值的地址大小超过A所占的空间大小,则其它的变量会被修改。 2.调试过程  把被改变的变量的地址和A的地址...

    1.问题描述

        在C语言的一个函数中定义了几个局部变量如A,B,C。当对其中一个变量A取地址并对该地址赋值时,如果赋值的地址大小超过A所占的空间大小,则其它的变量会被修改。


    2.调试过程

       把被改变的变量的地址和A的地址打印出来,发现两者的地址差小于变量类型的地址。


    3.举例

    fun()

    {

    int a = 1, b = 2, c = 3;

    changeVarToZero(&a, sizeof(int) * 2);    //changeVarToZero功能是把从变量a地址开始的两整形数据大小的空间内容变为0

    //发现b或者c的变量会被改变

    }


    4.启示

        C语言函数的局部变量牵扯到指针操作时候,一定要仔细进行检查是否超出变量的边界。

    展开全文
  • C++返回局部变量引用的具体细节

    千次阅读 2020-06-04 17:04:23
    返回局部变量引用的情况 书上都说不能返回局部变量的引用或局部指针,说这种行为危险,但又没讲具体原因,那么今天就来看看这种行为的具体细节 PS:下面含有AT&T汇编内容,未学过汇编的朋友可以跳过直接看结论 ...

    返回局部变量引用的情况

    书上都说不能返回局部变量的引用或局部指针,说这种行为危险,但又没讲具体原因,那么今天就来看看这种行为的具体细节

    PS:下面含有AT&T汇编内容,未学过汇编的朋友可以跳过直接看结论

    先放一个实验用函数,即返回 int& 类型的局部变量的函数

    int& RetInt(){
        int i=42;
        int& RefI=i;
        return RefI;
    }
    

    测试函数

    稍后会用到的几个测试函数,用来说明不同情况下使用局部的结果

    void nop(){
        int i=0,i2=12;
    }
    void Snop(){
        int i=3;
        int&ri=i;
    }
    void Skip(){
        const double&d=4.2;
    }
    

    第一次测试[正常]

    主函数如下(待会使用控制变量法)
    调用 nop 函数

    /**
     * @brief FileName:main.cpp
     * environment : g++&Ubuntu18.04
    */
    int main(){
        std::cout<<RetInt()<<std::endl;
        int& i=RetInt();
        nop();
        // Skip();
        // Snop();
        std::cout<<i<<std::endl;
        return 0;
    }
    
    $ g++ main.cpp -omain;./main #编译指令
    

    输出结果为:
    42
    42

    即两次使用返回的局部变量引用都表现正常

    前瞻/需知

    这时候回顾前瞻知识:

    1. 局部变量存放在栈区
    2. 局部变量使用后会被销毁(栈顶指针变化)
    3. 引用为变量别名,实际编译中仍会取变量地址(可见下面源程序和汇编相应部分)
    int  i=42;
    int& iref=i;
    int* ip=&i;
    
    movl    $42, -36(%rbp)      ;int i=42;
    leaq    -36(%rbp), %rax     ;leaq 为汇编取地址操作
    movq    %rax, -32(%rbp)     ;int& iref=i;//可见引用占的大小和 类型(int)大小是相同的
    leaq    -36(%rbp), %rax
    movq    %rax, -24(%rbp)     ;int* ip=&i;//指针为 8 个 字节
    

    解释

    1. 引用存放地址不与变量存放地址相同
    2. 销毁对象并不会改变相应地址的值,只改变栈顶指针,所以值能很容易被重写,但目前没有数据去重写这块地址的值
    3. 连续声明两个变量的地址在之后(即没有覆盖)

    汇编细节

    下面看一下汇编的具体细节

    main函数

    main_function

    RetInt

    RetInt
    黄框部分为C++源文件中函数语句直接对应部分

    nop

    nop
    可以看到之前函数所用内存:-20(%rbp) -16(%rbp) 是没有改变的

    第二次测试[接近真相]

    调用 Snop 函数
    main_Snop
    编译指令不变
    输出结果:

    42
    3
    Snop

    通过黄框可以明显看到调用 Snop 函数的时候定义变量和引用都是用的之前[上一个调用时]使用的内存地址,即发生了覆盖读写,main函数中的 i 的值发生变化

    这时似乎可以怀疑是 int i=RetInt();时,这时的 i 已经是3了
    那么修改了一下main函数
    New_main
    结果不变,和上面是一样啊
    到这里就基本验证了之前的解释
    只声明变量的函数未覆盖之前销毁的对象地址
    而如果使用了引用则覆盖地址

    第三次测试[危险结果]

    调用 Skip 函数
    main_Skip
    编译指令不变
    输出结果:

    42
    1074842828

    Skip 函数中常量引用 d 的值改为 0.0 后,输出第二行为 0

    如果第二次实验只是改变了数值,还勉强能看到值的由来的话,那这个 4.2 带来的值的变化,是着实看不懂了
    其实的话,是用double类型浮点数的形式存储 4.2 然后用int类型的形式去读取相应内存单元的结果

    汇编

    Skip

    Skip

    RetInt

    在这里插入图片描述
    可以看出显示的是Skip函数定义的常量引用的高位地址的值
    也许会有人质疑double类型的会影响是因为double 八位,相当于 int 与 int& 的总和
    于是对 Skip 函数稍加更改
    New_Skip
    输出结果:

    42
    4

    RetInt 函数的汇编没有变化

    Skip

    Skip
    可以看到依然发生了对地址的覆盖改写

    conclude

    结论

    1. 实验结果是对书所说结果的验证。
    2. 销毁对象的意思是可以改写那一块的值。
    3. 局部变量引用的使用是有很大风险的
      1. 风险在于所使用的引用的值,可能发生意味的改变 使用者不知道或未注意到的
      2. 除非是当临时值使用 如同 std:cout<<RetInt()<<std::endl; 不然没有语法检测的报错和警告,是很容易找不到问题所在的。
    4. 其实看着汇编代码来说的话 原来那个位置的值还是可以算出来的 能通过看代码最后知道那个值
      1. 不过 正经人谁做这个
    5. 简单点说就是 理解这种情况就相当于
      int retRef(){
      	int i;
      	return i;
      }
      int main(){
      	std::cout<<retRef()<<std::endl;
      }
      
    6. 补充一点就是 返回指向局部变量的指针 跟这个是差不多的
    展开全文
  • ASM增加局部变量

    千次阅读 2015-03-10 20:33:04
    使用asm工具为一个函数添加局部变量后,重新加载该类失败。本篇文章主要分析错误的原因以及解决的办法。 首先了解一下虚拟机的类加载机制。类在初始化之前要完成加载、验证、准备和解析。 加载 加载过程分为三步: 1...
  • 全局变量和局部变量  globals() 函数 和 locals函数  函数的嵌套定义 作用域  变量名的查找规则:  global语句  nonlocal 语句  nonlocal 说明 lambda 表达式(又称匿名函数) 全局变量和局部变量  ...
  • 函数里的局部变量一般都是按序排放的,并且因为是分配在堆栈之中,它们的地址是向下“增长”,即向低地址方向增长。比如下面的程序: int flag=0x12345678; printf("%x\n",flag); char s[6]; printf(“address ...
  • 全局变量和局部变量在内存中的区别 C语言经过编译之后将内存分为以下几个区域: (1)栈(stack):由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、返回值以及函数返回地址。操作...
  • # 定义一个外部函数outer def outer(): print('我是外部函数') x = 2 # 定义一个内部函数... nonlocal x # 此时这里的x不再是新增的变量,而是外部的局部变量x y = x + 1 print(y) x = 10 # 不是修改外部的局
  • 点dt显示dd的高度,如果用全局变量会产生冲突,解决的办法是将全局的变成局部的 -------全局变量有问题---------- var flag = true; $(".accountList2 dt").click(function(){ if(flag){ $(this).next()....
  • Python学习笔记,函数,全局变量&局部变量,内置函数
  • 函数返回局部指针变量是否可行?  我们大家都知道指针函数的返回指针不能指向函数内的自动变量,如果需要返回函数的内部变量的话,就需要将该变量声明为静态变量。为什么函数能够返回 静态变量的地址而...
  • 在做内存分配函数hook过程中,出现了一个导致程序崩溃的问题,最终定位到问题产生的罪魁祸首居然又是不知哪位大侠写的函数返回局部变量导致的。   该函数的实现大致是这样的: char * GetDateTime () {  char...
  • 静态局部变量被初始化后在程序运行期间是不会被释放的,可还是碰到每次如调用函数静态变量都变成初始值的现象,经过单步调试发现我在函数中定义了一个数组, char str[7]; str[7] ='0'; 很明显的一个数组越界,...
  • 为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象能够返回其地址,而什么样的对象不能够返回其地址?静态变量局部自动变量的主要区别是什 么?    要想明白这些就需要理解...
  • "是一个字符串常量,存放在静态数据区,没错,但是把一个字符串常量赋值给了一个局部变量(char []型数组),该局部变量存放在栈中,这样就有两块内容一样的内存,这是与前着最本质的区别,当returnStr函数退出时,栈...
  • 将指向栈底的ebp的值付给esp(栈顶的值),这个栈为空了,里面没变量了,从函数的角度说,所有的局部变量都已经“不存在”了,我们不应该用函数的局部变量做返回值,但是我们看到了 0040105C pop ebp //恢复...
  • volatile 修饰变量,会告知编译器每次都从变量的地址读取数据,而在局部变量上,一般使用后即释放,会有很多函数的局部变量用同一地址的SRAM,如果中断函数改写了该数据,会导致执行异常。 2. 局部变量必须要...
  • 上面的例子表明,增加局部变量后,编译器就不需要担心timer1和step的别名问题了,减少了对存储器的访问次数,减少对存储器的访问次数对提高系统性能是非常有好处的。 嵌入式及3G相关资源及学习请点击: 嵌入式...
  • 文章目录难查的数组越界神奇的volatile局部变量了解你的编译器编译器的一些小知识初始化的全局变量和静态变量的初始值被放到了哪里?在C代码中使用的变量,编译器将他们分配到RAM的哪里?默认情况下,栈被分配到RAM...
  • 1.对于变量来说,定义就是声明。 例如:int a ; 我们可以说它是定义也可以说是声明 2.对于函数来说,声明和定义完全不是一回事。 void sum(int a,int b); --函数的声明 void sum(int a,int b){ };--函数...
  • Java和C++中循环体中局部变量的相同点看以下Java代码public class tesT { public static void main(String args[]){ for(int i=0;i;i++) System.out.println(i); for(i=1;i;i++) System.out.println("this is 2
  • 上一篇简单介绍了基本Block的内部源码转换以及内部参数结构分析点击打开Block第一篇传送门 这次介绍一下Block是如何截获自动变量以及__block是什么原理???直接上代码#include "stdio.h" int main(){ ...
  • 当然,这个过程包括回收函数内部的局部变量(局部变量也是存储在栈空间中),而此处的"回收"是指销去变量名/函数名,并把其内存空间标记为可用。即操作系统可对该部分内存空间重新利用。但既然变量已经被回收了,为...
  • 函数返回局部指针变量是否可行

    千次阅读 2018-08-18 11:25:45
    近期在准备面试的过程中,多次遇到了strcpy的实现问题,在很多实现程序中...我们大家都知道指针函数的返回指针不能指向函数内的自动变量,如果需要返回函数的内部变量的话,就需要将该变量声明为静态变量。为什么函...
  • 为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象能够返回其地址,而什么样的对象不能够返回其地址?静态变量局部自动变量的主要区别是什 么?  要想明白这些就需要理解程序的...
  • 对于返回局部指针变量的思考

    千次阅读 2014-05-19 22:25:10
    为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象能够返回其地址,而什么样的对象不能够返回其地址?静态变量局部自动变量的主要区别是什 么?    要想明白这些就需要理解...
  • 被一组“{}”括起来的部分被称为一个“域”,在某个域中定义的变量称为局部变量,这个局部变量仅仅在该作用域下有效,一旦离开这个作用域,该变量就消亡;如果遇见多重作用域,外层的变量可在内层起作用,如果遇见...
  • c中的static变量

    2016-04-13 20:48:00
    static局部变量中文名叫静态局部变量。它与普通的局部变量比起来有例如以下几个差别: 1)位置:静态局部变量被编译器放在全局存储区,所以它尽管是局部的。可是在程序的整个生命周期中存在。 2)訪...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,154
精华内容 15,661
关键字:

局部变量改写