(原创)c#学习笔记06--函数02--变量的作用域01--其他结构中变量的作用域

6.2  变量的作用域

  在上一节中,读者可能想知道为什么需要利用函数交换数据。原因是C#中的变量仅能从代码的本地作用域访问。给定的变量有一个作用域,访问该变量要通过这个作用域来实现。

  在上一节中,读者可能想知道为什么需要利用函数交换数据。原因是C#中的变量仅能从代码的本地作用域访问。给定的变量有一个作用域,访问该变量要通过这个作用域来实现。代码如下:

class Program 
{ static void Write() { Console.WriteLine("myString = {0}", myString); } static void Main(string[] args) { string myString = "String defined in Main()"; Write(); Console.ReadKey(); } 
}

  编译代码,注意显示在任务列表中的错误和警告:

当前上下文中不存在名称“myString”【The name   'myString'   does not exist in the current context】
变量“myString”已赋值,但其值从未使用过【The variable 'myString' is assigned but its value is never used】

  什么地万出错了?不能在Write()函数中访问在应用程序主体(Main()函数)中定义的变量myString。

  原因是变量是有作用域的,在这个作用域中,变量才是有效的。这个作用域包括定义变量的代码块和直接嵌套在其中的代码块。函数中的代码块与调用它们的代码块是不同的。在Write()中,没有定义myString,在Main()中定义的myString则超出了作用域——它只能在Main()中使用。

  实际上,在Write()中可以有一个完全独立的变量myString,修古代码,如下所示:

class Program 
{ static void Write(){ string myString = "String defined in Write()"; Console.WriteLine("Now in Write()"); Console.WriteLine("myString = {0}", myString); } static void Main(string[] args) { string myString = "String defined in Main()"; Write(); Console.WriteLine("\nNow in Main()"); Console.WriteLine("myString = {0}", myString); Console.ReadKey(); } 
}

  运行后可以看到结果。

  这段代码执行的操作如下:
    Main()定义和初始化字符串变量myString。
    Main()把控制权传送给Wri。
    Write()定义和初始化字符串变量myString,它与Main()中定义的myString变量完全不同。
    Write()把一个字符串输出到控制台上,该字符串包含在Write()中定义的myString的值。
    Write()把控制仅传送回Main()。
    Main()把一个字符串输出到控制台上,该字符串包含在Main()中定义的myString的值。

  其作用域以这种方式覆盖一个函数的变量称为局部变量。还有一种全局变量,其作用域可覆盖多个函数。修改代码,如下所示:

class Program 
{ static string myString; static void Write() { string myString = "String defined in Write()"; Console.WriteLine("Now in Write()"); Console.WriteLine("Local myString = {0}", myString); Console.WriteLine("Global myString = {0}", Program.myString); 
} static void Main(string[] args) { string myString = "String defined in Main()"; Program.myString = "Global string"; Write(); Console.WriteLine("\nNow in Main()"); Console.WriteLine("Local myString = {0}", myString); Console.WriteLine("Global myString = {0}", Program.myString); Console.ReadKey(); } 
} 

  这里添加了另一个变量myString,这次进一步加深了代码中的名称层次。这个变量定义如下:

static string myString;

  注意,这里也需要static关键字。在这种类型的控制台应用程序中,必须使用static或const关键字,来定义这种形式的全局变量。如果要修改全局变量的值,就需要使用static,因为const禁止修改变量的值。

  为了区分这个变量和Main()与Write()中的同名局部变量,必须用一个完整限定的名称为变量名分类。这里把全局变量称为Program.myString。注意,在全局变量和局部变量同名时,这是必需的。如果没有局部myString变量,就可以使用myString表示全局变量,而不需要使用Program.myString。如果局部变量和全局变量同名,全局变量就会被屏蔽。

  是否使用全局变量取决于函数的位置。使用全局变量的问题在于,它们通常不适合于“常规用途”的函数——这些函数能处理我们所提供的任意数据,而不仅限于处理特定全局变量中的数据。

 

