C#中可以存在全局变量在函数钟自增和全局函数吗

博客访问: 1090333
博文数量: 276
博客积分: 8696
博客等级: 中将
技术积分: 2961
注册时间:
分类: C/C++ 23:39:05
个人牢骚:无奈,今天被人“鄙视”了,郁闷,看来要狠狠的打一下基础了。全局变量与全局静态变量的区别:
(a)若程序由一个源文件构成时,全局变量与全局静态变量没有区别。
(b)若程序由多个源文件构成时,全局变量与全局静态变量不同:全局静态变量使得该变量成为定义该变量的源文件所独享,即:全局静态变量对组成该程序的其它源文件是无效的。
静态全局变量的作用:
(a)不必担心其它源文件使用相同变量名,彼此相互独立。
(b)在某源文件中定义的静态全局变量不能被其他源文件使用或修改。
例如:一个程序由两个源文件组成,其中在一个源文件中定义了“”,在另一个源文件中定义了“”则程序给它们分别分配了不同的空间,两个值互不干扰。
例如:下面在file1.cpp中声明全局变量n,在file2.cpp中定义全局静态变量n。文件file1.cpp和file2.cpp单独编译都能通过,但连接时,file1.cpp中的变量n找不到定义,产生连接错误。
// file1.cpp
void main()
// file2.cpp
// 默认初始化为0,注意此处定义的n 只能在file2.cpp中使用。
静态函数:使某个函数只在一个源文件中有效,不能被其他源文件所用。
定义:在函数前面加上static。
说明:函数的声明和定义默认情况下在整个程序中是extern的。
静态函数的效果:
(1)它允其他源文件建立并使用同名的函数,而不相互冲突。
(2) 声明为静态的函数不能被其他源文件所调用,因为它的名字不能得到。&&&
静态变量和函数一般都局限于一个编译单元也就是.cpp文件中。
我想这是最主要的区别。&&&
静态变量和私有变量的最主要的区别就在于:他们分配内存空间的方式不一样。
静态变量的内存是在程序开始执时变量就占用了内存,直到程序结束时变量才释放内存.
私有变量(或者说是局部变量,不知道你是不是指这个:)),是在程序运行到该步的时候分配内存。所以,当离开了该私有变量的作用域的时候,私有变量的内存空间会被释放。
所以:静态变量只的值只会初始化一次,后面每次访问,都是上次处理过的值,(即使是在一个函数内部)。
私有变量每次都初始化。
看下面的实践:
&&& class Program
&&&&&&& static void Main(string[] args)
&&&&&&& {//输出未经定义的静态变量,结果为0;也说明了,在C#中未赋初值的变量系统自动赋为0
&&&&&&&&& Console.WriteLine(sort.i);&&&&&&&&&&
&&&&&&&& //静态变量的访问方法(类名.静态变量名),而且还可以在外部操作静态变量呢,可见静态变量并不神秘;
&&&&&&&&& sort.i = 5;
&&&&&&&& //输出5
&&&&&&&&& Console.WriteLine(sort.i);
&&&&&&& //还可以通过构造函数对静态变量初值呢,呵&&&&&&&&
&&&&&&&&& sort sortTest = new sort();
&&&&&&&& //输出构造函数中的赋值 3;
&&&&&&&&& Console.WriteLine(sort.i);
&&& class sort
&&&&&&& public sort()
&&&&&&&&&&&&&&& i = 3;
&&&&&&& }&&&&&&
总结:在类内部访问静态变量时,直接用静态变量名即可,不用以(类名.静态变量名),这样的方式访问,
除了有静态变量之外,还有静态类实例,还有静态方法.但用法都是大同小异;(没有静态类哦,呵呵越论越傻了)
如:public static void myFun(){}&& //静态方法
private static Random MyRandom=new Random(); //静态类实例
之所以有时声明为私有静态变量,是为了让它只初始化一次.这样节省了内存空间
但又想让它在外部是不可访问的,这样利用私有这个访问限定符就搞定了.
私有静态:安全又节省空间.
例:如果想在每次实例化类的时间生成一组随机数,但产生随机数是要用到一个类的,即Random,这个类不是静态类,它要产生实例,用产生的实例来生成随机数,但如果在每次类实例化时都产生一个Random实例,那内存空间简直是极大的浪费,所以可以用:
private static Random MyRandom=new Random();
这样每次类实例化时,都会用同一个Random实例MyRandom来产生随机数
阅读(11966) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~
请登录后评论。C#中可以存在全局变量和全局函数吗?_百度知道
C#中可以存在全局变量和全局函数吗?
我有更好的答案
可以在一个类中实现静态属性(字段)和静态方法,以此达到C或C++中全局变量和全局函数的效果。public&static&class&GlobalFunAndVar{&&&&public&static&int&Number{&}&&&&public&static&float&V&&&&&&&&public&static&float&GetValue()&&&&{&&&&&&&&return&V&&&&}&&&&&&&&public&static&void&SetNumber(int&number)&&&&{&&&&&&&&Number&=&&&&&}}定义好后,可以在任何地方使用://使用“全局变量”GlobalFunAndVars.Number&=&100;int&x&=&GloabalFunAndVars.NGlobalFunAndVars.Value&=&3.14;float&v&=&GlobalFunAndVars.V//使用“全局函数”float&y&=&GlobalFunAndVars.GetValue();GlobalFunAndVars.SetNumber(200);说明:严格地说在C#中没有全局函数和全局变量的概念。但是,可以通过类的静态成员(静态属性,静态方法,静态字段)来“模拟”全局变量和全局函数。
采纳率:87%
来自团队:
为您推荐:
其他类似问题
您可能关注的内容
全局变量的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。C#中的全局变量
winform全局变量,传参,cache,datagrid简单介绍 - C#,.net - language - ITeye论坛
C#中的全局变量
winform全局变量,传参,cache,datagrid简单介绍
锁定老帖子
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
wolfmaster
等级: 初级会员
来自: 深圳
发表时间:&&
一、C#中的全局变量
C#中没有了像VB.Net中的全局变量,那么我们如何实现在不同的页面间传递参数呢?
下面举例说明如何实现这一功能.
1.新建一个项目.
2.在该工程中添加一个窗体Form1.
3.在该窗体中定义静态型字符串变量myTestStr1:
public static string myTestStr1="";
4.在该窗体的构造函数中对该变量进行赋值,并为该窗体类添加属性GetStrValue.
public Form_Form1()
&&&&&&&& {
&&&&&&&&&&&&& InitializeComponent();
&&&&&&&&&&&&&
&&&&&&&&&&&&& myTestStr1="Hello!";
&&&&&&&& }
&&&&&&&& public string GetStrValue
&&&&&&&& {
&&&&&&&&&&&&& get
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& return myTestStr1;
&&&&&&&&&&&&& }
&&&&&&&&&&&&& set
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& myTestStr1=
&&&&&&&&&&&&& }
&&&&&&&& }&&&&&&
5.在该工程中另添加一个窗体Form2.
6.在Form1窗体上添加一个button按钮(name:but_Test);
7.在Form1窗体的but_Test_Click 事件中添加以下代码:
private void but_Test_Click(object sender, System.EventArgs e)
&&&&&&&& {
&&&&&&&&&&&&& Form2 frm1=new Form2();
&&&&&&&&&&&&& frm1.ShowDialog(this) ;
&&&&&&&&&&&&& frm1.Close();
&&&&&&&& }
8.在Form2窗体上添加一个button按钮(name:but_Yes);
9.在Form1窗体的but_Yes_Click 事件中添加以下代码:
private void but_Yes_Click(object sender, System.EventArgs e)
&&&&&&&& {
&&&&&&&&&&&&& MessageBox.Show (Form_Form1.myTestStr1 );&&& //直接访问. 显示.结果:" Hello!"
&&&&&&&&&&&&& Form_Form1 frm2=new Form_Form1();
&&&&&&&&&&&&& frm2.GetStrValue ="How do you do?";&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //生成一个新的实例对该静态变量进行操作(修改该静态变量的值).
&&&&&&&&&&&&& MessageBox.Show (frm2.GetStrValue );&&&&&&&&&&&&&&&&&&&& //通过该实例的内部成员对它进行访问 .显示.结果: How do you do?"
&&&&&&&&&&&&& MessageBox.Show (Form_Form1.myTestStr1 );&& //直接访问. 显示.结果:" How do you do?"
&&&&&&&& }
二、在Windows窗体开发中使用Cache
Cache在程序设计时可以带来很大的便利,这点想必在web程序开发中大家都有深刻的体会!同样,在windows程序设计中也可以使用它。
使用时需要将web引用添加到窗体项目的引用中,下面以一个实例介绍之!
首先要将程序的Main()函数放在一个添加的类里,这里就是AppMain类。下面是AppMain类的代码:
using S
using System.T
using System.W//添加引用
using System.Web.C //添加引用
using System.Windows.F
namespace WindowsApplication1
{
&&&& public class AppMain
&&&& {
&&&&&&&&& private static HttpRuntime _httpR
&&&&&&&& public static Cache Cache
&&&&&&&& {
&&&&&&&&&&&&& get
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& EnsureHttpRuntime();
&&&&&&&&&&&&&&&&&& return HttpRuntime.C
&&&&&&&&&&&&& }
&&&&&&&& }
&&&&&&&&& [STAThread]
&&&&&&&& static void Main()
&&&&&&&& {
&&&&&&&&&&&&& Application.Run(new Form1());
&&&&&&&& }
&&&&&
&&&&&&&&& private static void EnsureHttpRuntime()
&&&&&&&& {
&&&&&&&&&&&&& if( null == _httpRuntime )
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& try
&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&& Monitor.Enter( typeof( AppMain ) );
&&&&&&&&&&&&&&&&&&&&&&& if( null == _httpRuntime )
&&&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& // Create an Http Content to give us access to the cache.
&&&&&&&&&&&&&&&&&&&&&&&&&&& _httpRuntime = new HttpRuntime();
&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&& finally
&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&& Monitor.Exit( typeof( AppMain ) );
&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
&&&&&&&& }
&&&& }
}
然后在Form1窗体中定义和使用Cache,代码如下:
using S
using System.W//添加引用
using System.Web.C //添加引用
using System.D
using System.C
using System.ComponentM
using System.Windows.F
using System.D
namespace WindowsApplication1
{
&&&& ///&summary&
&&&& /// Form1 的摘要说明。
&&&& ///&/summary&
&&&& public class Form1 : System.Windows.Forms.Form
&&&& {
&&&&&&&&& private System.Windows.Forms.Label label1;
&&&&&&&&& private System.Windows.Forms.Label label2;
&&&&&&&&& private System.Windows.Forms.TextBox txtValueToPutInC
&&&&&&&&& private System.Windows.Forms.TextBox txtValueInC
&&&&&&&&& private System.Windows.Forms.Button btnPutInC
&&&&&&&&& private System.Windows.Forms.Button btnGetFromB
&&&&&
&&&&&&&&& private const string CACHE_KEY = "APPCACHEKEY";
&&&&&
&&&&&&&& ///&summary&
&&&&&&&& /// Required designer variable.
&&&&&&&& ///&/summary&
&&&&&&&&& private System.ComponentModel.Container components =
&&&&&
&&&&&&&& public Form1()
&&&&&&&& {
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // Required for Windows Form Designer support
&&&&&&&&&&&&& //
&&&&&&&&&&&&& InitializeComponent();
&&&&&&&&
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // TODO: Add any constructor code after InitializeComponent call
&&&&&&&&&&&&& //
&&&&&&&& }
&&&&&
&&&&&&&& ///&summary&
&&&&&&&& /// Clean up any resources being used.
&&&&&&&& ///&/summary&
&&&&&&&&& protected override void Dispose( bool disposing )
&&&&&&&& {
&&&&&&&&&&&&& if( disposing )
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& if (components != null)
&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&& components.Dispose();
&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
&&&&&&&&&&&&& base.Dispose( disposing );
&&&&&&&& }
&&&&&&&&& #region Windows Form Designer generated code
&&&&&&&& ///&summary&
&&&&&&&& /// Required method for Designer support - do not modify
&&&&&&&& /// the contents of this method with the code editor.
&&&&&&&& ///&/summary&
&&&&&&&&& private void InitializeComponent()
&&&&&&&& {
&&&&&&&&&&&&& this.label1 = new System.Windows.Forms.Label();
&&&&&&&&&&&&& this.label2 = new System.Windows.Forms.Label();
&&&&&&&&&&&&& this.txtValueToPutInCache = new System.Windows.Forms.TextBox();
&&&&&&&&&&&&& this.txtValueInCache = new System.Windows.Forms.TextBox();
&&&&&&&&&&&&& this.btnPutInCache = new System.Windows.Forms.Button();
&&&&&&&&&&&&& this.btnGetFromButton = new System.Windows.Forms.Button();
&&&&&&&&&&&&& this.SuspendLayout();
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // label1
&&&&&&&&&&&&& //
&&&&&&&&&&&&& this.label1.AutoSize =
&&&&&&&&&&&&& this.label1.Location = new System.Drawing.Point(8, 16);
&&&&&&&&&&&&& this.label1.Name = "label1";
&&&&&&&&&&&&& this.label1.Size = new System.Drawing.Size(113, 16);
&&&&&&&&&&&&& this.label1.TabIndex = 0;
&&&&&&&&&&&&& this.label1.Text = "Value to put in cache:";
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // label2
&&&&&&&&&&&&& //
&&&&&&&&&&&&& this.label2.AutoSize =
&&&&&&&&&&&&& this.label2.Location = new System.Drawing.Point(8, 40);
&&&&&&&&&&&&& this.label2.Name = "label2";
&&&&&&&&&&&&& this.label2.Size = new System.Drawing.Size(95, 16);
&&&&&&&&&&&&& this.label2.TabIndex = 1;
&&&&&&&&&&&&& this.label2.Text = "Value from cache:";
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // txtValueToPutInCache
&&&&&&&&&&&&& //
&&&&&&&&&&&&& this.txtValueToPutInCache.Location = new System.Drawing.Point(128, 16);
&&&&&&&&&&&&& this.txtValueToPutInCache.Name = "txtValueToPutInCache";
&&&&&&&&&&&&& this.txtValueToPutInCache.Size = new System.Drawing.Size(200, 20);
&&&&&&&&&&&&& this.txtValueToPutInCache.TabIndex = 2;
&&&&&&&&&&&&& this.txtValueToPutInCache.Text = "";
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // txtValueInCache
&&&&&&&&&&&&& //
&&&&&&&&&&&&& this.txtValueInCache.Location = new System.Drawing.Point(128, 40);
&&&&&&&&&&&&& this.txtValueInCache.Name = "txtValueInCache";
&&&&&&&&&&&&& this.txtValueInCache.ReadOnly =
&&&&&&&&&&&&& this.txtValueInCache.Size = new System.Drawing.Size(200, 20);
&&&&&&&&&&&&& this.txtValueInCache.TabIndex = 3;
&&&&&&&&&&&&& this.txtValueInCache.Text = "";
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // btnPutInCache
&&&&&&&&&&&&& //
&&&&&&&&&&&&& this.btnPutInCache.Location = new System.Drawing.Point(352, 16);
&&&&&&&&&&&&& this.btnPutInCache.Name = "btnPutInCache";
&&&&&&&&&&&&&& this.btnPutInCache.Size = new System.Drawing.Size(104, 23);
&&&&&&&&&&&&& this.btnPutInCache.TabIndex = 4;
&&&&&&&&&&&&& this.btnPutInCache.Text = "Put in Cache";
&&&&&&&&&&&&& this.btnPutInCache.Click +=
&&&&&&&&&&&&&&&&&& new System.EventHandler(this.btnPutInCache_Click);
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // btnGetFromButton
&&&&&&&&&&&&& //
&&&&&&&&&&&&& this.btnGetFromButton.Location = new System.Drawing.Point(352, 40);
&&&&&&&&&&&&& this.btnGetFromButton.Name = "btnGetFromButton";
&&&&&&&&&&&&& this.btnGetFromButton.Size = new System.Drawing.Size(104, 23);
&&&&&&&&&&&&& this.btnGetFromButton.TabIndex = 5;
&&&&&&&&&&&&& this.btnGetFromButton.Text = "Get from Cache";
&&&&&&&&&&&&& this.btnGetFromButton.Click +=
&&&&&&&&&&&&&&&&&& new System.EventHandler(this.btnGetFromButton_Click);
&&&&&&&&&&&&& //
&&&&&&&&&&&&& // Form1
&&&&&&&&&&&&& //
&&&&&&&&&&&&& this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
&&&&&&&&&&&&& this.ClientSize = new System.Drawing.Size(488, 133);
&&&&&&&&&&&&& this.Controls.Add(this.btnGetFromButton);
&&&&&&&&&&&&& this.Controls.Add(this.btnPutInCache);
&&&&&&&&&&&&& this.Controls.Add(this.txtValueInCache);
&&&&&&&&&&&&& this.Controls.Add(this.txtValueToPutInCache);
&&&&&&&&&&&&& this.Controls.Add(this.label2);
&&&&&&&&&&&&& this.Controls.Add(this.label1);
&&&&&&&&&&&&& this.Name = "Form1";
&&&&&&&&&&&&& this.Text = "Form1";
&&&&&&&&&&&&& this.ResumeLayout(false);
&&&&&&&& }
&&&&&&&&& #endregion
&&&&&&&&& private void btnPutInCache_Click(object sender, System.EventArgs e)
&&&&&&&& {
&&&&&&&&&&&&& AppMain.Cache.Insert(
&&&&&&&&&&&&&&&&&& CACHE_KEY,
&&&&&&&&&&&&&&&&&& txtValueToPutInCache.Text,
&&&&&&&&&&&&&&&&&& null,
&&&&&&&&&&&&&&&&&& Cache.NoAbsoluteExpiration,
&&&&&&&&&&&&&&&&&& TimeSpan.FromSeconds( 60 ) );
&&&&&&&& }
&&&&&&&&& private void btnGetFromButton_Click(object sender, System.EventArgs e)
&&&&&&&& {
&&&&&&&&&&&&&
&&&&&&&&&&&&& value = AppMain.Cache[ CACHE_KEY ]
&&&&&&&&&&&&& if( null == value )
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& value = "[No value in the cache.]";
&&&&&&&&&&&&& }
&&&&&&&&&&&&& txtValueInCache.Text =
&&&&&&&& }
&&&& }
}
三、windows form参数传递过程
在Windows 程序设计中参数的传递,同样也是非常的重要的。
这里主要是通过带有参数的构造函数来实现的,
说明:Form1为主窗体,包含控件:文本框textBoxFrm1,多选框checkBoxFrm1和按钮buttonEdit;&
Form2为子窗体,包含控件:文本框textBoxFrm2,多选框checkBoxFrm2和按钮buttonOK,buttonCancel。
当我们新建一个窗体的时候,设计器会生成默认的构造函数:&
&&&& public Form2()
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& InitializeComponent();
&&&&&&&&&&& }
它不带参数,既然我们要把Form1中的一些数据传到Form2中去,为什么不在Form2的构造函数里做文章呢?
假设我们要实现使Form2中的文本框显示Form1里textBoxFrm1的值,修改子窗体的构造函数:&
public Form2(string text)&&&&&&&&&
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& InitializeComponent();
&&&&&&&&&&&&&&&&&& this.textBoxFrm2.Text =&
&&&&&&&&&&& } 增加Form1中的修改按钮点击事件,处理函数如下:&
&&&& private void buttonEdit_Click(object sender, System.EventArgs e)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&& Form2 formChild = new Form2(this.textBoxFrm1.Text);
&&&&&&&&&&&&&&&&&& formChild.Show();
&&&&&&&&&&&&& }
我们把this.textBoxFrm1.Text作为参数传到子窗体构造函数,以非模式方式打开,这样打开的formChild的文本框就显示了”主窗体”文本,是不是很简单,接下来我们传一个boolean数据给子窗体。
&&&& Public Form2(string text,bool checkedValue)
&&&&&&&& {
&&&&&&&&&&&&& InitializeComponent();
&&&&&&&&&&&&& this.textBoxFrm2.Text =
&&&&&&&&&&&&& this.checkBoxFrm2.Checked = checkedV
&&&&&&&& }
private void buttonEdit_Click(object sender, System.EventArgs e)
&&&&&&&& {
&&&&&&&&&&&&& Form2 formChild = new Form2(this.textBoxFrm1.Text,this.checkBoxFrm1.Checked);
&&&&&&&&&&&&& formChild.Show();
&&&&&&&& }
跳转论坛:移动开发技术
Web前端技术
Java企业应用
编程语言技术没有更多推荐了,
不良信息举报
举报内容:
C#中可以存在全局变量和全局函数吗?
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!函数返回一个全局变量有什么好处?
写这种代码的一般都是高手(不是反话)。
都不怎么样,该用case了。
你脑子有洞?
这里演示的是全局变量的用法,你觉得挑不到毛病了,就说要用case,用不用case跟我说明的问题有半毛钱关系?
等一下用了case你还能变量命名太长了,可以用g做前缀或后缀是吧。
你这种人遇多了,别人文章写得比你好,你偏要说可是别人字写得难看,鸡毛蒜皮也要争口气。
讨论不要偏离主旨,你看你前面讨论什么是封装就已经离题了,这种讨论太低效率还容易得罪人,扯了几小时就是浪费时间。
这样写就多此一举、脱裤子放屁了,要封装就不要设全局变量,要全局变量就没必要读写函数。 ...
只要使用函数能够在内部修改实现方式,而不需要在外部全盘修改,这一个优点就够了。
你觉得不是封装,那就不是封装咯,但这绝对不是脱了裤子放屁。
这样才叫封装:
int get_flag(void)
你不知道一个项目中有很多个C文件吗?C语言里模块是指一个编译单元(也就是一个C文件);当这个C文件编译为*.o文件后,是不会导出static变量的标号的。这就是模块的封装!
而同一个模块(C文件)内部,都是同一个人设计的特定功能,可以不封装,这样更便于数据传递;如果该变量需要互斥或者保护,模块设计者最清楚了。
PS:你的头像配得好!
是这样的。刚改过来。
这个区别可大了。你误导了很多人,引起了很多不必要的口水争论。
你脑子有洞?
这里演示的是全局变量的用法,你觉得挑不到毛病了,就说要用case,用不用case跟我说明的问 ...
为什么说直接用全局变量就是新手,你自己定义的?你在哪个权威学术机构呢?
你能扯,我也能扯的。
只要使用函数能够在内部修改实现方式,而不需要在外部全盘修改,这一个优点就够了。
你觉得不是封装,那 ...
问题是,我不使用这种做法,照常规方法也一样可以实现。
一边封闭,一边开放,带有来结构复杂性是不是有点那个。
这样写的感觉是高手,毕竟全局变量不能用多了。
你不知道一个项目中有很多个C文件吗?C语言里模块是指一个编译单元(也就是一个C文件);当这个C文件编译 ...
你这么说,就是假定别人是猪,你自己最聪明,你是不会犯错的。
你又拿什么保证,别人没有需求改写你的模块文件?
假如你写的模块文件达不到别人的需求,是否只能求你啊?
谁能说说首楼做法的意义是什么?
封装?可文件里面漏洞大开;
检查数据合法性?我用常规方法也简单实现了;
防止变量被随意修改?你提供set/get不是给别人随意修改?
创建命名空间,防止变量名重复?你用函数名不重复?
最后是不是只能说,只是仿个接口,脱个裤子放屁。
rain73 发表于
谁能说说首楼做法的意义是什么?
封装?可文件里面漏洞大开;
检查数据合法性?我用常规方法也简单实现了; ...
谁能说说C++里用类(不谈继承与多态)的意义是什么?
封装?可里类面漏洞大开;
检查数据合法性?我用常规方法也简单实现了;
防止变量被随意修改?你提供set/get不是给别人随意修改?
创建命名空间,防止变量名重复?你用类名不重复?
最后是不是只能说,只是添加个语法糖,脱个裤子放屁。
我用C、C++、C#编程,你说过有没有用过别人的模块?
人家更强调的是类封装性,比这种文件模块式的封装严 ...
本来不想评论的,看你YY就想。。
1.你不明白别人讨论什么就YY,语文是体育老师教的吗
2.写出不符合的代码,别人指出还不承认,心太窄
体育老师教语文,不能要啊!!
另外111楼我不是贬C++哦。
本帖最后由 brahen 于
13:06 编辑
为什么说直接用全局变量就是新手,你自己定义的?你在哪个权威学术机构呢?
你能扯,我也能扯的。 ...
你脑子有病,又给老子扯有的没的,一股酸臭味。
谁能说说C++里用类(不谈继承与多态)的意义是什么?
封装?可里类面漏洞大开;
检查数据合法性?我用常规 ...
你抛开类的整体功能,就无从谈起了,呵呵,人家那是总体设计的。
而C就是C,你不能拿他当C++用。
你脑子有病,又给老子扯有的没的,一股酸臭味。
你82楼写的:
//小有所成
// 大彻大悟的苦逼孩子
你用什么得出这结论,有考究过程吗?
没有就是调侃。
既然你可调侃,我为什么不行呢?
本来不想评论的,看你YY就想。。
1.你不明白别人讨论什么就YY,语文是体育老师教的吗
2.写出不符合的代码 ...
我哪个代码不符合?请指出来,泼妇骂街就算了。
先学学什么是封装...
你上面说的,有300处访问变量,你怎么查找?
假如这300处访问,就是处于同一文件中 ...
前提是你的SRAM区域够大。
你抛开类的整体功能,就无从谈起了,呵呵,人家那是总体设计的。
而C就是C,你不能拿他当C++用。 ...
这些本来就到C自己的特性,与C++无关。
问题是,我不使用这种做法,照常规方法也一样可以实现。
一边封闭,一边开放,带有来结构复杂性是不是有 ...
不改变模块外部判断flag的代码,你怎么实现:
1、内存受限,需要将几个类型为uint8_t的flag聚合到一个位域时候。
2、模块代码重构,需要将散乱的变量集中到一个struct中进行管理的时候。
3、判断逻辑改变,需要同时判断A,B,C三个变量为true,或者变量a&100,b==2,flag==true,才算是true的时候。
4、存储方式改变,set flag的值需要同时将之写入到eeprom的时候。
本帖最后由 qingyin2009 于
14:34 编辑
战斗很激烈,我之前不会用这种办法的,最近在渐渐学,我觉得这种办法有两个好处:
1. 一个变量一般有两种属性:读和写:写的话,就是谁在影响它,读的话,就是它被谁依赖。如果一个变量不需要被其他模块操作,那么可以只写get函数。软件调试的时候,若一个变量不正常,我们全局搜set函数,可以清晰的看到哪个模块在影响它,全局搜get函数,就清晰的知道,此变量不正常会影响哪些模块,针对性的查找问题。
2. 统一接口:可以在set或get中做接口逻辑,限制其输入与输出值的范围。调试中,若一个变量在工程中有300次的写,若不用set函数,只能到处打断点了。还有的好处是还可以模拟状态操作,比如我把get里面的返回改为一固定值,就可以调试所有与此变量相关的模块。
假如一变量为运行状态,多处需要操作,并多处使用,调试代码的时候想知道系统若处于各个状态时的运行情况,在get里面修改返回值即可,不然要把所有的写操作注释掉才行。
不过这只是个人理解,没有那本书证明过它的正确,我不想参战,不同意也别乱喷,最讨厌有些人自以为是了
mark!慢慢看!
这明显是C语言里的 static 变量不能被其它文件使用,必须通过函数来返回
谁能说说首楼做法的意义是什么?
封装?可文件里面漏洞大开;
检查数据合法性?我用常规方法也简单实现了; ...
关于首楼做法有什么意义?
这个用 华为的编程规范 来回答一些
至于这点:有一天我们调整了内部实现,因为接口不变,所以此时不用调整外部调用的模块,
你不在乎,那我也没法说什么。
本帖子中包含更多资源
才可以下载或查看,没有帐号?
关于首楼做法有什么意义?
这个用 华为的编程规范 来回答一些
结构化编程本不就是这样吗?通过函数打交道,函数访问的并非就是全局变量,对单独的私有变量也是一样这么用的。
另一方面来说,人家这是建议,并非强制,在全局变量有诸多好处的时候,为什么不能用?
战斗很激烈,我之前不会用这种办法的,最近在渐渐学,我觉得这种办法有两个好处:
1. 一个变量一般有两种 ...
这是强行给set/get找好处吧?我不使用set/get,也没有遇到如此不济的状况。
再说你用了set/get就不用打断点了?说说是什么原理。你搜索set/get,不是跟我搜索变量名一样。
不改变模块外部判断flag的代码,你怎么实现:
1、内存受限,需要将几个类型为uint8_t的flag聚合到一个位 ...
我使用变量前,先做一下你所说的这些要求不行?或者干脆集合成一个函数,在变量使用前调用下这个函数即可。
这些个功能并非只有接口函数做得到,抛开接口函数的说法,从流程上讲两者是一模一样的。
我以上说这些,并非表示全局变量可以满天飞,总体原则就是少用、不用,在关键的地方用,比如在中断调用里,直接用
变量不比函数调用差,用变量执行的运算是固定的,如果是调用函数,可能在不经意间函数就被人为修改了,这对中断执
我使用变量前,先做一下你所说的这些要求不行?或者干脆集合成一个函数,在变量使用前调用下这个函数即可 ...
都是是要重构或者逻辑修改才导致的问题,你怎么会预测得出来,提前做修改了?
特别是第三个,你能预测出来就神了。
你觉得你的写法没问题是OK的,但你不能因为别人用了其他的写法就说是脱裤子放屁。
都是是要重构或者逻辑修改才导致的问题,你怎么会预测得出来,提前做修改了?
特别是第三个,你能预测出 ...
你不坊提出你的需求,等我有空看我写不写得出?你用接口函数能做的,我一样用常规方法来完成。
你觉得你的写法没问题是OK的,但你不能因为别人用了其他的写法就说是脱裤子放屁。 ...
你们讲封装,我就给了一个完全封装的例子。
你们讲接口,大家通常的结构化、模块化编程本来就是接口了,没什么特别的东西。
你们讲全局变量,我问问,用于中断收发的缓冲区,你们要多此一举加个set/get来访问么?
rain73 发表于
你们讲封装,我就给了一个完全封装的例子。
你们讲接口,大家通常的结构化、模块化编程本来就是接口了, ...
和你说不清楚了,我也不想再码字和你吵了,那我就俗套一点吧。
RT thread实时操作系统,在论坛有分论坛,源代码我看过一点,里面也用这种封装方法,难道他们故意找别扭?
哎,累不觉爱,大家继续。
rain73 发表于
你们讲封装,我就给了一个完全封装的例子。
你们讲接口,大家通常的结构化、模块化编程本来就是接口了, ...
另外你说说中断里为什么不能用?
另外你说说中断里为什么不能用?
用于中断收发的缓冲区,缓冲区干什么用的,就是协调速度的,你用函数去包装一通,速度能快么?
用于中断收发的缓冲区,缓冲区干什么用的,就是协调速度的,你用函数去包装一通,速度能快么? ...
这个问题已经在上面说过了,除非连一个函数调用的开销都无法支付,要不照用不误。
中断本来就特殊,代码中中断服务代码才占多少。
这是强行给set/get找好处吧?我不使用set/get,也没有遇到如此不济的状况。
再说你用了set/get就不用打断 ...
本来不想参战,你这浓浓的火药味,我依旧不愿意参战,只是表明看法,科学的问题,没必要掺杂个人情绪进来,不论你做了多少项目,没有定论的东西是不能随意指点别人的。或者说有定论的东西,你按错的来做,也不一定得不到正确的结果,如果你错了,那么只能说明你做了那么多项目,根本没有思考。我的回复是没有证据的,只是个人看法。如果你一定要指点别人的错误,那么你一定要有有力的解释或者说证据!
从A到B有无数条路,没人限制你用哪一条,所谓方法,符合标准的前提下,自己认为合理就行,没必要指点别人的好与不好。
全局变量到处飞,大工程用一个C文件,C语法不会说它错,只要执行没问题,仍然能做出来合格的产品。说白了代码若只是你和机器用,只要机器能识别,你直接写都可以。
我说的打断点的意思是,你没必要在每个变量变化的地方打断点,直接在set函数里面打断点,函数返回处就是变量在哪里被修改了。
你脑子有洞?
这里演示的是全局变量的用法,你觉得挑不到毛病了,就说要用case,用不用case跟我说明的问 ...
我就说吗?
公说公有理,婆说婆有理。
奏是感觉不对味,还是你牛,直接道出矛盾所在
本来不想参战,你这浓浓的火药味,我依旧不愿意参战,只是表明看法,科学的问题,没必要掺杂个人情绪进来 ...
你的情绪不对,我从没说这种做法是错的,也没说这种做法不行,就是质疑这种做法的具体意义,我写了具体的代码,不知道你有没有看过?
如果这种做法仅是帮你调试程序,我也有好的调试方法,不必绕个弯为测试而做这个。
我觉得你都没搞清楚我在说什么,而你就急于下结论。
就技术性讨论,千万别觉得我是故意和大家吵架。
其实最好的做法,就是写个用set/get的有说服力的代码,有比传统做法不可置否的优越性,那样我认可。
如仅仅是把一个变量传输变换一下方式,我认为没什么必要。
本帖最后由 ilcvm 于
23:53 编辑
加了set/get函数,就不会被乱更改?你说说原理。
比如说一个模块的控制参数,只有在该模块在某种状态才能更改,否则会造成控制过程混乱。所有我们用_bool setpara(int new_val)这样一个函数来实现参赛更改,不在可更改状态就返回0。虽然你也能提供一个全局变量让外部判断现在是否可更改状态,但你不能保证外面更改参数时是否有作判断。你说不用接口函数怎么保证控制变量不被不在合适时机更改更改同时更改的人能知道他的更改是否有效?
你不坊提出你的需求,等我有空看我写不写得出?你用接口函数能做的,我一样用常规方法来完成。 ...不改变模块外部判断flag的代码,你怎么实现:
3、判断逻辑改变,需要同时判断A,B,C三个变量为true,或者变量a&100,b==2,flag==true,才算是true的时候。
第三点重新描述一下:
某公司发型了一个硬件A,他的驱动被称为模块A。
模块A需要提供一个接口,用于客户的程序查询是否可以向模块A写入数据
目前有两个方式
1、提供变量接口:extern bool isAF
2、提供函数接口:extern bool IsAFree(void);
当前,逻辑是只要模块A被别的任务占用,isAFree就会变成FALSE。
外部可以使用如下两种方式判断
1、if ( isAFree ) {/*..................*/}
2、if ( IsAFree() ) {/*..................*/}
但因为硬件更新,模块A需要在它的MODE_CC接口为高电平的时候才能写入数据
结果直接判断isAFree变量的代码无法使用,A的实现者需要发布更新文档,告诉调用他模块的人,注意修改判断条件。
而调用IsAFree()接口的人,则不需要做修改,因为A的实现者只在在A模块中修改一下:
bool IsAFree(void)
& && &&&return ( isAFree&&( IsModeCC_High() ) );//用户在移植驱动的时候,已经实现了IsModeCC_High()。如果是客户用的也是同一款单片机的话,那只要修改对应的引脚宏就OK了。
当然,使用变量作为接口的A的实现者如果不想被客户的工程师碎碎念,他也可以新开任务,定时查询MODE_CC的状态,然后将至更新到flag的状态中。
但这个就不是实时的了,另外他也可以开启MODE_CC对应的外部中断去更新flag的状态,天啊为了一时的方便现在变得好麻烦啊。
然后过了一会因为调试中出现了BUG,发现还要新增一个条件,A模块所调用的子模块B也必须是free,A模块才能允许写入数据。这时候就悲催了,B模块必须要知道A
模块的flag变量,以便于及时更改flag的值。本来属于调用和被调用关系的A B模块,关系变得模糊起来,耦合度提高了,A的实现者也要和B的实现者沟通定制的事项
当我们编写一个API的时候,尽量要隐藏其内部的实现细节,毕竟关系到程序80%关键性能的仅存在于20%的地方,不要觉得别人用你的接口就一定是用到ISR里,然后将自己的代码完全按照20%的程序要求来编写。
尽量提供最少的、通用性的接口 当他真要用到ISR里,并且性能受到了影响,再来找你沟通,增加对应的特殊接口就行了。
使用变量和使用函数或者宏接口个有其优点,在一个模块内部当然是变量用得爽,但发布到模块外部使用的时候尽量使用函数OR宏接口的方式,用封装来隐藏内部实现细节。
除非碰到特殊情况:性能有要求、想偷懒的时候、个人项目、小组内部项目、不在乎的项目……
没必要极端到一用变量,那就通盘全局变量到处飞,没一个地方用接口函数的。或者一用接口函数,就算模块内部都完全不用变量,统一使用&接口&函数。我们不是这么有洁癖的人对吧?
这种变量的作用域是所在文件,文件模式封装模块化,便于多人合作项目!
码农何苦为难码农
比如说一个模块的控制参数,只有在该模块在某种状态才能更改,否则会造成控制过程混乱。所有我们用_bool&&...
这本来就是函数干的事啊,你不是认为我在模块中只能使用全局变量,而不能使用函数吧?那样还编什么程啊。
我的意思是,仅仅为了一个变量的读写而设set/get函数,就像一楼写的那样,如果函数是一堆逻辑处理,那就
是普通的函数了。
第三点重新描述一下:
某公司发型了一个硬件A,他的驱动被称为模块A。
模块A需要提供一个接口,用于客户 ...
看了好大一会,才基本明白你的意思。
用变量接口:extern bool isAFree,在模块A的内部,必然要有一个更新全局变量isAFree状态的函数(轮循、中断或OS任务),
在这个更新状态的函数中加入MODE_CC电平检查和B模块的状态检查,就完成了和你接口函数一样的功能。
你可能要说没有这个更新函数,没有的话isAFree变量不就是个摆设?根本就用不了。
看了好大一会,才基本明白你的意思。
用变量接口:extern bool isAFree,在模块A的内部,必然要有一个更 ...
好厉害,舌战群雄
这样才叫封装:
int get_flag(void)
你这样&&怎么设置这个标志呢?
本帖最后由 ilcvm 于
10:00 编辑
这本来就是函数干的事啊,你不是认为我在模块中只能使用全局变量,而不能使用函数吧?那样还编什么程啊。 ...
一楼的是只有get好吗?这样写对文件外的函数是这个变量是只读,文件内的函数可读写,这种写法在很多情况下是有需求的。
本帖最后由 rain73 于
10:41 编辑
一楼的是只有get好吗?原来你硬是塞给人家一个set函数然后说人家脱裤子放屁,呵呵。这样写对文件外的函数 ...
一楼原来那个外部变量,连static都是没有的,是个public,后来改了吧。
就算是如此,文件内就不怕全局变量满天飞,文件外就怕了?跟踪能力大概就如此了吧。
再者,不少人就提倡set/get对的,这样能防止别人乱修改?
如果一个变量本来就要求readonly,C没有健全的保护机制,只能用变量复制方式,那自然要用到函数来做。
而现在是,你看到一个全局变量,就下意识的要加重函数保护,不去考虑全局变量的便利性。
在我看来,结构化、模块化的程序设计才是重点,的确需要全局变量、或者有很大的便利性,用全局变量也
不是什么见不得人的事,原则就是不滥用、少用。
类似的问题还有一个,就是指针,指针乱飞比全局变量乱飞可怕N倍,要如可处理,考虑封装指针吗?
你这样&&怎么设置这个标志呢?
参考84楼。
看了好大一会,才基本明白你的意思。
用变量接口:extern bool isAFree,在模块A的内部,必然要有一个更 ...
我的回帖里就是有类似更新函数的描述,你没有回答我的问题,我不认为使用更新函数的效果等同于在函数接口中判断!
毕竟,很多时候引起flag改变的条件的改变不一定能触发isr对它进行处理(所以将更新函数丢到ISR里不一定能处理所谓的情况),
而你用任务周期查询这个就谈不上实时性了,或者说无法兼顾实时性和低功耗。
这本来就是函数干的事啊,你不是认为我在模块中只能使用全局变量,而不能使用函数吧?那样还编什么程啊。 ...仅仅为了一个变量的读写而设set/get函数,就像一楼写的那样
为这个变量编写set get接口是为了隐藏实现。
现在的需求是一个flag就能解决问题,但将来不一定。没必要让你的模块使用者去理解这些东西,所以提供一个set/get函数更有通用性。、
特殊情况,如142L里说的那一样就例外。
本帖最后由 ilcvm 于
11:32 编辑
文件内就不怕全局变量满天飞,文件外就怕了?..
因为有些变量只需要在模块内很有限的地方被更改,但会被模块外很多地方读取,如系统tick变量。直接用全局变量的话,一旦发现被乱动了你可能需要检查几百个地方,尤其是C语音这种语法比较灵活的语言,检查起来很费事,用get函数的话检查会容易得多。但如果这个变量只被几个地方读写,或者你整个工程才三两个文件,不到千行代码,那自然没这必要。另外,没人说全局变量必然不能用,只是说使用接口函数在很多场合有好处
楼层挺高,没有一一看完。看到些上来就说这是没有意义的,只能说它对应的场景的。
如编写闭源的库,或是多人合作项目,那么要做参数检查、访问控制,我不能预设用户能力较高。
至于称谓,用“封装”这个词,我理解它的意思,而我统称API。
说起封装,我想到了一个办法,看看怎么样:
在module.c中:
int func(bool set, int param) {
这种办法 也是可以的,用参数 去设置或是取得 这个变量的值
我的回帖里就是有类似更新函数的描述,你没有回答我的问题,我不认为使用更新函数的效果等同于在函数接口 ...
我已经认真地回答了,如果没有涉及的地方,那是我真的没有看懂,你的描述读起来有些晦涩难懂。
如果设计不了更新机制,那用全局变量传输不是个废物?设计之初就应该换其它方法。有些不解的
是,连内部的更新机制都做不到,外部的调用就可以做到?怎么说也是内部的优先级高啊。
为这个变量编写set get接口是为了隐藏实现。
现在的需求是一个flag就能解决问题,但将来不一定。没必要 ...
本来就一个数据传输通道,用set/get也是如此,使用者只要收或发数据,怎么会去揣摩怎么实现?
这种办法 也是可以的,用参数 去设置或是取得 这个变量的值
其实这种方法效率挺低,尤其是对于arm这类有流水线的,条件语句的开销往往比跳转大
因为有些变量只需要在模块内很有限的地方被更改,但会被模块外很多地方读取,如系统tick变量。直接用全局 ...
明白你的意思,直白说就是为了保护变量,如果有变量保护需求,自然不会直接提供这个变量出去,肯定会设计保护方法。
但更多的可能是变量不需要保护,或者要双向传输。
其实这种方法效率挺低,尤其是对于arm这类有流水线的,条件语句的开销往往比跳转大 ...
底层 也不会这样做吧 这只是应用层 才这样做
底层 也不会这样做吧 这只是应用层 才这样做
其实就是把一个模块封装在一个函数里,模块很小的话可以,但大了读起来就有点累赘
其实这种方法效率挺低,尤其是对于arm这类有流水线的,条件语句的开销往往比跳转大 ...
这种情况,不好讲效率吧?
我的想法中,就是说全局变量效率高,没必要套个set/get。
本帖最后由 ilcvm 于
12:03 编辑
这种情况,不好讲效率吧?
我的想法中,就是说全局变量效率高,没必要套个set/get。 ...
效率和保护程度之间的平衡点要看实际场合,没有什么方法是无论放在什么场合都是最合适的。写程序的了解清楚各种方法的优缺点即可,即使是goto也不是哪里都不应该用的
我觉得,既然用C了,就用C的特性去做好事情,结构化模块化是重点。
用C去模拟C++的特性,不好说,看过傻孩子的用C做继承,真是恐怖...
本帖最后由 chencc8 于
13:07 编辑
我已经认真地回答了,如果没有涉及的地方,那是我真的没有看懂,你的描述读起来有些晦涩难懂。
如果设计 ...
在外部调用接口函数的时候,在接口函数内部当场判断就OK了,无需做更新函数。
调用函数的时候的状态就是当前的实际状态,而不是通过更新函数获取的之前的状态。
同时,就算内部改写代码,改成使用更新函数来更新状态,而不是在外部询问状态的时候才判断,也不会影响到外部调用的方式。
编辑增加:最后,使用函数接口的方式,还可以方便的在调用接口的时候,添加带有副作用的调试信息,比i如通知内部或者打印数据
rain73 发表于
我觉得,既然用C了,就用C的特性去做好事情,结构化模块化是重点。
用C去模拟C++的特性,不好说,看过傻孩 ...
傻孩子的做法或许会吓退一堆人,但其实面向对象思想可以更直接,就像rt-thread那样,较直观点,就是之前我讲的,用适当的开销,来有效降低软件复杂度,是可取的。
另外,我们不指望每个人都有你的领悟力,更希望通过推广使用多数人认可的技术(就像之前我说的,包括华为,也是建议这么做,人家肯定不是随便建议的),来降低团队协作开发难度。
我觉得这场辩论,不会有结果了,路在脚下,大家自己各自选择吧,回家洗洗睡了。
防止堆栈溢出,其实返回全局变量神马的,多线程就挂了…
本帖最后由 rain73 于
18:10 编辑
在外部调用接口函数的时候,在接口函数内部当场判断就OK了,无需做更新函数。
调用函数的时候的状态就是 ...
我觉得这样的设计有问题,当多个条件符合后,综合得到一个就绪信号告知外部,难道就绪等待的过程中,状态又忽然改
变了?如果是这样,外部调用也是不可靠的,当检测的时候是就绪的,然后正要发数据过去了,你内部状态又变了!
从另一方面说,通过接口传输数据,必然是异步的,在这个过程中程序可能会等待、会被中断,你所谓“当前状态”的说法,
其实也可能是过去的状态。
傻孩子的做法或许会吓退一堆人,但其实面向对象思想可以更直接,就像rt-thread那样,较直观点,就是之前 ...
其实接口这种东西,大家都会、都在做了,你把程序按文件分类,然后通过头文件声明公共函数,这已经是接口了。
通过这个接口,可以输入数据,输出结果,这个过程可以交换绝大多数的数据,可以不需要公有变量,这就是结构
我不知道大家为什么会觉得首楼的做法很新鲜、没做过,这不是你天天在做的吗?任何C的结构化教程不都是这样。
唯一不同的地方,就是去掉了逻辑结构,仅仅把一个变量通过接口呈现出来,所以觉得新奇。事实上在编程过程中,
这样仅呈现一个变量的用法不多,这个变量在通常的功能函数中,已经包括进输入输出数据中了。
而确实需要全局变量的地方,是为了便利性、高效率而设的,不会是一般数据,把这种变量用函数去包装,我一直
都认为没必要的。
在外部调用接口函数的时候,在接口函数内部当场判断就OK了,无需做更新函数。
调用函数的时候的状态就是 ...
其实,想懂得人在你列出4点应用场景的时候就懂了,也能体会到其中的好处。而不想懂得人,你是说服不了他们的。
我觉得C模块的接口有两种:一种是变量,一种是函数
不是说放弃一种,只使用一种就是叫封装的好
在嵌入式系统中往往效率和代码空间都是比较重要的,没必要为了封装而封装
当然有些人喜欢这样也无可厚非,每个人的习惯不同
为了舌战群熊而舌战群熊。。。。
学习了。。。。
MARK,全局变量的讨论
对比LZ提供的代码和C#中的类,个人体会 .C文件中类似于C#中的类,.C文件中的静态全局变量类似于C#类中的字段(private修饰),加上set和get后(public修饰)类似于C#中的属性。
在C#中的字段在整个类中也是可操作的即对内的,属性是对外的
阿莫电子论坛, 原"中国电子开发网"
, 原www.ourdev.cn, 原www.ouravr.com

我要回帖

更多关于 js函数给全局变量赋值 的文章

 

随机推荐