C语言变量的存储类别
C语言第5章 函数(数组作参数、变量的作用域和存储类别)
int large(int x, int y) {
int flag; if (x > y) {
flag = 1; } else if (x < y) {
flag = -1; } else {
flag = 0; } return (flag); }
⒉ 数组名可作函数参数
数组名作参数,此时实参与形参都应用数组名。
printf(“%d”, a[i]); }
return 0; }
a[0] a[1] a[2] a[3] a[4]
36194
b[0] b[1] b[2] b[3] b[4]
void sort(int b[ ], int n) {
int i, j, k, t; for (i=0; i<=n-2; i++)
(3) 形式参数也是局部变量。 例如: char f2(int x,int y) {
int i,j; …… }
⒋ 在一个函数内部,可以
在复合语句中定义变量,这
些变量 只在本复合语句中
有效,离开复合语句该变量
就无效,释放内存单元。这
种复合语句也可称为“分程
序”或“程序块”。
#include <stdio.h>
int a=3,b=5;
int max(int a,int b)
{ int c; c=a>b?a:b;形参a、b的作 用范围
return(c);
}
int main(void) {
局部变量
int a=8;
a的作用
printf(“max=%d”,max(a,b)); 范围 return 0;
}
全局变量a、b 的作用范围
C中的auto、static、register和extern的区别
} int A=13,B=-8;
也可以在多文件的程序中声明外部变量。
extern还可声明函数,eg:extern int fun(int a, int b);声明的外部函数可供其他文件调用,在C中,定义函数时省略extern,则隐含为外部函数 另附加一个两个关键字const和volitate
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。
假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
1). 一个参数既可以是const还可以是volatile吗?解释为什么。
2). 一个指针可以是volatile 吗?解释为什么。
3). 下面的函数有什么错误:
}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
auto变量:函数中的局部变量,如不专门声明static,一般都是动态地分配存储空间。自动变量:在调用该函数时系统会给他们分配存储空间,一旦函数调用结束这些存储空间就会自动释放。关键字“auto”可以省略,不写则隐含确定为“自动存储类别”,属于动态存储方式。
C语言函数章节选择题
1.在C语言中,全局变量的存储类别是:A) static B) externC) void D) registerA2.C语言中,凡未指定存储类别的局部变量的隐含存储类别是:A) 自动(auto) B) 静态(static)C) 外部(extern) D) 寄存器(register)A3. 在一个C源程序文件中,要定义一个只允许本源文件中所有函数使用的全局变量,则该变量需要使用的存储类别是:________。
A) extern B) registerC) auto D) staticD4. 若有以下调用语句,则正确的fun函数首部是main(){ ∶∶int a;float x;∶∶fun(x,a);∶∶}A) void fun(int m,float x) B) void fun(float a,int x)C) void fun(int m,float x[]) D) void fun(int x,float a)B5. 有如下函数调用语句func(rec1,rec2+rec3,(rec4,rec5));该函数调用语句中,含有的实参个数是A) 3 B) 4C) 5 D) 有语法错误A6. 以下程序的运行结果是。
#include <stdio.h>main(){ int k=4,m=1,p;p=func(k,m); printf("%d, ",p);p=func(k,m); printf("%d\n",p); }func(int a,int b){ static int m=0,i=2;i+=m+1;m=i+a+b;return m; }A) 8,17, B) 8,17C) 8,8 D) 4,1B7. 函数fun的功能是:根据以下公式计算S,n通过形参传入,n的值大于等于0。
划线处应填________。
1 1 1 1S=1 - ─+ ─- ─+ …───3 5 7 2n-1float fun(int n){ float s=0.0,w,f=-1.0;int i=0;for(i=0;i<=n;i++){________;w=f/(2*i+1);s+=w; }return s; }A) f=1 B) f=-1C) f=-1*f D) f=0C8. 函数fun的功能是:根据以下公式计算并返回S,n通过形参传入,n的值大于等于0。
第18讲 局部变量 全局变量和存储分类 局部变量作用域和生存期
局部变量 全局变量和存储分类 局部变量及其作用域和生存期
第八章 用户标识符的作用域和存储类
8.1 局部变量,全局变量和存储分类
1. 用户标识符的作用域 作用域 在C语言中,由用户命名的标识符都有一个有 效的作用域.所谓"作用域"是指程序中的某一 部分,只有在这一部分中,该标识符才是有定义 的,即只有在这个域中才能使用该标识符. 例如,在某一函数内定义的变量,只能在该 函数内进行使用.显然,变量的作用域与其定义 语句在程序中出现的位置有直接的关系.由此可 以划分为局部变量和全局变量.
2. 局部变量 例 不同函数中同名变量 例 复合语句中变量
Ch7_103.c Ch7_102.c
局部变量 float f1(int a) 5 #define N { main() int b,c; 定义:在函数内定义,只在本函数内有效 main() a,b,c有效 a,b; { int{ …….i; 说明: } int a=3; int a[N]={1,2,3,4,5}; b=4; ①在main函数中定义的变量只能在main函数中有效 printf("main:a=%d,b=%d\n",a,b); char f2(int x,int y) for(i=0;i<N/2;i++) ②不同函数中的同名变量,占不同的内存单元 sub(); i,j; temp; { { int int x,y,i,j有效 printf("main:a=%d,b=%d\n",a,b); ③函数的形参属于局部变量 …… temp=a[i]; } } ④可以定义只在某个复合语句中有效的变量 a[i]=a[N-i-1]; sub() main() a[N-i-1]=temp; { int a,b;m,n; { int } m,n有效 a=6;……. b=7; for(i=0;i<N;i++) } printf("sub:a=%d,b=%d\n",a,b); printf("%d ",a[i]); } }
c语言中变量的存储类别
一.C语言中,从变量的作用域角度来分,可以分为全局变量和局部变量。
二.变量值存在的时间角度来分,可以分为静态存储方式和动态存储方式。
所谓静态存储方式是指在程序运行期间有系统分配固定的存储空间的方式。
而动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。
具体包含4种:自动的(auto),静态的(static),寄存器的(register),外部的(extern)。
1. 自动的(auto)在调用函数时系统会给他们分配存储空间,在函数调用结束时就自动释放这些存储空间,这类局部变量称为自动变量。
2. 静态的(static)为了满足局部变量的值在函数调用结束后不消失而且保留原值,既占用的存储单元不释放,就出现了静态的局部变量,用static来声明的局部变量。
局部变量的特点:(1)相对自动变量(即动态局部变量),在程序的运行期间都占用静态存储区,直到程序结束才释放该存储区。
(2)静态局部变量只是在程序编译时赋初值,以后每次调用时不再重新赋初值,而只是保留上次函数调用结束时的值。
动态局部变量编译时不赋初值,直到程序调用时才给变量赋值,每次调用都要赋初值。
(3)在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时会自动赋初值0或空字符。
而对动态局部变量,不赋初值则它的值是一个不确定的值,因为动态变量每次都要自动分配存储空间,存储空间的值是不固定的。
(4)静态局部变量在函数调用结束后不释放,但其他函数是不能调用的。
3.寄存器的(register)为了提高程序的执行效率,对一些运算频繁的变量定义为寄存器变量可以节省每次程序执行时的内存读取,大大节省了时间,提高了效率。
寄存器的一些特点:(1)寄存器变量的特点程序运行时分配寄存器存储空间,结束时释放。
这个特点限定了只能把局部自动变量和形式参数定义为寄存器变量。
(2)局部静态变量不能定义为寄存器变量。
4. 外部的(extern)外部变量是在函数的外部定义的全局变量,他的作用是从变量的定义初开始,到本程序文件的末尾。
你知道嵌入式C语言中各变量存储的位置吗?
你知道嵌入式C语言中各变量存储的位置吗?
在举行C/C++编程时,需要程序员对内存的了解比较精准。
常常需要操作的内存可分为以下几个类别:
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局
部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—普通由程序员分配释放,若程序员不释放,程序
结束时可能由OS回收。
注重它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放
在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
4、文字常量区—常量字符串就是放在这里的。
5、程序代码区—存放函数体的二进制代码。
以下是一段实际解释的程序代码:这是一个前辈写的,十分具体。
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456在常量区,p3在栈上。
static int c =0;全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456放在常量区,编译器可能会将它与p3
第1页共3页。
C程序设计 变量作用域和存储类别(教案)
4、函数调用
5、本章总结
备注
思主要区别是什么?
函数的嵌套与递归调用的实现过程是怎样的?
结合前面所学知识,试全面总结变量的分类及作用。
教学后记
课题
变量作用域和存储类别
课型
理论课
教学时数
2
教学目的
掌握变量作用域、生命期
重点难点
静态存储变量
采用教法
启发式教学,
学法建议
讨论交流、比较
教学
过程
设计
(复习内容、课题引入、主要知识点序列或操作步骤教法设计、时间分配等)
1、复习函数定义、调用、参数传递方式,提出各个函数同名变量问题,进而引入变量作用域概念
2、变量的作用域(有效范围、可见性)
变量的作用域:变量的有效范围或者变量的可见性。变量定义的位置决定了变量的作用域。
变量从作用域(变量的有效范围,可见性)的角度可以分为:局部变量,全局变量。
1、变量的存储类别(生存期、生命期)
变量从空间上分为局部变量、全局变量。
从变量存在的时间的长短(即变量生存期)来划分,变量还可以分为:动态存储变量、静态存储变量。变量的存储方式决定了变量的生存期。
C语言变量的声明和空间的分配
无论用什么语言编制的程序,都是为让计算机完成某一特定功能而编写的文本文件。
这些文本文件是不能直接在机器上运行的,它们必须经过系统软件(包括编辑器和编译器)的输入并编译或汇编后,转换成二进制的可执行代码,才是计算机可以识别的机器语言。
此时,程序就是一个包含二进制可执行代码文件的模块。
当内核把二进制的可执行代码装入内存后,它由三部分组成:代码段、数据段、堆栈段。
在线性地址的低地址字段是代码段,存放程序经编译后的可执行代码(程序文本)。
在操作系统中,代码段是只读的,不能修改,所以,代码段的长度是不会改变的。
在程序文本(代码段)的上方是数据段,用来存放程序的变量、字符串和其它数据。
它分为初始化静态数据(data)和未初始化静态数据(BSS。
数据段的长度是可以改变的。
程序可以修改其中的变量。
在程序设计中,将其值可以改变的量称为变量。
每一个变量在内存中都要占据一定的存储单元,因此,每一个变量也就会具有一定的存储属性。
从变量的作用域(空间)的角度来考虑变量的属性,可将变量分为全局变量和局部变量。
局部变量局部变量是指在一个函数内部定义的变量,它只中本函数范围内有效。
说明:1、在主函数中定义的变量只在主函数中有效,且主函数也不能使用其他函数中定义的变量2、在不同函数中可以使用相同名字的变量,它们代表不同的变量,互不干扰;3、形参也是局部变量,也只在对应的函数中有效,其他函数不能使用4、在一函数内部,可在复合语句(有一个{} 括起的一组语句)中定义变量,这些变量只在本复合语句中有效。
全局变量程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数。
在函数之外定义的变量称为外部变量(extern ), 也叫全局变量。
全局变量的有效范围是从定义变量的位置开始到本源程序文件结束为止,其关键字extern 可以省略。
说明:1、在一个函数中既可以使用本函数中的局部变量,又可以使用有效的全局变量。
2、设置全局变量的作用是增加函数间数据联系的渠道。
第4讲_内存存储
4
8.9 变量的存储类别
变量的存储方式分为两类:静态存储方式和动态存储方式 •静态存储方式:在程序运行期间由系统分配固定的存储空间 •动态存储方式:在程序运行期间根据需要动态 的分配存储空间
auto—自动的
static—静态的 变量的存储类别分4种 register—寄存器的
extern—外部的
低 局部变量d 栈存储区 局部变量 c 局部变量b 堆存储区 0x0012fec8 0x0012ff24 0x0012ff78
hhh ggg 程序代码区 main
高 全局变量a
0x00401030 0x00401080
0x004010f0
0x00428a30
19
8.10 内部函数和外部函数
函数的作用域是全局的,它的存储类别 有两种:static 和extern
第4讲 内存存储
本讲内容: (1)变量的存储类别 (2)C程序的内存映像 (3)内部函数和外部函数
1
8.9 变量的存储类别
★ 几个概念: ⑴ 作用域-----变量能够起作用的程序范围。 在整个程 从作用域的角度区分,变量可分为: 只有在某函 序的运行 数的执行过 时间内一 全局变量和 局部变量 程中存在的 直存在的 ⑵ 生存期----变量在内存中存在的某一时间范围 。 变量 变量。 从生存期的角度区分,变量可分为: 静态变量和 动态变量 ⑶变量的生存期由其存储类别决定,变量的存储 类别有四种:auto、static、register、extern ⑷函数的存储类别:extern、static
5
auto变量 •函数中的局部变量如果没有特殊声明则都是auto变量 •auto变量的特点:在调用函数时系统为它们分配存储空间, 在函数调用结束时自动释放这些存储空间 •程序中的大多数变量为auto变量,auto可省略不写
10、变量的作用域和存储类型
10、变量的作⽤域和存储类型1、变量的定义 变量定义:在程序运⾏过程中其值可以更改的格式:<存储类型> <数据类型> <变量名> = <初始值>;2、变量的作⽤域 变量的作⽤域定义:程序中可以访问⼀个指⽰符的⼀个或多个区域,即变量出现的有效区域,决定了程序的那些部分通过变量名来访问变量。
⼀个变量根据其作⽤域的范围可以分为函数原型作⽤域、局部变量和全局变量。
2.1、函数原型参数作⽤域 函数原型中的参数的作⽤域始于‘(’,终于‘)’。
2.2、局部变量 (1)、在函数内部定义的变量称为局部变量。
(2)、局部变量仅能被定义该变量的函数使⽤,其他函数是⽤不了的。
局部变量仅存在于该变量的执⾏代码块中,即局部变量在进⼊模块时⽣成(压⼊栈堆),在退出模块时消亡(弹出堆栈),定义局部变量的最常见的代码块是函数。
(3)、当全局变量和局部变量同名时,在局部范围内全局变量被屏蔽,不再起作⽤,或者说变量的使⽤遵守就近原则,如果在当前作⽤域中存在同名变量,就不会向更⼤的作⽤域中去寻找变量。
(4)、可以在不同的函数中使⽤相同的变量名,他们表⽰不同的数据,分配不同的内存,互不⼲扰,也不会发⽣混淆。
(5)、局部变量的定义和声明可以不加区分。
(6)、在{}内定义的变量只在{}内起作⽤。
2.3、全局变量 (1)、全局变量贯穿整个程序,它的作⽤域为源⽂件,可被源⽂件中的任何⼀个函数使⽤。
(2)、全局变量的定义和全局变量的声明并不是⼀回事,全局变量定义必须在所有函数之外,且只能定义⼀次,⼀般定义形式如下: 全局变量的定义格式:<数据类型> <变量名,变量名…..> 全局变量的声明出现在要使⽤该变量的各个函数内。
全局变量的声明格式:<extern> <数据类型> <变量名,变量名…….> (3)、全局变量在定义时就已分配了内存单元,并且可做初始赋值。
变量的储存类别(Variable storage class)
c)函数调用时的现场保护和返回地址等
二、四种储存方法
1、auto变量
函数中的局部变量,如不专门声明为static储存类型,都是动态地分配储存空间的,数据储存在动态储存区中。
2、static声明局部变量
static声明的局部变量的值在函数调用结束后不消失而保留原值,即其占用的储存单元不释放,在下一次改函数调用时,改变量已有值,就是上一次函数调用结束时的值。
2, static local variable declaration
The static local variable declared value at the end of the function call does not disappear and leave, namely the storage unit the occupation does not release, in the next to a function call, change the value, is a function call at the end of the value.
a)在一个文件内声明外部变量。
如果外部变量不在文件的开头定义,其有效的作用范围只限于定义出到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量做“外部变量声明”。表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。
3, the register variable
In general, the value of a variable is stored in memory, when where a variable in a program value, the controller issued a directive to the variable has the value in memory to the ALU. After computing for operation, if the need to save the number, then the data is sent to the memory storage from operator. If the need for frequent storage, can put the value of the local variable is placed in the CPU register.
C语言习题(7)
C语言习题(7)第7章函数一.填空题1.C语言中从函数的形式分可分为无参函数和。
2.在C语言中,一个自定义函数一般由两部分组成,它们是函数首部和。
3.从用户使用角度看,函数有两种:标准函数和。
4.若一个函数不需要形参,则在定义该函数时应使形参表为空或者放置一个标识符。
5.有函数调用fun1(x+y, (y,z), 10, fun((x,y-1))); 函数fun1有个参数。
6.已知函数定义:void dothat(int n, double x) { …… },其函数声明的两种写法为_________________________,_________________________。
7.C语言变量按其作用域分为和;按其生存期分为___________和。
8.C语言变量的存储类别有,,和。
9.凡在函数中未指定存储类别的局部变量,其默认的存储类别为。
10.在一个C程序中,若要定义一个只允许本源程序文件中所有函数使用的全局变量,则该变量需要定义的存储类别为。
11.C语言中,形式参数的缺省存储类型是。
12.C语言中,若为指定函数是内部函数或外部函数,则默认该函数是。
二.选择题1.以下正确的说法是___________。
A)用户若需要调用标准库函数,调用前必须重新定义B)用户可以重新定义标准库函数,如若此,该函数将失去原有定义C)系统不允许用户重新定义标准库函数D)用户若需要使用标准库函数,调用前不必使用预处理命令将该函数所在的头文件包含编译,系统会自动调用。
2.以下正确的函数定义是___________。
A)double fun(int x, int y); B)int fun(int x,y){ z=x+y ; return z ; } { int z ; return 3;}C)double fun (x,y) D)double fun (int x, int y){ int x, y ; double z ; { double z ; z=x+y;z=x+y ; return z ; } return z ; }3.C语言中,简单变量做实参和形参时,以下正确的说法是___________。
大一c语言期末考试题库及答案
大一c语言期末考试题库及答案大一C语言期末考试题库及答案一、选择题1. C语言中,以下哪个关键字用于定义一个变量的存储类别?A. intB. charC. staticD. void答案:C2. 在C语言中,以下哪个运算符用于计算两个数的差?A. +B. -C. *D. /答案:B3. 如果一个变量被定义为int a; 那么它的初始值是什么?A. 0B. 1C. 不确定D. -1答案:C二、填空题1. 在C语言中,______是最基本的数据单位。
答案:变量2. 一个C程序总是从______函数开始执行的。
答案:main3. 在C语言中,______关键字用于定义一个函数。
答案:void 或者 int(取决于函数的返回类型)三、简答题1. 简述C语言中数组的定义和初始化方式。
答案:在C语言中,数组定义的一般形式为:类型名数组名[常量表达式],其中类型名是数组元素的数据类型,数组名是数组的标识符,常量表达式是数组中元素的个数。
数组的初始化是在定义数组的同时,给数组元素赋初值。
例如:```cint arr[5] = {1, 2, 3, 4, 5};```2. 描述C语言中指针的概念及其用途。
答案:指针是C语言中一种特殊的变量,它存储的是另一个变量的内存地址。
指针的主要用途包括动态内存分配、数组操作、函数参数的传递等。
指针的使用可以提高程序的灵活性和效率。
四、编程题1. 编写一个C语言程序,实现两个整数的加法,并输出结果。
```c#include <stdio.h>int main() {int num1, num2, sum;printf("请输入两个整数:");scanf("%d %d", &num1, &num2);sum = num1 + num2;printf("两个整数之和为:%d\n", sum);return 0;}```2. 编写一个C语言程序,实现字符串的复制功能。
c语言数据的四种存储类型
c语言数据的四种存储类型标题:C语言数据的四种存储类型详解在深入探讨C语言编程的世界中,数据存储类型是构建程序逻辑的基础元素之一。
它们定义了变量或函数在内存中的生命周期、作用域和可见性。
本文将详细解析C语言中的四种主要数据存储类型:自动存储类型、静态存储类型、寄存器存储类型以及外部存储类型。
1. 自动存储类型(Auto)自动变量是在函数内部声明的局部变量,其存储类型默认为“auto”,虽然在现代C语言中可以省略不写。
这类变量在执行到其声明处时分配空间,当控制权离开该函数时,即函数结束时,系统会自动释放其占用的内存空间,因此得名“自动”。
自动变量的作用域仅限于定义它的代码块内。
例如:cvoid func() {int autoVar; 这是一个自动变量...}在上述代码中,`autoVar` 在`func()` 函数体内声明,当`func()` 执行完毕后,`autoVar` 就不再存在。
2. 静态存储类型(Static)静态变量也是在函数内部声明,但与自动变量不同的是,它具有静态存储持续性,即即使函数结束,其值也不会丢失,下次调用函数时仍然保留上次的值。
此外,静态局部变量的作用域仍限制在声明它的函数内,但在整个程序运行期间始终占据内存空间。
例如:cvoid func() {static int staticVar = 0;staticVar++;printf("staticVar: d\n", staticVar);}每调用一次`func()`,`staticVar` 的值就会加一,因为其存储类型为静态。
3. 寄存器存储类型(Register)寄存器存储类型的变量请求编译器将其存储在CPU的寄存器中以提高访问速度,而非内存中。
然而,并非所有声明为register的变量都能真正被存放在寄存器中,这完全取决于硬件限制和编译器的优化策略。
寄存器变量也具有自动存储期限,即在其所在代码块结束时失效。
C语言中auto,static,register,extern存储类型的用法
在C语言中提供的存储类型说明符有auto,extern,static,register,说明的四种存储类别。
四种存储类别说明符有两种存储期:自动存储期和静态存储期。
其中auto和register对应自动存储期。
具有自动存储期的变量在进入声明该变量的程序块是被建立,它在该程序块活动时存在,退出该程序块时撤销。
Auto在函数内部定义的变量成为局部变量。
局部变量称为自动变量,这就与使用可选关键字a u t o定义局部变量这一作法保持一致。
局部变量仅由其被定义的模块内部的语句所访问。
换言之,局部变量在自己的代码模块之外是不可知的。
切记:模块以左花括号开始,以右花括号结束。
对于局部变量,要了解的最重要的东西是:它们仅存在于被定义的当前执行代码块中,即局部变量在进入模块时生成,在退出模块时消亡。
定义局部变量的最常见的代码块是函数。
请见以下代码:#include "stdio.h"main(){int i,num;num=2;for (i=0;i<3;i++){ printf("The num equal %d \n",num);num++;{auto int num=1;printf("The internal block num equal %d \n",num);num++;}}}运行的结果为:其实现在都不用打上auto了,编译器默认为auto的不信可以把auto删除试试。
StaticC语言中,存储类型static字面意思很容易把我们导入歧途,其实它的作用有三条,1,隐藏。
这也是最重要的一条。
2,static的第二个作用是保持变量内容的持久。
3,第三个作用是默认初始化为0。
(1)这里就先说第一条,当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。
我举例来说明。
我们要同时编译两个源文件,一个是my.c,另一个是main.c。
c语言函数形参的存储类别
c语言函数形参的存储类别在C语言中,函数形参指的是在函数定义中接收传递进来的参数。
函数参数可以简化函数的参数传递,提高代码的可读性和可维护性。
C语言中的函数参数有四种存储类别:auto、register、static和extern。
1. autoauto是默认的存储类别,在函数定义中声明的变量默认存储在栈中,它们的值在函数调用时得到初始化,在函数调用完成后被销毁。
如果没有显式地指定变量的存储类别,则编译器会默认将变量存储为auto类型。
以下是一个例子:```int sum(int a, int b) {auto int c = 0; // auto 可以省略c = a + b;return c;}```2. registerregister关键字用于向编译器提示将变量存储在寄存器中,以便提高访问速度。
它实际上是建议性的,不能保证变量一定会存储在寄存器中。
以下是一个例子:3. staticstatic关键字用于指定变量在函数被执行时在全局变量区分配内存,函数执行完毕后,内存不会被回收,下次执行这个函数时,变量的值会继续保持。
static变量可以被用于实现全局变量的效果,同时又不会对程序的其他部分产生影响。
以下是一个例子:运行结果为:1 2 3 4 5 6 7 8 9 10。
4. externextern关键字用于在函数定义中声明全局变量。
如果一个函数需要使用全局变量,但是全局变量不是在函数内部定义的,则需要使用extern来引用全局变量。
以下是一个例子:```#include <stdio.h>int g = 20;void print() {extern int g;printf("g = %d", g);}运行结果为:g = 20。
综上,C语言函数形参的存储类别有四种:auto、register、static和extern。
程序员应根据具体情况选用适当的存储类别。
C语言中局部变量和全局变量等在内存中的存放位置
C语言中局部变量和全局变量变量的存储类别(static,extern,auto,register)8.8局部变量和全局变量在讨论函数的形参变量时曾经提到,形参变量只在被调用期间才分配内存单元,调用结束立即释放。
这一点表明形参变量只有在函数内才是有效的,离开该函数就不能再使用了。
这种变量有效性的范围称变量的作用域。
不仅对于形参变量,C语言中所有的量都有自己的作用域。
变量说明的方式不同,其作用域也不同。
C语言中的变量,按作用域范围可分为两种,即局部变量和全局变量。
8.8.1局部变量局部变量也称为内部变量。
局部变量是在函数内作定义说明的。
其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。
例如:int f1(int a) /*函数f1*/{int b,c;……}a,b,c有效int f2(int x) /*函数f2*/{int y,z;……}x,y,z有效main(){int m,n;……}m,n有效在函数f1内定义了三个变量,a为形参,b,c为一般变量。
在f1的范围内a,b,c有效,或者说a,b,c变量的作用域限于f1内。
同理,x,y,z的作用域限于f2内。
m,n的作用域限于main函数内。
关于局部变量的作用域还要说明以下几点:1)主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用。
同时,主函数中也不能使用其它函数中定义的变量。
因为主函数也是一个函数,它与其它函数是平行关系。
这一点是与其它语言不同的,应予以注意。
2)形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量。
3)允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。
如在前例中,形参和实参的变量名都为n,是完全允许的。
4)在复合语句中也可定义变量,其作用域只在复合语句范围内。
例如:main(){int s,a;……{int b;s=a+b;……/*b作用域*/}……/*s,a作用域*/}【例8.12】main(){int i=2,j=3,k;{int k=8;printf("%d\n",k);}printf("%d\n",k);}本程序在main中定义了i,j,k三个变量,其中k未赋初值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言变量的存储类别内存中供用户使用的存储空间分为代码区与数据区两个部分。
变量存储在数据区,数据区又可分为静态存储区与动态存储区。
静态存储是指在程序运行期间给变量分配固定存储空间的方式。
如全局变量存放在静态存储区中,程序运行时分配空间,程序运行完释放。
动态存储是指在程序运行时根据实际需要动态分配存储空间的方式。
如形式参数存放在动态存储区中,在函数调用时分配空间,调用完成释放。
对于静态存储方式的变量可在编译时初始化,默认初值为O或空字符。
对动态存储方式的变量如不赋初值,则它的值是一个不确定的值。
在C语言中,具体的存储类别有自动(auto)、寄存器(register)、静态(static)及外部(extern)四种。
静态存储类别与外部存储类别变量存放在静态存储区,自动存储类别变量存放在动态存储区,寄存器存储类别直接送寄存器。
变量存储类别定义方法:存储类别类型变量表;例如:(1)a,b,c为整型自动存储类别变量:auto int a,b,c;(2)x,y,z为双精度型静态存储类别变量:static double x,y,z;1、变量有哪些存储类型?变量的存储类型由“存储类型指明符”来说明。
存储类型指明符可以是下列类键字之一:autoregisterexternstatic下面是详细的解释:auto 存储类指明符--用于说明具有局部作用域的变量,它表示变量具有局部(自动)生成期,但由于它是所有局部作用域变量说明的缺省存储类指明符,所以使用得很少。
要注意的是,所有在函数内部定义的变量都是局部变量,函数内部定义的变量其作用域只在函数内部。
它的生存期为该函数运行期间,一旦离开这个函数或这个函数终止,局部变量也随之消失。
register 存储类指明符--当声明了这个指明符后,编译程序将尽可能地为该变量分配CPU内部的寄存器作为变量的存储单元,以加快运行速度。
注意,寄存器与存储器是不同的。
寄存器一般在CPU内部,而存储器一般指外部的(比如内存条),CPU内部的寄存器其运算速度是很高的。
当寄存器已分配完毕,就自动地分配一个外部的内存。
它的作用等价于auto,也只能用于局部变量和函数的参量说明。
static 存储类指明符--表示变量具有静态生成期。
static变量的的特点是它离开了其作用域后,其值不会消失。
当回到该作用域之后又可以继续使用这个static变量的值。
例:利用static变量统计调用函数的次数int two(); /*函数原型说明*/void main(){int a=0;a=two(); /*a的值等于1*/a=two() /*a的值等于2*/a=two(); /*a的值等于3*/}int two(){static int b=0;/*定义了一个局部的static变量*/b ;return b;}如果不是一个static变量就不会有这个效果了int two(); /*函数原型说明*/void main(){int a=0;a=two(); /*a的值等于1*/a=two() /*a的值等于1*/a=two(); /*a的值等于1*/}int two(){int b=0;b ;return b;}变量a的值总是1,原因是在函数two()中,变量b不是一个static变量,其值随着离开two函数就消失了,当回到two函数时又被重新赋值0。
extern 存储类指明符--一般用在工程文件中。
在一个工程文件中因为有多个程序文件,当某一个变量在一个程序文件中定义了之后,如果在另一个程序文件中予以定义,就会出现重复定义变量的错误。
使用extern存储类型指明符就可以指出在该文件外部已经定义了这个变量。
extern变量的作用域是整个程序。
2、变量存储在内存的什么地方?1)变量可以存储在内存的不同地方,这依赖于它们的生成期。
在函数上部定义的变量(全局变量或static外部变量)和在函数内部定义的static变量,其生存期就是程序运行的全过程。
这些变量被存储在数据段(Data Segment)中。
数据段是在内存中为这些变量留出的一段大小固定的空间,它分为二部分,一部分用来初始化变量,另一部分用来存放未初始化的变量。
2)在函数内部定义的auto变量(没有用关键字static定义的变量)的生成期从程序开始执行其所在的程序块代码时开始,到程序离开该程序块时为止。
作为函数参数的变量只在调用该函数期间存在。
这些变量被存储在栈(stack)中。
栈是内存中的一段空间,开始很小,以后逐渐自动变大,直到达到某个预定义的界限。
3)当用malloc等函数给指针分配一个地址空间的时候,这个分配的内存块位于一段名为“堆(heap)”的内存空间中。
堆开始时很小,但调用malloc或clloc等内存分配函数时它就会增大。
堆可以和数据段或栈共用一个内存段,也可以有它自己的内存段,这完全取决于编译选项和操作系统。
与栈相似,堆也有一个增长界限,并且决定这个界限的规则与栈相同。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------C语言变量的作用域和存储类型一、作用域和生存期C程序的标识符作用域有三种:局部、全局、文件。
标识符的作用域决定了程序中的哪些语句可以使用它,换句话说,就是标识符在程序其他部分的可见性。
通常,标识符的作用域都是通过它在程序中的位置隐式说明的。
1.局部作用域前面各个例子中的变量都是局部作用域,他们都是声明在函数内部,无法被其他函数的代码所访问。
函数的形式参数的作用域也是局部的,它们的作用范围仅限于函数内部所用的语句块。
void add(int);main(){int num=5;add(num);printf("%d\n",num); /*输出5*/}void add(int num){num++;printf("%d\n",num); /*输出6*/}上面例子里的两个num变量都是局部变量,只在本身函数里可见。
前面我们说了,在两个函数出现同名的变量不会互相干扰,就是这个道理。
所以上面的两个输出,在主函数里仍然是5,在add()函数里输出是6。
2.全局作用域对于具有全局作用域的变量,我们可以在程序的任何位置访问它们。
当一个变量是在所有函数的外部声明,也就是在程序的开头声明,那么这个变量就是全局变量。
void add(int);int num;main(){int n=5;add(n);printf("%d\n",num); /*输出6*/}void add(num) /*形式参数没有指定类型*/{num++;printf("%d\n",num); /*输出6*/}上面的main()和add()里面,并没有声明num,但是在最后输出的时候却要求输出num,这是由于在程序的开始声明了num是全局变量,也就是在所有函数里都可以使用这个变量。
这时候一个函数里改变了变量的值,其他函数里的值也会出现影响。
上面的例子输出都是6,因为在add()函数里改变了num的值,由于num是全局变量,就好象它们两个函数共用一个变量,所以在main()函数里的num也随之改变了。
3.文件作用域在很多C语言书上,都没有说明文件作用域,或者只是略微的提到,其实文件作用域在较大程序中很有作用(在多文件系统中)。
文件作用域是指外部标识符仅在声明它的同一个转换单元内的函数汇总可见。
所谓转换单元是指定义这些变量和函数的源代码文件(包括任何通过#i nclude指令包含的源代码文件)。
static存储类型修饰符指定了变量具有文件作用域。
static int num;static void add(int);main(){scanf("%d",&num);add(num)printf("%d\n",num);}void add(num){num++;}上面的程序中变量num和函数add()在声明是采用了static存储类型修饰符,这使得它们具有文件作用域,仅爱定义它们的文件内可见。
由于我们提到的大多数程序都只有一个编译文件组成,所以这种写法没有实际意义。
但是实际工程上的文件有很多,它们不是由一个人写成的,由很多人共同完成,这些文件都是各自编译的,这难免使得某些人使用了一样的全局变量名,那么为了以后程序中各自的变量和函数不互相干扰,就可以使用static修饰符,这样在连接到同一个程序的其他代码文件而言就是不可见的。
二、变量存储类型前面我们说了,声明变量时用如下类似的形式:int num;float total;它们都没有存储类型修饰符,我们在声明时也可以通过存储类型修饰符来告诉编译器将要处理什么类型的变量。
存储类型有以下四种:自动(auto)、静态(static)、外部(extern)、寄存器(regiser)。
1.自动存储类型自动存储类型修饰符指定了一个局部变量为自动的,这意味着,每次执行到定义该变量的语句块时,都将会为该变量在内存中产生一个新的拷贝,并对其进行初始化。
实际上,如果不特别指明,局部变量的存储类型就默认为自动的,因此,加不加auto都可以。
main(){auto int num=5;printf("%d\n",num);}在这个例子中,不论变量num的声明是否包含关键字auto,代码的执行效果都是一样的。
函数的形式参数存储类型默认也是自动的。
2.静态存储变量前面已经使用了static关键字,但是对于局部变量,静态存储类型的意义是不一样的,这时,它是和自动存储类型相对而言的。
静态局部变量的作用域仍然近局限于声明它的语句块中,但是在语句块执行期间,变量将始终保持它的值。
而且,初始化值只在语句块第一次执行是起作用。
在随后的运行过程中,变量将保持语句块上一次执行时的值。
看下面两个对应的程序:/*1.C*/ /*2.C*/int add(); int add();main() main(){ {int result; int result;result=add() result=add();printf("%d ",result); printf("%d ",result);result=add(); result=add();printf("%d ",result); printf("%d ",result);result=add(); result=add();printf("%d",result); printf("%d",result);} }int add() int add(){ {int num=50; static int num=50;num++; num++;return num; return num;} }上面两个源文件,只有函数add()里的变量声明有所不同,一个是自动存储类型,一个是静态存储类型。