6.2.1  其他结构中变量的作用域

  变量的作用域包含定义它们的代码块和直接嵌套在其中的代码块。这也可以应用到其他代码块上,例如分支和循环结构的代码块。考虑下面的代码:

int i; 
for (i = 0; i < 10; i++) 
{ string text = "Line " + Convert.ToString(i); Console.WriteLine("{0}", text); 
} 
Console.WriteLine("Last text output in loop: {0}", text); 

  字符串变量text 是for 循环的局部变量,这段代码不能编译,因为在该循环外部调用的Console.WriteLine()试图使用该变量text,这超出了循环的作用域。修改代码,如下所示:

int i; 
string text; 
for (i = 0; i < 10; i++) 
{ text = "Line " + Convert.ToString(i); Console.WriteLine("{0}", text); 
} 
Console.WriteLine("Last text output in loop: {0}", text);

  这段代码也会失败,原因是必须在使用变量前对其进行声明和初始化,而text 是在for循环中初始化的。赋给text的值在循环块退出时就丢失了。但是还可以进行如下修改:

int i; 
string text = ""; 
for (i = 0; i < 10; i++) 
{ text = "Line " + Convert.ToString(i); Console.WriteLine("{0}", text); 
} 
Console.WriteLine("Last text output in loop: {0}", text); 

  只声明一个简单变量类型,并不会引起其他的变化。只有在给变量赋值后,这个值才占用一块内存空间。如果这种占据内存空间的行为在循环中发生,该值实际上定义为一个局部值,在循环的外部会超出了其作用域。

  即使变量本身没有局部化到循环上,循环所包含的值也局部化到该循环上。但是,在循环外部赋值可以确保该值是主体代码的局部值,在循环内部它仍处于其作用域中。这意味着变量在退出主体代码块之前是没有超出作用域的,所以可以在循环外部访问它的值。

  最后一个要注意的问题是,应采用“最佳实践方式”。一般情况下,最好在声明和初始化所有变量后,再在代码块中使用它们。一个例外是把循环变量声明为循环块的一部分,例如:

for (int i = 0; i < 10; i++) 
{ ... 
}

 

转载于:https://www.cnblogs.com/wodehao0808/p/4912236.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419403.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

禁用应用中Android系统的导航栏(特别是平板)

由于公司项目是在全屏下的&#xff0c;所有界面都是全屏&#xff0c;唯有弹出提示框的时候&#xff0c;会出现系统的导航栏&#xff0c;由于是平板&#xff0c;导航栏信息比较多&#xff0c;该项目属于永不让用户进入原系统的项目。所以有导航栏&#xff0c;就让用户有了机会进…

spring使用注解@Scheduled执行定时任务

最近做的项目中遇到了用spring中Schedule注解执行定时任务的功能&#xff0c;这里简单记录一下。 首先在applicationContext.xml中进行配置&#xff1a; xmlns 加下面的内容 xsi:schemaLocation加下面的内容 最后我们的task任务扫描注解 需要注意的几点&#xff1a; 1、spring的…

关于dialog的一点东西

今天开发一个上传照片的小功能&#xff0c;对弹出的Dialog的一些用法查找了下&#xff0c;记录下来以后备用。 1.设置dialog标题居中: 在style中配置如下代码 <style name"UploadDialog" parent"android:style/Theme.Dialog"> <item …

DIY Ruby CPU 分析 Part II

【编者按】作者 Emil Soman&#xff0c;Rubyist&#xff0c;除此之外竟然同时也是艺术家&#xff0c;吉他手&#xff0c;Garden City RubyConf 组织者。本文是 DIY Ruby CPU Profiling 的第二部分。本文系 OneAPM 工程师编译整理。 在第一部分中我们学习了 CPU 分析的含义和进行…

spring注解 @Scheduled(cron = 0 0 1 * * *)的使用来实现定时的执行任务

