【static&extern,有心得】staitc在C中,修饰函数.(让我明白了,在include该文件后,则该文件的static也可见了)
2015-10-05 20:40
501 查看
链接:http://blog.sina.com.cn/s/blog_4f8ea2ef0100y8d3.html
我的笔记:
1)static 终于搞明白了,#include (“预处理” 命令)进来的就相当于文件内的!
看到有人在 .h 文件里既声明又定义 static 函数,很疑惑还专门问了他
2)关于 .h 和 .cpp 文件的纠葛
// test.c
void test() {
printf("123\n");
}
// main.c
(extern) void test();
int main() {
test();
return 0;
}
这个例子里面,即使没有 test.h,也能编译链接通过,对于 .h 文件发挥的作用更加清晰了!
static函数(也叫内部函数)
只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。区别于一般的非静态函数(外部函数)
static 在 c 里面可以用来修饰变量,也可以用来修饰函数。
先看用来修饰变量的时候。变量在 c 里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不包含对,不要弄混。
static 对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多 .c 文件构成。彼此可以互相引用变量,但加入 static 修饰之后,只能被本文件中函数引用此变量。
static 对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由 OS 管理,在退栈的过程中,栈变量的生命也就结束了。但加入 static 修饰之后,变量已经不在存储在栈中,而是和全局变量一起存储。同时,离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。
static 对函数的修饰与对全局变量的修饰相似,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。
static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
我的笔记:
1)static 终于搞明白了,#include (“预处理” 命令)进来的就相当于文件内的!
看到有人在 .h 文件里既声明又定义 static 函数,很疑惑还专门问了他
2)关于 .h 和 .cpp 文件的纠葛
// test.c
void test() {
printf("123\n");
}
// main.c
(extern) void test();
int main() {
test();
return 0;
}
这个例子里面,即使没有 test.h,也能编译链接通过,对于 .h 文件发挥的作用更加清晰了!
static函数(也叫内部函数)
只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。区别于一般的非静态函数(外部函数)
static 在 c 里面可以用来修饰变量,也可以用来修饰函数。
先看用来修饰变量的时候。变量在 c 里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不包含对,不要弄混。
int a ; main() { int b; int* c= (int*)malloc(sizeof(int)); }a 是全局变量,b 是栈变量,c 是堆变量。
static 对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多 .c 文件构成。彼此可以互相引用变量,但加入 static 修饰之后,只能被本文件中函数引用此变量。
static 对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由 OS 管理,在退栈的过程中,栈变量的生命也就结束了。但加入 static 修饰之后,变量已经不在存储在栈中,而是和全局变量一起存储。同时,离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用,而且保存了前次被调用后留下的值。
static 对函数的修饰与对全局变量的修饰相似,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。
static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
// test.h static void test();---
// test.c #include "test.h" #include <stdio.h> #include <stdlib.h> static void test() { printf("test....\n"); }---
// main.c #include <stdio.h> #include <stdlib.h> #include "test.h" int main(int argc, char *argv[]) { test(); // 如果去掉这个调用程序将可以编译,相当于只申明了一个静态函数,没有使用它的话不会去找它的实现, // 如果不去掉它, 将无法编译通过,因为静态函数的生命期是本 main.c 文件,而在此文件中找不到 test() 的实现。 // 如果在此要调用 test(), 必须将 test.c 中的 test() 实现移到 main.c or test.h //这也就是为什么将 定义和实现分开的原因 system("PAUSE"); return 0; }--EOF--
相关文章推荐
- 2014 Asia Shanghai Regional Contest J
- 矩阵快速幂 CodeForces - 582B Once Again...
- codeforces 583B B. Once Again...(dp)
- HDU 4810 Wall Painting(组合数学)
- LightOJ 1282 Leading and Trailing
- Codeforces Round #323 (Div. 1) B. Once Again... 最长非严格递增子序列
- 搭建hibernate时 'hibernate.dialect' must be set when no Connection available错误
- testlink和maints的集成
- Codeforces Round #323 (Div. 2) D. Once Again... 暴力+最长非递减子序列
- maints使用
- codeforces 583 D. Once Again... (LIS + 贪心)
- [CareerCup] 10.3 Integer not Contain in the File 文件中不包含的数
- 1236 - Pairs Forming LCM (唯一分解定理加组合数学)
- 端口状态说明 LISTENING、ESTABLISHED、TIME_WAIT及CLOSE_WAIT
- Codeforces Round #323 (Div. 1) B. Once Again...
- coreseek windows下服务 FATAL: Tokenizer initialization failure 解决办法
- 嵌套的 CONTAINING_RECORD 宏
- 详细分析CONTAINING_RECORD宏
- ListEntry 链表图解,及解析 InsertTailList & RemoveHeadList&RemoveEntryList函数
- Codeforces Round #323 (Div. 1) B. Once Again... (最长不下降序列_DP)