Chinaunix首页 | 论坛 | 博客
  • 博客访问: 914493
  • 博文数量: 119
  • 博客积分: 2493
  • 博客等级: 大尉
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 14:00
文章分类

全部博文(119)

文章存档

2013年(19)

2012年(100)

分类: LINUX

2012-09-10 19:25:35

static的用法可以概括为如下三个问题:
1,static函数和普通函数有什么区别?
2,static全局变量和普通全局变量有什么区别?
3,static局部变量和普通局部变量有什么区别?


上面这个三个问题也恰好反映了static三个修饰对象,函数,全局变量
和局部变量。

---------------------------------------------------------------------
一,static函数和普通函数有什么区别?(static主要用来限制作用域)
      C语言中函数有内部函数和外部函数之分。内部函数只能被在本文件
内调用,也就是函数的作用域被指定了。而外部函数是没有指定作用域的。
如果函数什么都没有加,也就是默认情况下是外部函数。

在内核里面有很多函数只供内部使用,故可以将其声明为内部函数,而供外
部提供接口的函数就不用声明为内部函数。例如:内核红黑树的实现。

左旋,右旋的实现就是供内部使用的。声明为内部函数。

  1. static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
  2. static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
而插入操作是向外部提供接口,故是外部函数。
  1. void rb_insert_color(struct rb_node *node, struct rb_root *root)

必要的时候声明为内部函数有什么好处呢?
1,可以避免重命名的问题。
      内核代码这么多,很容易就遇到了重命名问题,如果声明为内部函数
即使出现重命名,编译器也不会报错。
2,可以提高代码的健壮性。
     有些内部函数指定了作用域相对于对外是透明的,外面就调用不了。
所以可以避免代码的错宗复杂引发的错误。

例如:

file1.c:

  1. #include <stdio.h>

  2. static void hello1(void);
  3. static void hello2(void);

  4. static void hello1(void)
  5. {
  6.     printf("aaaaaaaaa\n");
  7. }

  8. static void hello2(void)
  9. {
  10.     printf("cccccccc\n");
  11. }

  12. int main(void)
  13. {
  14.     hello1();
  15.     hello2();
  16.     return 0;
  17. }
file2.c
  1. #include <stdio.h>

  2. static void hello2(void);

  3. static void hello2(void)
  4. {
  5.     printf("bbbbbbbbbbb\n");
  6. }
将这两个文件放在一起编译也不会出错,尽管有函数重名,但使用static限制了作用域。
----------------------------------------------------------------------
二,static全局变量和普通全局变量有什么区别?(static主要用来限制作用域)
     假如现在在一个文件里面定义了一个全局变量,要在另外一个文件里面引用。
该如何引用呢?static修饰的全局变量在别的文件是不可见的,而在本文件是可见
的,这和static修饰函数的作用差不多,可以见上面的例题。
  
    全局变量的空间的开辟在静态区,加static修饰后仍然在静态区。唯一有变化的
就是作用域,加static作用域限定在本文件,不加static的全居变量作用域为整个
源程序。
 
   用static修饰的变量位于静态区,那静态区又在哪儿呢?我也没有确定的答案。
个人看法,静态区=数据段+BSS段,静态区主要用来区分栈的。


  1. #include <stdio.h>

  2. static int k = 9;//----->数据段(静态区)
  3. static int h;//--------->BSS(静态区)

  4. int main(void)
  5. {
  6.     static int i = 1;//-------->数据段(静态区)
  7.     int j = 2;//-------->栈上。
  8.     printf("addr of main = %p\n",main);
  9.     printf("addr of i = %p\n",&i);
  10.     printf("(begin stack)addr of j = %p\n",&j);
  11.     printf("addr of k = %p\n",&k);
  12.     printf("addr of h = %p\n",&h);
  13.     
  14.     return 0;
  15. }
用户态内存示意图:


------------------------------------------------------------------------
三,static局部变量和普通局部变量有什么区别?(主要用于设置存储属性的)
   普通局部变量随函数的调用而开辟空间,随函数执行完而释放空间。
而static局部变量不会,它的值始终存在,static局部变量只被初始化一次,
下次使用的依然是上一次的值。

---------------------------------------------------------------------------------------------
阅读(1575) | 评论(0) | 转发(1) |
0

上一篇:函数指针

下一篇:const

给主人留下些什么吧!~~