<span style"font-size:14px;">初次接触定时类的小程序&#xff0c;还是走了很多的弯路&#xff0c;如今终于搞定了&#xff0c;总结如下&#xff1a;</span> <span style"font-size:14px;">import com.activityvip.api.service.Securit…

在Oracle里,表的别名不能用as,列的别名可以用as

列的别名也可以不用as&#xff0c;如&#xff1a;select t.a xxx from table t在Oracle数据库中&#xff0c;数据表别名是不能加as的&#xff0c;例如&#xff1a; select a.appname from appinfo a;-- 正确 select a.appname from appinfo as a;-- 错误 注释&#xff1a;这…

Android自定义RadioButton

今天公司项目中需要完成一个效果&#xff0c;首先是要用自己的图片&#xff0c;然后文字在按钮图片的左边。 1.使文字在图片的左边&#xff0c;有两种方法&#xff1a; 第一种&#xff0c;设置radioButton的属性&#xff1a; <span style"font-size:24px;">a…

MySQL实现当前数据表的所有时间都增加或减少指定的时间间隔

做了一个简答的小项目&#xff0c;其中遇到了一些数据库的sql使用技巧总结如下&#xff1a; DATE_ADD() 函数向日期添加指定的时间间隔。 当前表所有数据都往后增加一天时间&#xff1a; UPDATE ACT_BlockNum SET CreateTime DATE_ADD(CreateTime, INTERVAL 1 DAY); 当前…

Android蓝牙4.0的数据通讯

我在两家公司都用到了app与BLE设备通讯&#xff0c;当时也是什么都不懂&#xff0c;在网上各种搜索&#xff0c;各种查资料&#xff0c;总算弄出来了。在这里记录下来&#xff0c;希望对有需要的人有些帮助。 1.检测手机是否支持蓝牙4.0&#xff08;一般手机4.3以上的android系…

荐 Intellij IDEA创建Maven Web项目(带有webapp文件夹目录的项目)

转载自&#xff1a;点击打开链接 在创建项目中&#xff0c;IDEA提供了很多项目模板&#xff0c;比如Spring MVC模板&#xff0c;可以直接创建一个基于Maven的Spring MVC的demo&#xff0c;各种配置都已经设定好了&#xff0c;直接编译部署就可以使用。 最开始自己创建maven we…

iOS设计模式 - 迭代器

iOS设计模式 - 迭代器 原理图 说明 提供一种方法顺序访问一个聚合对象中的各种元素&#xff0c;而又不暴露该对象的内部表示。 源码 https://github.com/YouXianMing/iOS-Design-Patterns // // Node.h // IteratorPattern // // Created by YouXianMing on 15/10/26. // …

Android程序杀死自己的进程和其他程序进程方法

1.获取程序进程ID&#xff1b; int pidandroid.os.Process.myPid(); android.os.Process..killProcess(pid); 2.杀死其他程序进程&#xff1b; ActivityManager manager(ActivityManager)getSystemService(ACTIVITY_SERVICE); manager.killBackgroundProcesses("packa…

maven依赖关系中Scope的作用

Dependency Scope 在POM 4中&#xff0c;<dependency>中还引入了<scope>&#xff0c;它主要管理依赖的部署。目前<scope>可以使用5个值&#xff1a; * compile&#xff0c;缺省值&#xff0c;适用于所有阶段&#xff0c;会随着项目一起发布。 * provided&…

如何运行ruby代码

第一种&#xff0c;ruby -e 在命令行中运行下面命令&#xff0c;-e的意思是&#xff0c;把后面的字符串当作脚本执行 ruby -e "print hello" 使用irb交互控制台 在命令行输入irb hello worldxingooxingoo-Lenovo:~/workspace/RubyTest$ irb irb(main):001:0> p &q…

使用ViewPager制作Android引导界面

1.涉及Android知识点&#xff1a; ViewPager组件、Handler机制、SharedPreferences。 2.开发实践&#xff1a; a.布局文件设计。 第一个引导界面one.xml&#xff0c;另外两个布局文件类似。 <?xml version"1.0" encoding"utf-8"?> <LinearLay…