一、局部变量
1、定义
在一个函数内部定义的变量成为内部变量,它只在本函数范围内有效,也就是说只有在本函数才能使用它们,在此函数外是不能使用这些变量的。这称为“局部变量”。
2、示例
void main()
{
int a,b;
...
...
}
int f1(inta,int b)
{
int c;
...
...
}
int f2(int x,int y)
{
int z;
...
...
}
其中主函数(main()函数)中定义的变量也是局部变量,只在主函数中有效。主函数也不能使用其他函数中定义的变量。在不同函数中可以使用相同的变量名称,它们代表不同的对象,互不干扰,例如,上例中,在主函数和f1()函数的形式参数中中都出现了a、b,它们在内存中占用不同的内存单元,互不干扰。
形式参数也是局部变量,只在定义它的函数中有效,其他函数不能使用。在一个函数内部,也可以在复合语句中定义变量,这些变量的作用域为本复合语句,离开该复合语句即失效,占用的内存单元被释放。
例如:
int f1(int a,int b)
{
int c;
{
int m,n;
m=a+c;
n=b+c;
...
}
...
}
变量m、n只在复合语句内有效,离开该复合语句该变量就无效,释放内存单元。
3、在Ubuntu中编写一个C语言实例
①首先创建一个.c文件;
②输入gedit jubu.c
编写程序
#include<stdio.h>
void main()
{
int a,b;
a=3,b=5;
{
int a;
a=8;
printf("a is %d\n",a);
}
printf("a is %d\n",a);
}
③编译生成可执行程序,进行运行。
在此程序中,定义了两个名为a的局部变量。在执行第一个printf语句时,起作用的是复合语句中定义的局部变量a,因此输出的结果是复合语句中a的值;在执行第二个printf语句时,已离开复合语句,在复合语句中定义的变量a失效,因此输出结果是“a is 3”。
4、局部变量的存储方式
局部变量的存储方式有三种:自动型、静态型和寄存器型。
二、全局变量
1、定义
在函数内部定义的变量称为局部变量,在函数外部定义的变量称为全局变量。全局变量可以为C程序中的其他函数使用。它的有效范围是从定义变量的位置到程序结束。
2、示例
int a=3,b=5;
int f1()
{
int a;
...
...
}
float c;
void main()
{
...
...
}
int f2()
{
...
...
}
程序中,a、b、c均为全局变量,但他们的作用范围不一样,在主函数和f2()函数中可以使用a、b、c这三个全局变量,而在f1()函数中只能使用a、b这两个全局变量。
在同一C程序中,当局部变量与全局变量同名时,在局部变量作用的范围内,全局变量不起作用。如上例中,在f1()函数中定义有局部变量a与全局变量a同名,但在f1()函数内全局变量a不起作用。
3、在Ubuntu中编写C语言实例
①创建.c文件;
②编写.c程序求一个整数数组中某两个数出现的次数及数组中所有数据的和;
程序如下:
#include<stdio.h>
int count1=0,count2=0;
int count(int a[],int b,int m,int n)
{
int i,sum=0;
for(i=0;i<b;i++)
{
if(a[i]==m)
{
count1++;
}
if(a[i]==n)
{
count2++;
}
sum+=a[i];
}
return sum;
}
void main()
{
int a[10];
int i,sum=0,m,n;
m=3,n=5;
for(i=0;i<10;i++)
{
scanf("%d",&a[i]);
}
sum=count(a,10,m,n);
printf("m appears %d times\n",count1);
printf("n appears %d times\n",count2);
printf("the sum of array is %d\n",sum);
}
③编译运行。
在上面的程序中,定义了函数count(),该函数的作用是求一个有b元素的数组a中m、n的出现次数,以及数组中各元素的和。因为一个函数只有一个函数值,因此定义两个全局变量count1、count2分别来存放m、n的出现次数。如果在count函数中改变了count1,count2的值,在其他函数中其值也随之改变。
4、全局变量的存储方式
全局变量是在静态存储区中分配内存单元的。全局变量的存储类型有两种:外部类型(extern)和静态类型(static)。
三、堆和栈
1、堆
堆是一种经过排序的树形数据结构,每一个节点都有值。通常我们说的堆的数据结构是指二叉堆。堆的特点是根结点的最小(或最大),且根结点的两个子树也是一个堆。
2、栈(Stack)
栈是限定只能在表的一端进行插入和删除操作的线性表。在表中,允许插入或删除的一端称作“栈顶(top)”,不允许插入和删除的另一端称作“栈底(bottom)”。栈是一种后进先出的数据结构。
四、利用C语言中局部变量、全局变量、堆和栈的概念在Keil中对stm32系统进行编程
在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区、堆区、全局区(静态区)、常量区、代码区,其中全局区中高地址分布着.bss段,低地址分布着.data段。
打开指南针开发板的配套资料,打开一个串口工程,将其中的main.c函数改成如下内容:
#include "stm32f10x.h"
#include "bsp_usart.h"
char global1[16];
char global2[16];
char global3[16];
char global4[16];
char global5[16];
char global6[16];
int main(void)
{
//定义局部变量
char part1[16];
char part2[16];
char part3[16];
char part4[16];
char part5[16];
char part6[16];
USART_Config();
printf("局部变量:0x%p\n", part1);
printf("局部变量:0x%p\n", part2);
printf("局部变量:0x%p\n", part3);
printf("局部变量:0x%p\n", part4);
printf("局部变量:0x%p\n", part5);
printf("局部变量:0x%p\n", part6);
printf("全局变量:0x%p\n", global1);
printf("全局变量:0x%p\n", global2);
printf("全局变量:0x%p\n", global3);
printf("全局变量:0x%p\n", global4);
printf("全局变量:0x%p\n", global5);
printf("全局变量:0x%p\n", global6);
while(1)
{
}
}
编译生成,hex文件
利用串口下载软件将程序下载到开发板上,并进行调试,结果如下:
可以看到全局变量的地址是越来越大,二局部变量的地址是越来越小。
接下来再将main.c函数进行更改。
改成:
#include "stm32f10x.h"
#include "bsp_usart.h"
int main(void)
{
static char st1[16];
static char st2[16];
static char st3[16];
char *p1;
char *p2;
char *p3;
USART_Config();
printf("st1: 0x%p\n", st1);
printf("st2: 0x%p\n", st2);
printf("st3: 0x%p\n", st3);
p1 = (char *)malloc(sizeof(char) * 16);
p2 = (char *)malloc(sizeof(char) * 16);
p3 = (char *)malloc(sizeof(char) * 16);
printf("p1: 0x%p\n", p1);
printf("p2: 0x%p\n", p2);
printf("p3: 0x%p\n", p3);
while(1)
{
}
}
可以看到他们的地址都是逐渐增加的。
五、总结
以上就是本博客的所有内容,看起来有点多,我并没有很详细的介绍,如果大家感兴趣的话,可以去查阅一些资料进行了解。欢迎大家在下方留言。