static修饰函数和变量

static修饰符是一个能够减少此类命名冲突的有用工具。例如,以下声明语句

static int a;

其含义与下面的语句相同

int a;

只不过,a的作用域限制在一个源文件内,对于其他源文件,a是不可见的。因此,如果若干个函数需要共享一组外部对象,可以将这些函数放到一个源文件中,把它们需要用到的对象也都在同一个源文件中以static修饰符声明。

static修饰符不仅适用于变量,也适用于函数。如果函数f需要调用另一个函数g,而且只有函数f需要调用函数g,我们可以把函数f与函数g都放到同一个源文件中,并且声明函数gstatic

static int

g(int x)

{

 

}

void f() {

 

b=g (a);

}

我们可以在多个源文件中定义同名的函数g,只要所有的函数g都被定义为static,或者仅仅只有其中一个函数g不是static o因此,为了避免可能出现的命名冲突,如果一个函数仅仅被同一个源文件中的其他函数调用,我们就应该声明该函数为static

 

static函数

在C语言编程中,static的一个作用是信息屏蔽!
比方说,你自己定义了一个文件 -- 该文件中有一系列的函数以及变量的声明和定义!
你希望该文件中的一些函数和变量只能被该文件中的函数使用,那么,你可以在该函数、变量的前面加上static,代表他们只能被当前文件中的函数使用!

而在C++中,用static来作为信息屏蔽就显得没有必要了!因为,C++有了信息屏蔽的利器 -- class机制!

类中的private属性的变量和函数就对外禁止访问!

然后是C/C++通用的函数作用域的static型的变量!其目的,也是为了信息的屏蔽!
int fun() {
   static int 1;
   a++;
}
在第一次进入这个函数的时候,变量a被初始化为1!并接着自增1!

以后每次进入该函数,a就不会被再次初始化了,仅进行自增1的操作!

在static发明前,要达到同样的功能,则只能使用全局变量:

int 1;

int fun() {
   a++;
}
那么,a的值就有可能被其他函数所改变!

最后,说说类中的static变量和函数。

这种存储属性的变量和函数是同一种类的不同实例之间通信的桥梁!
#include <iostream>
using namespace std;

class {
public:
    static int num;    //    统计创建了多少个实例
    () {num++};    //    每创建一个实例,就让num自增1

    //    返回通过构造函数所创建过的A类实例的数目
    static int how_many_instance() {
        return num;
    }
}

static A::num 0;    //    需要在类申明的外部单独初始化!

int main() {
    cout << A::how_many_instance() << endl;
    a, b, c, d;
    cout << A::how_many_instance() << endl;
    system("pause");
}

一般,在类内部,是通过static属性的函数,访问static属性的变量! 
Q. How does static local variable works in C/C++?
A: Local static variable is persistent between function calls. It is not supposed to be destructed at the end of function. 
See the following example. 
#include<iostream>
using namespace std;
class Apple 
public:
    Apple(int,int);
    void addSize(int m) {size += m;}
    void printApple() cout<<"The Apple is "<<size<<" and "<<type<<"."<<endl;}
    ~Apple();
  private:
    int size;
    int type;
};
Apple::Apple(int s,int t){ 
  size=s;
  type=t;
}
Apple::~Apple(){ 
  printApple();
}
void testStatic(){ 
  static Apple a2(20,6);
  a2.addSize(10);
  a2.printApple();
}
int main() {
  testStatic(); //The Apple is 30 and 6.
  testStatic(); //The Apple is 40 and 6.
  return 0;
}

You see!!! testSatic() has been called twice, and the addSize(10) effect accumulated.
Note: There is local static variable in Java. 
Q. What does static function mean in C? Can you give an example?
A: static function is only visible by the file itself.
If you include static function in header file, you much include its body to make the function usable. See the following example, sum1() is static, sum2 is not, notice the code differences. 
//=======
//aa.h
#ifndef AA_H
#define AA_H
int sum2(int a, int b);
static int sum1(int a, int b);
int sum1(int a, int b) 
  return a+sum2(b, 10);
}
#endif
//=======
//aa.c
#include "aa.h"
int sum2(int a, int b) 
  return a+b;
}
//=======
//test.c
#include "aa.h"
int main() {
  printf("%d\n", sum1(3,4)); //17
  printf("%d\n", sum2(9,4)); //13
}
//=======
Read more from here:

http://bobcat.webappcabaret.net/javachina/faq/cpp_01.htm#cpp_static_ttl 
补充一点,在类中,static型的成员函数,由于是类所拥有的,而不是具体对象所有的,这一点对于windows的回调机制非常有用。
因为对于回调函数而言,windows不会借助任何对象去调用它,也就不会传递this指针,那么对于一般成员函数作为回调函数的后果,就是堆栈中有一个随机的变量会成为this指针,这当然会引发程序的崩溃。
而static函数,由于是整个类的,屏蔽了this指针。因此,如果成员函数作为回调函数,就应该用static去修饰它。

原文地址:http://blog.sina.com.cn/s/blog_40e9d4dd01009xfm.html

