如何判断函数中的变量是全局变量和局部变量还是局部变量

JavaScript中作用域与局部作用域有什么区别?怎样声明全局变量?如何初始化变量生命周期?
发布日期: 15:40
JavaScript教程
JavaScript作用域
JavaScript变量生命周期
本章我们主要学习JavaScript中作用域与局部作用域、全局变量及变量生命周期,下面我们就做一下具体讲解,希望大家多多支持中国站长网络学院。
作用域可访问变量的集合。JavaScript 作用域在 JavaScript 中, 对象和函数同样也是变量。在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。JavaScript 函数作用域: 作用域在函数内修改。JavaScript 局部作用域变量在函数内声明,变量为局部作用域。局部变量:只能在函数内部访问。实例// 此处不能调用 carName 变量function myFunction() {&&& var carName = &Volvo&;&&& // 函数内可调用 carName 变量}因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量。局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁。 JavaScript 全局变量变量在函数外定义,即为全局变量。全局变量有 全局作用域: 网页中所有脚本和函数均可使用。&实例var carName = & Volvo&;// 此处可调用 carName 变量function myFunction() {&&& // 函数内可调用 carName 变量 }如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。以下实例中 carName 在函数内,但是为全局变量。实例// 此处可调用 carName 变量function myFunction() {&&& carName = &Volvo&;&&& // 此处可调用 carName 变量} JavaScript 变量生命周期JavaScript 变量生命周期在它声明时初始化。局部变量在函数执行完毕后销毁。全局变量在页面关闭后销毁。函数参数函数参数只在函数内起作用,是局部变量。HTML 中的全局变量在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。实例//此处可使用 window.carNamefunction myFunction() {&&& carName = &Volvo&;}你知道吗?你的全局变量,或者函数,可以覆盖 window 对象的变量或者函数。局部变量,包括 window 对象可以覆盖全局变量和函数。
(window.slotbydup = window.slotbydup || []).push({
id: '1063561',
container: s,
size: '230,230',
display: 'inlay-fix'
JavaScript 是 Web 的编程语言。所有现代的 HTML 页面都使用 JavaScript。JavaScript 非常容易学。JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。本教程将教你学习从初级到高级JavaScript知识。
免责声明:以上教程信息由会员自行搜集、整理、发布,内容的真实性、准确性和合法性由发布会员负责。站长学院对此不承担任何责任。iOS开发学习(15)之C语言 全局变量和局部变量 - 简书
iOS开发学习(15)之C语言 全局变量和局部变量
一、变量作用域基本概念
1.1变量作用域:
变量的可用范围
1.2按照作用域的不同,变量可以分为:
局部变量和全局变量
1.3局部变量(1)定义在函数内部的变量以及函数的形参称为局部变量(2)作用域:从定义哪一行开始直到与其所在的代码块结束(3)生命周期:从程序运行到定义哪一行开始分配存储空间到程序离开该变量所在的作用域
特点:(1)相同作用域内不可以定义同名变量(2)不同作用范围可以定义同名变量,内部作用域的变量会覆盖外部作用域的变量
1.4全局变量
(1)定义在函数外边的变量称为全局变量
(2)作用域范围:从定义哪行开始直到文件结尾
(3)生命周期:程序一启动就会分配存储空间,直到程序结束
(4)存储位置:静态存储区
多个同名的全局变量指向同一块存储空间
int a = 10;
int b, c = 20;
int sum(int v1, int v2)
return v1 + v2;
void test()
printf("a = %d, num = %d\n", a, num);
int main(int argc, const char * argv[])
int value = 20;
二、static和extern关键字-对变量的作用
2.1static 与 extern对局部变量的作用
static对局部变量的作用(1)延长局部变量的生命周期,从程序启动到程序退出,但是它并没有改变变量的作用域(2)定义变量的代码在整个程序运行期间仅仅会执行一次
extern用在函数内部(1)不是定义局部变量,它用在函数内部是声明一个全局变量
2.2static 全局变量的作用
全局变量分类:(1)内部变量:只能在本文件中访问的变量(2)外部变量:可以在其他文件中访问的变量,默认所有全局变量都是外部变量
static对全局变量的作用(1)声明一个内部变量(2)定义一个内部变量 static int a = 10;
由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以 避免在其它源文件中引起错误。
2.3extern对全局变量的作用
extern作用(1)完整声明一个外部变量(2)完整定义一个外部变量 extern int a = 10;
注意:(1)如果声明的时候没有写extern那系统会自动定义这个变量,并将其初始化为0(2)如果声明的时候写extern了,那系统不会自动定义这个变量。
三、static和extern关键字-对函数的作用
3.1static 与 extern对函数的作用(1)内部函数:只能在本文件中访问的函数(2)外部函数:可以在本文件中以及其他的文件中访问的函数(3)默认情况下所有的函数都是外部函数
3.2static 作用
(1)声明一个内部函数static int sum(int num1,int num2);
(2)定义一个内部函数
static int sum(int num1,int num2){return num1 + num2;}
3.3extern作用
(1)声明一个外部函数extern int sum(int num1,int num2);
(2)定义一个外部函数extern int sum(int num1,int num2){return num1 + num2;}
四、预处理指令基本概念
4.1预处理指令的概念
(1)C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译
(2)为了区分预处理指令和一般的C语句,所有预处理指令都以符号“#”开头,并且结尾不用分号
(3)预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件
(4)C语言?供了多种预处理功能,如宏定义、文件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。本章介绍常用的几种预处理 功能
预处理1-1.jpg
预处理1-2.png
五、宏定义
5.1宏的概念及定义方法(1)被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。(2)宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。在C语言中,“宏”分为有参数和无参数两种。本节讨论无参数宏。
5.2.不带参数的宏定义
格式:define 标识符 字符串
其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。
#include &stdio.h&
// 源程序中所有的宏名PI在编译预处理的时候都会被3.14所代替
#define PI 3.14
// 根据圆的半径计radius算周长
float girth(float radius) {
return 2 * PI *
int main ()
float g = girth(2);
printf("周长为:%f", g);
注意:(1)宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误(2)对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作
#define R 10
int main ()
char *s = "Radio"; // 在第1行定义了一个叫R的宏,但是第4行中"Radio"里面的'R'并不会被替换成10
(3)在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查
示例:#define I 100
int main ()
int i[3] = I;
(4)宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令
示例:#define PI 3.14
int main ()
printf("%f", PI);
void test()
printf("%f", PI); // 不能使用
六、条件编译基本概念
6.1条件编译基本概念 在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译。6.2为什么要使用条件编译(1)按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。有利于程序的移植和调试。(2)条件编译当然也可以用条件语句来实现。 但是用条件语句将会对整个源程序进行编译,生成 的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目 标程序较短。
6.2#if-#else 条件编译指令
第一种格式:
#if 常量表达式
..code1...
..code2...
#define SCORE 67
#if SCORE & 90
printf("优秀\n");
printf("不及格\n");
它的功能是,如常量表达式的值为真(非0),则对code1 进行编译,否则对code2进行编译。因此可以使程序在不同条件下,完成不同的功能。
注意:条件编译后面的条件表达式中不能识别变量,它里面只能识别常量和宏定义
第二种格式:
...code1...
#elif 条件2
...code2...
...code3...
#define SCORE 67
#if SCORE & 90
printf("优秀\n");
#elif SCORE & 60
printf("良好\n");
printf("不及格\n");
1如果条件1成立,那么编译器就会把#if 与 #elif之间的code1代码编译进去(注意:是编译进去,不是执行,很平时用的if-else是不一样的)
2如果条件1不成立、条件2成立,那么编译器就会把#elif 与 #else之间的code2代码编译进去
3如果条件1、2都不成立,那么编译器就会把#else 与 #endif之间的code3编译进去
4注意,条件编译结束后,要在最后面加一个#endif,不然后果很严重(自己思考一下后果)
5#if 和 #elif后面的条件一般是判断宏定义而不是判断变量,因为条件编译是在编译之前做的判断,宏定义也是编译之前定义的,而变量是在运行时才产生的、才有使用的意义
七、ifndef 条件编译指令
格式:#ifndef 标识符 程序段1
#else 程序段2
与第二种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define命令 定义过则对程序段1进行编译,否则对程序段2进行编译。这与第二种形式的功能正相反。
八、使用条件编译指令调试bug
应用:可变参数宏,更方便地打印调试信息
#define DEBUG1 1
#if DEBUG1 == 0 //format是格式控制,##表示可以没有参数,__VA_ARGS__表示变量 #define Log(format,...) printf(format,## __VA_ARGS__)
#define Log(format,...)
void test(){
Log("xxxxx");
int main(int argc, const char * argv[]) {
Log("%d\n",10);
这里,‘...’指可变参数。这类宏在被调用时,##表示成零个或多个参数,包括里面的逗号,一直到到右括弧结束为止。当被调用时,在宏体(macro body)中,那些符号序列集合将代替里面 的VA_ARGS标识符。
九、typedef关键字介绍
9.1typedef基本概念C语言不仅?供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户为数据类型取“别名”。
9.2typedef语法格式
typedef 原类型名 新类型名;
其中原类型名中含有定义部分,新类型名一般用大写表示,以便于区别。
有时也可用宏定义来代替typedef的功能,但是宏定义是由预处理完成的,而typedef则是在编译 时完成的,后者更为灵活方便
9.3typedef使用方法
(1)基本数据类型typedef int INTEGER
INTEGER // 等价于
也可以在别名的基础上再起一个别名
typedef int I
typedef Integer MyI
用typedef定义数组、指针、结构等类型将带来很大的方便,不仅使程序书写简单而且使意义更为 明确,因而增强了可读性。
数组类型typedef char NAME[20]; // 表示NAME是字符数组类型,数组长度为20。然后可用NAME 说明变量,
NAME // 等价于 char a[20];
(1)结构体类型
第一种形式:
struct Person{
typedef struct Person PersonT
第二种形式:
typedef struct Person{
第三种形式:
typedef struct {
第一种形式:
typedef enum Sex SexT
第二种形式:
typedef enum Sex{
第三种形式:
typedef enum{
(3)指针typedef与指向结构体的指针
// 定义一个结构体并起别名
typedef struct {
// 起别名 typedef Point *PP;
typedef与指向函数的指针
// 定义一个sum函数,计算a跟b的和 int sum(int a, int b) { int c = a + printf("%d + %d = %d", a, b, c); } typedef int (*MySum)(int, int);
// 定义一个指向sum函数的指针变量p MySum p =
十、宏定义与函数以typedef区别
10.1与函数的区别 从整个使用过程可以发现,带参数的宏定义,在源程序中出现的形式与函数很像。但是两者是有本质区别的:(1)宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题(2)函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。所以带参数的宏比函数具有更高的执行效率
10.2typedef和#define的区别
用宏定义表示数据类型和用typedef定义数据说明符的区别。(1) 宏定义只是简单的字符串替换,?是在预处理完成的(2)typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符?重新命名。被命名的标识符具有类型定义说明的功能
typedef char *S
int main(int argc, const char * argv[])
String str = "This is a string!";
#define String char *
int main(int argc, const char * argv[])
String str = "This is a string!";
typedef char *String1; // 给char *起了个别名String1
#define String2 char * // 定义了宏String2
int main(int argc, const char * argv[]) {
只有str1、str2、str3才是指向char类型的指针变量
由于String1就是char *,所以上面的两行代码等于:
char *str1;
char *str2;
String1 str1, str2;
宏定义只是简单替换, 所以相当于
char *str3, str4;
*号只对最近的一个有效, 所以相当于
char *str3;
char str4;
String2 str3, str4;
十一、const关键字
11.1什么是常量?
常量是一个类型修饰符(1)使用const的修饰变量则可以让变量的值不能改变(2)常类型是指使用类型修饰符常量说明的类型,常类型的变量或对象的值是不能被更新的。
11.2const有什么主要的作用?
(1)可以定义常量常量,具有不可变性例如:const int Max=100;
int Array[Max];
(2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。void f(const int i) { .........}
编译器就会知道我是一个常量,不允许修改;
(3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变!如(1)中,如果想修改最大的内容,只需要:const int的最大值=你想;即可!
(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性还是上面的例子,如果在函数体内修改了我,编译器就会报错。void f(const int i) { i=10;//error! }
(5) 可以节省空间,避免不必要的内存分配。
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ...... double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存! const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存 中有若干个拷贝。
(6)高了效率。编译器通常不为普通const的常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
11.3如何使用常量?
(1)修饰一般常量一般常量是指简单类型的常量。这种常量在定义时,修饰符常量可以用在类型说明符前,也可以用在类型说明符后。int const x=2; 或 const int x=2;
当然,我们可以偷梁换柱进行更新:通过强制类型转换,将地址赋给变量,再作修改即可以改变const的常量
const int a = 5;
p = (int *)&a;
printf("%d\n", a);
printf("%d\n", *p);
输出结果: 5, 10
(2)修饰常数组(值不能够再改变了)定义或说明一个常数组可采用如下格式:int const a[5]={1, 2, 3, 4, 5};
const int a[5]={1, 2, 3, 4, 5};
const int a[5]={1, 2, 3, 4, 5};
a[1] = 55; // 错误
(3)修饰函数的常参数常量修饰符也可以修饰函数的传递参数,格式如下:无效乐趣(const int的VAR);告诉编译器功在函数体中的无法改变,从而防止了使用者的一些无意的或错误的修改。
(4)修饰函数的返回值:常量修饰符也可以修饰函数的返回值,是返回值不可被改变,格式如下:const int Fun1();
const MyClass Fun2();
(5)修饰常指针const int的* A;
// const的修饰指针,A可变,A指向的值不能被修改
INT常量* A;
// const的修饰指向的对象,A可变,A指向的对象不可变
INT * const的A;
// const的修饰指针A,A不可变,A指向的对象可变
const int的* const的A;
//指针一个和一个指向的对象都不可变
技巧先看“*”的位置
如果const 在 *的左侧 表示值不能修改,但是指向可以改。
如果const 在 *的右侧 表示指向不能改,但是值可以改
如果在“*”的两侧都有const 标识指向和值都不能改。
十二、代码
#include &stdio.h&
void test();
//void test(int v1);
概念: 局部变量就是定义在函数, 代码块和函数形参列表中的变量, 我们就称之为局部变量
作用范围: 从定义的那一行开始一直直到遇到大括号结束或者遇到return为止
相同作用域范围内不能出现同名的局部变量
不同作用域范围内出现同名的局部变量, 内部的局部变量会覆盖外部的局部变量
局部变量没有固定的初始化值, 如果没有对局部变量进行初始化, 那么局部变量中是一些随机的值, 所以在开发中千万不要使用未初始化的局部变量
局部变量存储在栈中, 当作用域结束系统会自动释放栈中的局部变量
概念: 写在函数,代码块,形参列表外的变量, 我们就称之为全局变量
作用范围: 从定义的那一行开始一直直到文件末尾(暂时这样认为)
全局变量和局部变量可以同名
如果存在和全局变量同名的局部变量, 那么局部变量会覆盖全局变量
全局变量如果没有进行初始化, 那么系统默认会将全局变量初始化为0
全局变量存储在静态区中, 他会随着程序的启动而创建, 随着程序的结束而结束
// 全局变量
int main(int argc, const char * argv[]) {
int num = 10;
int a = 55;
int num = 998;
printf("num = %i\n", num);
int num = 20;
printf("b = %i\n", b);
// 局部变量
num = 10; // 访问的是局部变量num
printf("num = %i\n", num); // 10
printf("num = %i\n", num); // 10
void test()
printf("num = %i\n", num);
num = 998; // 访问的是全局变量
num++; // 1 2
printf("num = %i\n", num);
//void test(int v1)
printf("num = %i\n", num);
int v1 = 55;
在简书整理下iOS开发的知识点,如果有遗漏多多指教下.
如果你喜欢,请不吝点赞和关注。博客访问: 37178
博文数量: 7
博客积分: 0
博客等级: 民兵
技术积分: 55
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
1.static修饰全局变量
& & 在全局变量前加static,全局变量就被定义成为一个全局静态变量。
&&&&特点如下:
& &1)存储区:静态存储区没变(静态存储区在整个程序运行期间都存在);
& &2)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。
&&&&&好处:& &
&&&&1)不会被其他文件所访问,修改;
&&&&2)其他文件中可以使用相同名字的变量,不会发生冲突。
2.static修饰局部变量
&&&&在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。
&&&&特点如下:
& 1)存储区:有栈变为静态存储区rw data,生存期为整个源程序,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,
&&&&&&&&但不能使用它;&&
& 2)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。
3. static修饰函数
& & &在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
&& &&函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用
& & &好处:
& &&1)其他文件中可以定义相同名字的函数,不会发生冲突
& &&2) 静态函数不能被其他文件所用。
阅读(11597) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。C++如何在局部函数中改变定义的全局变量的值?
本回答由提问者推荐
var sogou_ad_id=731547;
var sogou_ad_height=160;
var sogou_ad_width=690;

我要回帖

更多关于 全局变量和局部变量 的文章

 

随机推荐