C语言复习(4)变量

在这里插入图片描述
大家好,我是米兰,一个五年级开始编程的小伙。我曾经研究过各种技术,在代码底层摸爬打滚,经历过无数次从入门到放弃的生活,感受过黑暗与毒打。如果你也有相同的经历和探究的问题,欢迎关注我,咱们共同探究,共同进步。废话不多说,送货!在这里插入图片描述

变量的含义

在C语法中,变量是可操作的内存块,在程序内部使用标识符区别各个独立的变量,标识符应用于不同实体上有不同的名称。如变量标识符被称为变量名,函数标识符被称为函数名,每个变量都是一个独立的实体具有自己的数据类型,类型规范并告知编译器在执行编译操作时设定分配给变量的占用空间储存布局,占用空间进一步规范了变量的可容数据以及取值范围
本节将对内存变量的应用展开相关讨论。在实际的C程序开发中,尽管操作系统为了简化编程步骤,屏蔽了系统底层的实现机制,如内存映射和管理,其间涉及一系列复杂的实现算法,但我们还是不可避免地和内存打交道。在C中,内存管理被大量应用,其中最典型的就是指针变量,这是间接操作内存块最常用的途径。内存究竟是什么?变量在内存中是如何储存的?

内存

在日常生活中,我们会使用各种软件以满足自己的需要,这些软件均安装在硬盘上,硬盘容量通常很大,如经常听说的500G机械硬盘,2TB固态硬盘等。硬盘在储存海量数据时,有一个很重要的特性就是断电后数据不会消失,硬盘占用这个优势的同时也有自己的不足,就是读写速度太慢,特别是机械硬盘。众所周知,CPU集成电路的运算速度是相当快的,如果CPU处理的数据每次都要从硬盘读取,将严重拖慢操作系统的处理速度,使得CPU存在大量饥饿时间,恶化用户体验,所以上述的机制不可取。内存条图片来自|网络
为了尽可能地减少读写数据造成的时间延迟,在CPU和硬盘之间还存在内存内存读写速度相对硬盘更快,但断电后数据会消失。此外,CPU还存在多级缓存,缓存容量较内存更小,但速度更快,路程更短,CPU的运算单元在读取数据时,会优先在缓存中读取,如果缓存中并没有没有相关数据,CPU就会到内存寻找,这关乎到CPU的命中率,在操作系统内部有一系列的算法指导其有序地执行。
在程序运行时,程序的二进制代码以及相关数据会被读取到内存中,变量的创建,读写,销毁均发生在内存中。换言之,程序是在内存中运行的

变量在内存中的储存

内存中的基本单位是位(bit),8个位组成一个字节(byte),每个字节均有属于自己的地址,方便对内存块执行读写操作。变量作为一个可操作的独立实体,在内存中除了单字节类型(如char类型),单个变量占用连续的字节。程序上下文间的变量可能是紧密排列的,也可能是期间存在其他实体,但内存中的实体一般是紧密排列的,排除编译器执行优化操作,为了方便CPU寻址而进行内存对齐
编译阶段变量的类型就已经确定了,类型指定了变量的储存大小以及储存布局,基本类型的变量如int,它的内存布局如下:
在这里插入图片描述
由图可知,int类型的变量占用4字节。同一个变量,每一个字节在内存中实际上都是首尾相接的排列,在内存中占用连续的空间。
其他类型如浮点类型的布局与整形有所差异,float是单精度浮点类型,在内存中由1位符号,8位指数,23位小数组成。合计32位,即4个字节。float的内存布局如下:在这里插入图片描述
图片来自|网络
double是双精浮点类型,在内存中双精度是1位符号,11位指数,52位小数。如图所示:
在这里插入图片描述图片来自|网络
此外,还有枚举、指针、数组、结构、共用体等其他类型,它们的内存布局各有差异,以后会有提及。

变量的定义

在程序内部经常要执行一系列不同的运算,以实现不同的效果。为了将运算结果临时性存储,以方便在下文以各种方式继续使用该值,我们需要定义变量。定义变量就是在内存中划分出内存块供我们用于各种用途,所以定义变量需要告知编译系统用户需要的内存块的大小以及储存的数据布局等。实现上述操作,只需要表明相关的数据类型即可,另外需要使用标识符标记内存块,以方便在下文进行引用该内存块,变量定义的语法如下:
type variable_list;
type 一个有效的C数据类型,例如char类型。
variable_list 由单个或者多个标识符组成的列表,多个标识符同时存在是以逗号分隔,在同一个列表上所有被定义的变量类型均为type类型

