C语言(4)/static关键字 与 内存分布

目录

​编辑

一、关键字

Ⅰ、static关键字

① 、static修饰局部变量

②、static修饰全局变量

③、static修饰函数(与修饰全局变量同理)

 Ⅱ、(define)定义常量和宏

①、定义常量与宏 

二、内存(指针)

Ⅰ、从内存条到指针

①、内存条

②、指针和指针变量的大小

③、指针解引用操作(* 解引用操作符)

三、拓展:大小端字节序

四、原码,反码,补码

Ⅰ、原码

Ⅱ、反码

Ⅲ、补码 


前言

以下内容使用Visual Stdio 2022集成开发环境,配置环境为debug版本32位操作数。


 读前须知

①c语言常见内存分布 

②由代码到可执行程序需要经过 编译——>链接——>可执行程序


正文 

一、关键字

Ⅰ、static关键字

    ① 、static修饰局部变量

static修饰局部变量的时候改变了局部变量的存储类型:本来一个局部变量是存储在栈区的,而被static修饰的局部变量是存储在静态区的。

存储在静态区的变量出了它的作用域(以下例子add函数为z的作用域)变量也不销毁,所以生命周期较长,但是局部变量的作用域是不被改变的。如果想在作用域外部调用这个静态变量,则需要传出(返回)静态变量的地址。

 static修饰的变量生命周期与程序的生命周期相同,即程序运行完毕static修饰的变量才销毁。

正常情况下:

 而被static修饰之后:

 

 ②、static修饰全局变量

static修饰全局变量的时候,改变了全局变量的链接属性

本来一个全局变量是具有外部链接属性的,但是被static修饰之后就变成了内部链接属性。这时static修饰的全局变量只能在本源文件(.c)中使用,其他文件无法使用。

 :内外部链接属性:一个源文件能否通过代码使用另一个源文件中的变量或者函数。能使用就称这个变量(或函数)具有外部链接属性,不能的话就称这个变量(或函数)具有内部链接属性

正常情况:

 外部符号被static修饰:

:extern关键字是用来声明外部符号的。 

③、static修饰函数(与修饰全局变量同理)

 static修饰函数和修饰全局变量是类似的,一个函数本来也是具有外部链接属性的。当被static修饰的时候,外部链接属性就变成了内部链接属性,这个函数就只能本源文件内部使用,其他文件不能使用了

正常情况: 

 被static修饰后:

 Ⅱ、(define)定义常量和宏

①、定义常量与宏 

 

 注:定义的常量,在源文件编译时,编译器做的第一步就是将define定义的常量替换文件中所有出现常变量(例如SUM)的位置

 注:定义宏的时候每个变量都要加上括号,因为宏变量是直接替换表达式,可能会遇见操作符优先级跟预想中的不一样,导致出错,例如:

 

 原本你想ADD(1,1)返回的应该是2,输出为4,但是这里是,应该替换表达式,所以

a = 2 * 1 + 1 = 3;

二、内存(指针)

Ⅰ、从内存条到指针

①、内存条

内存条如下:

 

:0x是十六进制的前导,意思是表示后面一串数字是十六进制的形式

 地址怎么来的?————><地址详解>

比如我们创建一个int类型的变量b,与一个char类型的变量c:

 ②、指针和指针变量的大小

 指针就是地址,一串二进制,如上图(32位操作系统)0xFFFFFF11 就是二进制的

11111111 11111111 11111111 00010001

每个指针都指向一个字节,就把一个字节看作一个房间,地址(指针)就是这个房间的门牌号。

指针变量的大小由操作系统或者由配置的地址操作数决定

32位操作数的指针变量大小为4个字节,64位操作数的指针变量大小为8个字节如:

32位操作数:11111111 11111111 11111111 11111111

                    (32位,4个字节)=0xFFFFFFFF

64位操作数:11111111 11111111 11111111 11111111 

                      11111111 11111111 11111111 11111111

                      (64位,8个字节) =0xFFFFFFFF FFFFFFFF 

(稍微能理解为什么64位操作数的软件为啥不能兼容32位的了吧!)

 ③、指针解引用操作(* 解引用操作符)

如下代码和内存分布:

b的二进制为:00000000 00000000 00000001 00000000

c存放的是b的首个字节的地址:0xFFFFFF11

解引用就是访问c指向的字节,具体访问多少字节由指针变量的类型决定

 指针变量c的类型为char* ,那么c解引用只访问一个字节,也就是说*c = 00000000 等于十进制的0,其他类型比如 int*解引用访问内存中4个字节,由此可以做到一些特殊操作(以后再介绍)。

 注:1、Visual Studio采用的是端字节序,底位字节放在底地址处,高位字节放在高地址处

三、拓展:大小端字节序

小端字节序:数据的低位放在低地址处,数据的高位放在高地址处。(我们使用的vs使用的就是小端存储)

 大端字节序:数据的低位放在高地址处,数据的高位放在低地址处。

四、原码,反码,补码

 注:内存条中存放的都为补码

Ⅰ、原码

原码是字面值的二进制,比如

255的原码是  00000000 00000000 00000000 11111111

-255的原码是 10000000 00000000 00000000 11111111

(有符号二进制的第一位是符号位,0表示数据为正数,1表示负数)

 Ⅱ、反码

 反码是在原码的基础上,除了符号位,其他位按位取反,比如

255的反码是  00000000 00000000 00000000 11111111

-255的反码是 11111111 11111111 11111111 00000000 (1比0窄,这里没问题)

:正数的原码、反码和补码都是相同的。

Ⅲ、补码 

补码是在反码的基础上加一,比如

255的反码是  00000000 00000000 00000000 11111111

-255的反码是 11111111 11111111 11111111 00000001 (1比0窄,这里没问题)

(补码也是存放在内存中的数据)

原码、反码与补码的转换关系:

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒夕君哎

动力+99(*•̀ᴗ•́*)و

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值