鱼C论坛

 找回密码
 立即注册
查看: 1622|回复: 6

静态变量a的值

[复制链接]
发表于 2015-7-31 16:02:51 | 显示全部楼层 |阅读模式
30鱼币
下面这个程序中,全局变量与静态变量a在不同的作用域中取值是多少?解释得具体点,本人实在是想不清楚。
#include <stdio.h>

int a=2;
int f(int n)
{
        static int a=3;
        int t=0;
        if(n%2)
        {
                static int a=4;
                t+=a++;
        }
        else
        {
                static int a=5;
                t+=a++;
        }
        return t+a++;
}

int main()
{
        int s=a,i;
        for(i=0;i<3;i++)
        {
                s+=f(i);
        }
        printf("%d\n",s);
        
        return 0;


}

最佳答案

查看完整内容

从主函数中看 要求的是 2+f(0)+f(1)+f(2) 再看f(n)这个函数 里面有三个a 设第一个a 为 a ; 第二个a 为a1 ;第三个a 为a2 a1 和 a2 都只在其各自if分支里有效 所以最后返回值是第一个a 下面我们来计算 : f(0):t+=a2++ ----> t等于5,a2自增,a2等于6 return t+a++ ----> 返回t+a等于8(5+3) ,a自增 等于4 f(0)=8 f(1): t+=a1++ ------> t等于4,a1自增, a1等于5 return t+a++ -----> 返回t ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-31 16:02:52 | 显示全部楼层
从主函数中看 要求的是 2+f(0)+f(1)+f(2)
再看f(n)这个函数  里面有三个a   设第一个a 为 a ; 第二个a 为a1 ;第三个a 为a2
a1 和 a2 都只在其各自if分支里有效  所以最后返回值是第一个a
下面我们来计算 :
f(0):t+=a2++  ---->  t等于5,a2自增,a2等于6
return t+a++   ---->   返回t+a等于8(5+3) ,a自增 等于4
f(0)=8

f(1):

t+=a1++   ------> t等于4,a1自增, a1等于5
return t+a++   -----> 返回t+a等于8(4+4),a自增 等于5
f(1)=8

f(2):
t+=a2++   ------->  t等于6 ,a2自增
return t+a++   ----->  返回t+a等于11(6+5)

所以等于 2 + 8 + 8 + 11 = 29

希望楼主能够采纳!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-31 16:23:24 | 显示全部楼层
本帖最后由 ryxcaixia 于 2015-7-31 16:26 编辑

其实很简单
楼主 你的代码里面的静态变量 是静态局部变量 在局部覆盖全局变量

#include <stdio.h>
int a=2;
int f(int n)
{
        static int a=3;
        int t=0;
        if(n%2)
        {
                static int a=4; // 新定义静态局部变量, 永远被赋值为4
                t+=a++; // a的取值是刚刚定义的 静态局部变量 覆盖全局变量
        } // 语句结束 静态局部变量a消失
        else
        {
                static int a=5; // 静态局部变量, 永远被赋值为5
                t+=a++;  // a的取值是刚刚定义的 静态局部变量 覆盖全局变量
        } // 语句结束 静态局部变量a消失
        return t+a++;  // 这里的a是全局变量
}

int main()
{
        int s=a,i;
        for(i=0;i<3;i++)
        {
                s+=f(i);
        }
        printf("%d\n",s);
        
        return 0;


}
在整个函数中, 全局变量a的值并为改变, 即始终都是2

评分

参与人数 1鱼币 +5 收起 理由
364904690 + 5 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-7-31 16:59:22 | 显示全部楼层
取最近的(在一个模块中),但是在真实的编写中不要这样定义同名变量。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-8-1 10:04:28 | 显示全部楼层
本帖最后由 ryxcaixia 于 2015-8-2 09:16 编辑
ryxcaixia 发表于 2015-7-31 16:23
其实很简单
楼主 你的代码里面的静态变量 是静态局部变量 在局部覆盖全局变量


那刚刚进入被调用函数f时,static a=3,这个静态变量的作用域是整个函数吗?f被调用后,退出时,这个a的值与全局变量a=2;相冲突吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-8-2 09:16:11 | 显示全部楼层
364904690 发表于 2015-8-1 10:04
那刚刚进入被调用函数f时,static a=3,这个静态变量的作用域是整个函数吗?f被调用后,退出时,这个a的 ...