初始化变量

在实际的开发中,很多变量在定义时就应该有其初始值。为了简化代码,定义变量时可以使用初始化器对变量进行初始化,初始化器由赋值运算符(=)和单个常量表达式组成。type variable_name=value;如果同时定义多个变量时需要时初始化整个列表的变量,则需要使用多个初始化器:
type variable_name1=value1,variable_name=value2...;
不带初始化的定义带有静态存储持续时间的变量会被隐式初始化为 NULL(所有字节的值都是 0),其他所有变量的初始值是未定义的。

外部变量

以外部定义形式定义的变量,称为外部变量。外部变量允许先使用后定义,声明外部变量使用关键字extern,按照以下形式:
extern type variable_list;
外部变量与函数类似,若想先使用后定义,必须作出声明,而且外部变量必须存在实体,否则将在链接阶段出现错误,外部变量常用于在另一个源文件中定义而被其他文件使用,注意不可以在同一级域中同时出现外部变量的声明以及其实体的定义,否则就会出现错误,错误信息通常是没有链接变量声明跟随外部声明,因为这种做法违背了外部变量建立的初衷。
外部变量定义时如果没有使用初始化器对其进行初始化,将会默认赋予初值为NULL
此外,静态变量以及全局变量也会自动初始化为NULL,静态变量分为局部静态变量外部静态变量,这就在后面函数章节以及C作用域处作出讨论。

变量的声明

声明是告知编译器变量的存在,需要指明其类型以及名称,这样编译器在不知道完整细节的情况下也可以继续编译。注意变量的实际定义必须存在,编译时变量声明后在下文的使用均是有效且存在意义的,但如果链接时候没有存在对应的定义实体,变量声明以及下文的使用都会失效且报错,变量的声明分为两种:

附带定义的声明

若想在下文使用变量,可以选择定义相关变量,定义相关变量后变量的标识符和类型将写入程序内部的符号表,并且在内存开辟和划分相对于该变量的内存区域,在下文只要是有权限访问此变量的,出现相关标识符时就会定位到该变量的内存区域,所以定义变量的同时也是声明变量,这是附带定义的声明。

仅作声明

在使用外部变量的关键字extern时,只是注册了一个可用于下文的标识符,并向编译系统提供该标识符的相关信息。编译器会假设该变量的存在,使用extern关键字修饰的变量仅作声明而不定义,变量实际定义可以是当前项目的其他工程文件中涉及

addtwonum.c 文件代码:
#include <stdio.h>
/*外部变量声明*/
extern int x ;
extern int y ;
int addtwonum()
{    
return x+y;
}

test.c 文件代码:

#include <stdio.h>
  /*定义两个全局变量*/
  int x=1;
  int y=2;
  int addtwonum();
  int main(void)
  {    
  int result;    
  result = addtwonum();    
  printf("result 为: %d\n",result);    
  return 0;
  }

左值和右值

左值(lvalue)

指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。

右值(rvalue)

术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。

实例

#include<stdio.h>
int main()
{    
int Window_variable=2;    
return 0;
}

分析

Window_variable是一个变量,可以使用赋值运算符(=)对其进行赋值运算,标识符Window_handle实际指向一个内存区域,该内存区域上的数据的属性是可读写的,所以变量是左值的一种,可以位于赋值运算符的左侧或者右侧。
数值2是一个字面常量,可以将其理解为一个特殊标识符,其实这种标识符是非法,因为标识符不可以以数字作为首位,所以这是一个特殊的标识符。2的值就是2,它的属性是只读的,所以不可以使用赋值运算符对2进行赋值,下面的语句是非法的:10=2;
对于这些只可以放在赋值运算符的右侧的实体,被称为右值在这里插入图片描述今天的教程就到这里了,如果你觉得有收获,不要忘了关注收藏和转发,希望我的教程可以帮助到更多的人,咱们下期不见不散。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值