C语言中常见的3种修饰符

前言

为了更好地理解static,这里有必要先补充一下前置知识:

1.作用域(scope)

简单来说就是限定某个名字或变量可用性的代码范围

局部变量的作用域是变量所在的局部范围。

全局变量的作用域是整个工程(项目)。

2.生命周期

简单来说就是 变量的创建(申请内存)——>变量的销毁(收回内存) 之间的⼀个时间段。

局部变量的生命周期:进入作用域变量创建,生命周期开始,出作用域生命周期结束。

全局变量的生命周期:整个程序的生命周期。


1.extern(外部)

如果一个符号具有外部链接属性,如:全局变量、函数。在外部的文件中想使用,只要适当的声明就可以使用,此时就可以使用extern声明。如:

一个全局的符号在A文件中被定义,在b文件中想要使用,在使用前就可以使用extern声明该全局符号。

test1.c文件

int Moment=0;

test2.c文件

#include <stdio.h>
 extern int Moment=0;
 
int main()
{
 printf("%d\n", Moment);
 return 0;
}

2.static(静态的)

(1)static修饰局部变量

#include <stdio.h>
void test()
{
   static int i = 0;//static修饰局部变量
   i++;
   printf("%d ", i);
}
  
int main()
{
    int i = 0;
    for(i=0; i<5; i++)
    {
      test();
    }

    return 0;
}

未用static修饰前:test函数中的局部变量 i 是每次进入test函数都要先创建变量(生命周期开始)并赋值为0,然后 ++,再打印,出函数的时候变量生命周期结束(释放内存)。

使用static修饰后:,i 的值有累加的效果,test函数中的 i 创建好后,出函数的时候不会销毁,重新进入函数也就不会重新创建变量,直接从上次累积的数值继续计算。

注:

static修饰局部变量改变了变量的生命周期,本质上是改变了变量的存储类型,原本局部变量存储在内存的栈区,但是被static修饰后存储到了静态区,存储在静态区的变量和全局变量生命周期相同,但是作用域不变。

(2)static修饰全局变量

为了方便理解,将上面extern处代码截图至此处:

代码1

代码2

test3.c文件(static修饰)

static int Moment=0;

test4.c文件

#include <stdio.h>
 extern int Moment=0;
 
int main()
{
 printf("%d\n", Moment);
 return 0;
}

结论:代码1正常运行,代码2在编译的时候会出现链接性错误。

解释:

全局变量默认具有外部链接属性,在外部的文件中想使用,只要适当的声明就可以使用;但是全局变量被 static 修饰之后,外部链接属性就变成了内部链接属性,只能在当前所在的源文件内部使用,其他源文件,即使声明,也无法正常使用。

3)static修饰函数

static 修饰函数和 static 修饰全局变量⼀模⼀样,参照修饰全局变量理解。


3.const(恒定的、不变的)

(1)const修饰变量

 #include <stdio.h>
 int main()
 {
   int m = 0;
   m = 2;//m是可以修改的
 
   const int a = 0;
   a = 2;//a是不能被修改的
 
   return 0;
 }

注:

const修饰变量虽然不能直接修改,但是可以通过该变量的地址去间接修改其值,所以是有漏洞可钻的,而const修饰指针完善了这一点。

(2)const修饰指针

void test1()//const在*左边
{
 int n = 10;
 int m = 20;
 const int* p = &n;
 *p = 20;//ok? ,不可以
 p = &m; //ok? ,可以
}
 

void test2()//const在*右边
{
 int n = 10;
 int m = 20;
 int *const p = &n;
 *p = 20; //ok? ,可以
 p = &m;  //ok? ,不可以
}


void test3()//*左右两边都有const
{
 int n = 10;
 int m = 20;
 int const * const p = &n;
 *p = 20; //ok? ,不可以
 p = &m;  //ok? ,不可以
}



int main()
{  
   //测试const放在*的左边情况
   test1();

   //测试const放在*的右边情况
   test2();

   //测试*的左右两边都有const 
   test3();

   return 0;
}

结论:

• const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变,但是指针变量本身的内容(地址)可变。

• const如果放在*的右边,修饰的是指针变量本身,保证了指针变量本身的内容(地址)不能修改,但是指针指向的内容,可以通过指针改变。

• const如果在*两边都有,那么指针变量本身的内容(地址)以及指针指向的内容都不能改变。

关于C语言中常见的3种修饰符就介绍到这里,如有疏漏不当之处,欢迎各位大佬斧正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值