亲 我的注释写的比较清楚了 static a 这个变量的作用于仅仅是当前的{}大括号内 出了大括号就消失了
他并不会与全局变量冲突 而是直接覆盖了, 但是也不会影响全局变量的值 相当于此时全局变量a"隐藏"了, 但是仍然存在 只不过当前有个冒名顶替的局部变量a 所以在当前作用域 不可见
  if(n%2)
        {
                static int a=4; // 新定义静态局部变量, 永远被赋值为4
                t+=a++; // a的取值是刚刚定义的 静态局部变量 覆盖全局变量
        } // 语句结束 静态局部变量a消失
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-8-12 00:32:44 | 显示全部楼层
本帖最后由 默默路过 于 2015-8-12 00:35 编辑

//不知道楼主是否真的懂了,简单提一点个人意见希望有帮助
//楼主这个 关于作用域的问题是其一,其二还有就是关于C本身的内存处理的一些问题了
//在C里面一般的函数的局部变量我们知道都是在函数本身的栈中临时开辟的,随着函数调用的结束
//相关的所有局部变量都会被释放掉,这是 局部变量的生命周期(函数调用开始到函数调用结束);
//而全局变量的生命周期是程序开始到程序的结束,同样的他的存在位置就不在是任何函数的栈区了,
//全局变量和静态变量都是存在于一块叫 静态内存区的地方,这块内存区的生命周期也是从程序的开始
//到程序的结束,这是基本要注意的地方;下面说代码:


#include <stdio.h>

int a=2; //此处全局变量必然在静态内存区中 楼主可以再此处下断点然后查看内存 &a,这时可以看到其地址和值
int f(int n)
{
        static int a=3;//此处是函数f的静态局部变量,同样在静态类存区,同上方式查看内存你会发现 它就在全局a的后面
        int t=0;
        if(n%2)
        {
                static int a=4;//此处呢是一个复合语句的局部变量,同上看内存,你会看到他在函数静态局部变量a的后面
                t+=a++;//离开这里以后  a 不会消失,也不会被覆盖,定义的代码只会在首次调用时执行,其后不被执行但是一直存在 下次来 a就是5了
        }
        else
        {
                static int a=5;//此处也是一个复合语句的局部变量,同上看内存,你会看到他在if静态局部变量a的后面
                t+=a++;//离开这里以后  a 不会消失,也不会被覆盖,定义的代码只会在首次调用时执行,其后不被执行但是一直存在 下次来 a就是6了
        }
        return t+a++;//简单的一点所有变量都必须服从作用域原则。选择当前作用域内最近的变量值,这个其实和汇编的调用有一定的关系,
                                //就不展开说了,if 和else 的静态变量的作用域无法覆盖这句代码,而全局的a和函数的a都有覆盖,但是函数的a更近,
                                //所以此处操作和返回的必然是 函数的 静态局部变量了 也就是返回 , 8 , 8   ,  13,但愿口算没出错

}

int main()
{
        int s=a,i; //这个a 必然是全局的a了;
        for(i=0;i<3;i++)
        {
                s+=f(i);
        }
        printf("%d\n",s);
        
        return 0;
//终上所述在静态内存去中一共有4个不一样的a 分别属于4个作用域;都是在程序的开始到结尾都存在。
//区别只是使用的地方不同


}


//最后建议楼主 学会 单步调试中查看内存,这样的话很多东西,你的理解会跟进一步,不是仅仅只停留在使用的层面上
//C 中 重要的就是操作内存,所以,对于内存要了然于胸,每一变量,常量,甚至是函数地址(这一点我也还没达到。。。)在
//内存中的什么区域(这个区域不是说地址段的范围,没必要到那样的程度)都要清清楚楚,那么遇到问题就方便很多了!
//主要是 栈、堆、静态内存区、常量内存区、指令区(可以不管),前面三个是基础---说了不少闲话,希望有用!
//前面 内存 查看地址本来想放截图的,想想,希望楼主自己去验证一番!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-26 08:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表