C语言存储方式和作用域(1)

一概述:

        只有完全了解每个变量或函数存储方式、作用范围和销毁时间才可能正确的使用编程语言。基础扎实才是硬道理。

       


二.变量作用范围:

        在C语言中变量从作用范围分为:

        1.全局变量:定在所有函数外部的定义的变量,定义后所有的函数中均可以使用,只要前面的代码修改了,那么后面的代码中再使用就是修改后的值。(ps:在项目中,一般有两到三处,我一般定义成全局变量,方便修改,方便维护,不需要一个一个修改)。

        2.局部变量:作用范围一般在一个函数内部(通常在一对大括号{}内),外面的程序无法访问它,它却可以访问外面的变量。

    

#include<stdio.h>
int a =1;
void changeValue(){
  a = 2;
printf("a=%d\n",a);
}

int main(){
  int b = 1;
  changeValue();
  printf("a=%d,b=%d\n",a,b);
  return 0;
}

打印结果为: a = 2;

                a=2,b=1;

只要修改了a全局变量,再使用就是被修改后的值.

b是局部变量



三.变量存储方式:

    C语言的强大之处在于它能直接操作内存(指针),但是要搞懂它的操作方式我们必须要搞懂它的存储方式.

     存储变量的位置分为:

        1.普通内存(静态存储区)

        2.运行时堆栈(动态存储区)

        3.硬件寄存器(动态存储区)

        这几种存储效率是从低到高的,它们决定了变量何时创建、何时销毁以及它的值能保持多久,也就是决定了,变量的生命周期。

    额外其实在C语言中还有两种存储区:常量存储区和代码存储区,分别用于存储字符串常量、使用const修饰的全局变量以及二进制函数代码

然后再根据存储位置分为不同变量:

        1.静态变量

        2.自动变量

        3.寄存器变量


2.1.静态变量:

       1.定义:静态变量是存储在静态内存中的,也就是不属于堆栈。


       2.哪些属于静态变量呢?

        1.所有的全局变量都是静态变量

        2.被关键字static修饰局部变量也就是静态变量

       3.生命周期:静态变量在程序运行之前创建,在程序运行期间始终存在,直到程序结束.只初始化一次.

#include<stdio.h>
int a = 1;
void showMessage(){
static int b = 1;
int c = 1;
++b;
a+=2;
printf("a=%d,b=%d,c=%d\n",a,b,c);
)

int main(){

showMessage();
showMessafe();
return 0;
}

结果为: a=3,b=2,c=1

            a=5,b=3,c=1

全局变量a在静态内存中,只初始化一次。

虽然b是局部变量,但是被static修饰,在程序结束前,一直存在,但外部无法访问。

变量c则第一次执行完就释放了,第二次执行再次创建。



2.2.自动变量(要不是回来复习,我还真的不知道什么是自动变量)

    1.定义:自动变量存储在堆栈中.

    2.哪些是自动变量:被关键字auto修饰的局部变量都是自动变量,但是极少没有人使用这个关键字,所以(我不知道),但是局部变量在没有加关键词情况下默认是自动变量!!!!(emmm...)


    3.生命周期:在程序执行到声明自动变量的代码块(函数或是在 {})时,自动变量才被创建,代码块(函数或遇到 })执行完毕后就会自动销毁。如果重复调用该代码块(函数),这些自动表变量再次重新创建,再次重新销毁。


void test(int a,int b){
int c = a+b;

}


需要注意的是,上面的自动变量存储在栈中,其实还可以存储到堆中.

补充:(看不懂没关系,往下学习碰到面向对象学习课程,就会懂了)
int main(){
char c[] = "hello,world!";
long len = strlen(c)*sizeof(char)+1;
//之所以+1是因为字符串后面默认加上\0空字符串不计算在长度内.
char *p = NULL;
p = (char *)malloc(len);
//开辟内存空间,分配指定的字节存放c中字符串.
memset(p,0,len);
//清除指向内存中的存储内容,因为分配的内存是随机,如果不清空就可能因为垃圾数据产生造成不必要的麻烦。
strcpy(p,c);
printf("p==%s\n",p); //hello,world!
free(p)//释放分配的空间
p=null;//回收对象,防止存储一个无用地址的野指针

retrun 0;
}

malloc分配的空间在逻辑上连续,物理上未必连续;

p必须手动释放,否则直到程序运行结束它占用的内存将一直被占用;

释放p的过程只是把p指向的空间释放掉,p中存放的地址并未释放,需要手动设置为NULL,否则这将是一个无用的野指针;


同样的p也是一个自动变量,也可以用auto修饰,只是它指向的内容放到堆上(p本身就在栈上.)

简单来说 c、 len、 p都存在栈,当执行到

p = (char *)malloc(len)  p就存储在堆上了。



其实目的更早了解堆:

当然存储自动变量的其实是两个完全不同的空间(虽然都在运行时有效的空间内):

栈一般是程序自动分配,其存储结果类似于数据结构中的栈,先进后出,程序结束时由编译器自动释放;

而堆则是开发人员手动编码分配,如果不进行手动释放就只有等到程序运行完操作系统回收,其存储结构类似于链表。



注意:无论自动变量还是静态变量都在内存中,不同之处就是自动变量放在运行时分配的特殊内存中。


2.3.寄存器变量(这个我也忘了。。。)

    1.定义:存储在硬件寄存器中的变量,称为寄存器变量。寄存器变量比存储在内存中的变量访问效率更高(

无论自动变量还是静态变量都在内存中,不同之处就是自动变量放在运行时分配的特殊内存中).

    2.哪些变量是寄存器变量呢:

    2.1.被关键字 register 修饰的变量都是寄存器变量

    2.2.只有自动变量才可以是寄存器变量,全局变量和静态变量不行。

    2.3.寄存器变量只限于int、char指针类型变量的使用

    3.生命周期:因为寄存器变量本身就是自动变量,所以函数中寄存器变量在调用该函数时占用寄存器中存放的值,当函数结束时候,寄存器变量消失.


注意:

由于计算机中寄存器数目有限,不能使用太多的寄存器变量。如果寄存器使用饱和时,程序将寄存器变量自动转换为自动变量处理

为了提高运算速度,一般会将一些频繁使用的自动变量定义为寄存器变量,这样程序尽可能地为它分配寄存器存放,而不用内存。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值