<think>嗯,用户让我介绍一下局部变量、全局变量,还有各种static修饰变量函数之间的关系区别。这个问题看起来是关于C语言变量函数的作用域生命周期的,可能用户在学习编程时遇到了相关概念混淆的情况。我需要先回忆这些概念,然后组织成一个清晰的解释结构。 首先,局部变量应该是在函数内部定义的变量,作用域仅限于该函数内部,生命周期在函数调用时创建,结束时销毁。而全局变量则是在所有函数之外定义的,作用域从定义处开始到文件结束,生命周期是整个程序运行期间。接下来是static修饰的局部变量,虽然作用域还是局部,但生命周期会被延长到整个程序运行期间,也就是只会初始化一次,每次函数调用时保持之前的值。而static修饰的全局变量,作用域会被限制在当前文件内,其他文件无法访问,这应该普通的全局变量不同,普通的全局变量是可以通过extern在其他文件中使用的。static修饰函数也是类似的,作用域仅限于本文件,防止被其他文件调用。 接下来要考虑用户可能的疑问点。比如,static在不同上下文中的不同作用,比如修饰局部变量时改变的是生命周期,而修饰全局变量函数时改变的是链接属性。还有普通函数static函数的区别,是否可以被其他文件访问。需要把这些对比点列出来,可能需要用例子来说明。 用户可能是刚开始学习C语言,对static关键字的多重用法感到困惑。需要明确区分不同情况下static的作用,避免混淆。同时,用户可能需要实际应用中的例子来理解这些概念,比如在多个文件项目中如何控制变量函数的可见性。 另外,需要注意回答的结构,按照用户的要求分点说明,先介绍每个概念,再对比区别,最后总结关系。可能需要用表格来对比,但用户要求使用中文,并且可能更倾向于简洁的列表形式。 还要检查是否存在理解错误,比如static局部变量是否真的只在第一次初始化,之后保持值不变。例如,在函数内部定义static int count = 0; 每次调用时count会保留上次的值,而普通局部变量每次都会重新初始化为0。这个例子可以帮助用户理解。 总结下来,回答的结构应该是: 1. 基本概念分点介绍 2. 对比区别(作用域、生命周期、链接属性) 3. 关系总结(static如何影响不同变量/函数) 4. 示例说明 需要确保每个部分都清晰,避免术语混淆,用简单的中文表达。同时注意用户可能对链接属性不太熟悉,需要适当解释。比如,普通全局变量具有外部链接,而static全局变量是内部链接,只能在当前文件访问。函数同理。 最后,检查是否有遗漏点,比如static修饰函数的情况是否覆盖,是否提到存储位置(比如全局变量static变量在静态存储区,而普通局部变量在栈区),这可能有助于理解生命周期的问题。不过用户可能更关注逻辑上的区别,而不是底层实现,所以需要根据情况决定是否提及。 现在,把这些整理成一个连贯的回答,确保符合用户的要求,分点明确,使用例子,对比清晰,并且用中文自然表达。</think>好的,我将用分点对比的方式为您梳理这些概念的关系与区别,并附上示例帮助理解: --- ### 一、基本概念对比表 | 类型 | 作用域 | 生命周期 | 链接属性 | 存储位置 | |---------------------|----------------------|------------------|-----------------|---------| | 局部变量 | 所在代码块内 | 代码块结束时销毁 | 无链接 | 栈区 | | static局部变量 | 所在代码块内 | 程序结束时销毁 | 无链接 | 静态区 | | 全局变量 | 整个程序(需extern引用) | 程序结束时销毁 | 外部链接 | 静态区 | | static全局变量 | 当前源文件内 | 程序结束时销毁 | 内部链接 | 静态区 | | 普通函数 | 整个程序(需extern引用) | 程序结束时销毁 | 外部链接 | 代码区 | | static函数 | 当前源文件内 | 程序结束时销毁 | 内部链接 | 代码区 | --- ### 二、详细说明与示例 #### 1. 局部变量 vs static局部变量 ```c void func() { int a = 0; // 普通局部变量 static int b = 0; // static局部变量 a++; b++; printf("a=%d, b=%d\n", a, b); } // 调用3次输出: // a=1, b=1 // a=1, b=2 // a=1, b=3 ``` - **核心区别**:static局部变量只会初始化一次,且生命周期持续到程序结束 #### 2. 全局变量 vs static全局变量 ```c // file1.c int global_var = 10; // 普通全局变量 static int static_global = 20; // static全局变量 // file2.c extern int global_var; // 正确,可以访问 extern int static_global; // 链接错误!无法访问 ``` - **核心区别**:static全局变量仅限本文件使用,避免多文件命名冲突 #### 3. 普通函数 vs static函数 ```c // file1.c void normal_func() {} // 普通函数 static void static_func() {} // static函数 // file2.c extern void normal_func(); // 正确,可以调用 extern void static_func(); // 链接错误!无法调用 ``` - **核心区别**:static函数只能在本文件内调用,实现模块化封装 --- ### 三、关键区别总结 1. **作用域控制**: - static修饰全局变量/函数:限制作用域到当前文件 - 未static修饰:具有外部链接性(跨文件访问需extern声明) 2. **生命周期控制**: - static修饰局部变量:将栈区变量变为静态存储,生命周期延长 - 普通局部变量:随代码块结束销毁 3. **设计意义**: - static用于实现封装:隐藏内部实现细节(面向对象思想雏形) - 防止命名污染:static全局变量/函数避免多文件同名冲突 --- ### 四、关系图示 ``` 程序内存布局 ├─ 静态存储区(全局变量static变量) ├─ 栈区(普通局部变量) └─ 代码区(函数体) static关键字作用: 修饰局部变量 → 改变存储位置生命周期 修饰全局变量/函数 → 改变链接属性 ``` 建议在实际项目中多用static修饰文件内私有变量/函数,这是实现模块化开发的重要技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值