关于C语言的 变量 地址 和 值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于C语言的 变量 地址 和 值相关的知识,希望对你有一定的参考价值。

变量 地址 和 值的关系式啥 ?

通过变量来访问值的时候,会经过地址码 ?

变量和地址是啥关系?

别告诉我 变量名 可以访问到值
&变量名可以访问到地址
*地址可以访问到值
这些我都知道

我想知道 内存中的访问顺序;

或说他们都是怎么执行的

或收他们都是怎么指向的

我老觉得 访问一个东西 不知道地址 很难实现 应为那样就成收索了

以下是个人理解:
变量具有类型,而类型是编译器用来分配存储空间的模板,比如int型分配4个字节,也就是分配了32位。所以,定义一个变量并不代表分配了一个空间,只是定义了一个分配模板。
只有使用了已经定义的变量,才为其分配空间,如int i=0;
分配空间给所定义的变量和使用变量,两个的本质是一样的,并且分配了空间就是使用变量来存储数值。而存储了值的那个变量的空间是内存里的存储单元,所以变量在内存中有一个地址,这个地址是随机的,也只有使用变量时候才分配的。
其实,直接访问变量就是直接访问一个地址,等价于访问一个指针,如果一个变量里存储的值是另一地址,那么就把这个变量当做指针!
本质上,指针和变量没有任何区别,他们的区别在于:为指针分配的地址空间是固定的,如32位机器就分配32位,64位机器就分配64位;而为变量分配的地址空间是因不同约定的类型的不同而不同的,这里说的是约定的类型,如int分配4个字节,long int分配8个字节,float分配4个字节。
(以上的一些变量类型所占的字节是因为编译平台和编译机器不同而会有所区别,但现在的机器和平台几乎都是如此的。)
参考技术A 地址和指针是紧密相连的,首先值是放在内存中的一个区域,而内存中的区域都会有不同的编号,这些编号可以认为就是地址。
例如:int* a是指针变量,int b=3,
a=b,则是错误的,此时a是不等于3的,因为a是指针变量,你不能把b的值赋给它。应该是
b的地址
a=&b,就是正确的,此时a存放的就是b的值在内存中的地址
如果你输出printf(“%d”,a)与printf(“%d”,*a) 结果是不一样
前者输出的是b在内存中的地址,后者输出的是指针a 指向b的地址的值(即b的值3)追问

更没说一样!

参考技术B 把内存看成是一个一个的格子
往内存中放数据就是往格子里放
每个格子对应一个编号
这个编号就叫做地址
所以通过地址可以确定格子
也就是确定格子里的数据

而变量是有类型的
类型决定的是格子的个数
比如int
那么一般可以确定4个格子
所以使用变量名,就相当于访问这4个格子

仅供参考 个人理解追问

更没说一样

参考技术C 要想很好的理解去看看,编译原理吧
人家在编译的时候,要维护一个符号表的
比如一个变量,int a;
就有相应的 a这个符号对应的在内存中的偏移地址
当你在使用这个符号的时候,在相应的指令直接就插入它的偏移地址
参考技术D 关于这个问题我也很困惑。我最不解的是到底地址和存储空间哪个能访问到值,书上这么说的比如
int a=12,*p=&a,从这里开始,看吧:*&a==a成立,并且&*p==p也成立。前者是指向a的地址的指针却跟a本身等同了,指向地址的指针跟值有什么关系呢?后者是指针的地址跟p的地址等同了。p的地址是指针p的地址,p表示p存储的地址是a的地址,两者地址i怎么能等同呢?
====================
根据书上的解释,貌似存储空间就是值。比如int a=12,那么变量a的存储空间就是a,也就是12.这个可能要看看关于变量的定义了。
====================
更正一下这个答案。任何变量,都是一个代表,所代表的东西在CPU里,就是地址和值两个东西。当*(指针符号)加在变量前面的时候,就代表了对变量(此时变量代表一个地址)取值;当&(地址符号)加在变量前面的时候,就代表了对变量(此时变量代表一个值)取地址。

通过C学Python关于语言数值类型和变量

强类型语言,不可能出现“程序执行出错后仍可继续执行,并且该错误导致的问题使后续执行可能出现任意行为”这类错误,这类错误的例子,如C里的缓冲区溢出、Jump到错误地址。

弱类型语言,类型检查更不严格,如偏向于容忍隐式类型转换。例如C语言中int类型和double类型的隐式转换。(个人认为int型和指针型的自由转换,以及union中的一个int对4个char更能说明问题)

静态类型语言,在编译时就拒绝类型错误导致的问题

动态类型语言,在运行时才报出类型错误

C语言是弱类型、静态类型

python是强类型,动态类型

 

 

数值类型:

整型 int 

C中整型数据按照内存占用有好多种,python里面只有一种

浮点型 float

C中有float和double两种,python里面只有一种

布尔型 bool

C中用宏TRUE和FALSE对应常量1和0,在python中True和False是属于单独的数据类型bool,但是内部实现依然是1和0,例如:1+True==2,1*False==0

 

复数型 (在python中用小写 j ,表示虚部,用其他的字母不行)complex

C中没有这个类型,需要自己定义一个结构体和一系列运算函数,但是C99/C++有添加这种数据类型。python中有这个数据类型,就可以很方便的进行复数运算

空类型 NoneType

C中用宏NULL表示空,对应常量0,在python中None是属于单独的数据类型NoneType,与常量0不同,不能与数值做运算,其实这也并不能算作数值类型

数值运算常用运算符:

+ - * %加、减、乘、取模,和C都一样
/ 除,即使是两个整型数据相除,得到的结果也可能是浮点数

// 整除,向下取整,和C语言中的整型相除效果一样,没有小数部分

** 乘方(幂),C对应的函数是pow,当然直接用乘方运算符用起来会更好看且易于理解

赋值运算符 :
= += -= *= /= //= 等...  和C的用法基本一致,python没有++,自增1要用+=1

 

变量:
Python的变量无需事先声明,无需指定类型,但是每个变量都是有类型的

Python中每个变量、常量都有一个id,可以通过内置函数id()来取得,通过这个函数可以看到一些特性:

实验一:a = 2  ,b = 2 ,这时分别查看id(a)、id(b)、id(2)可以发现,他们三个的值是一样的,就好像是三个指针指向了同一个地址,而这个地址上的数据就是2

实验二:a = 1 ,id(a) , a = 2, id(a) ,这时可以看到,a的id发生了变化,也就是说这两个a并不是同一个a了

通过这些现象来看,变量a、b并没有用独立的存储空间去存放值,而更像是指针,指向了一块内存区域,id()就是取出来目标地址,而在取变量a的值的时候,先通过id(a)找到目标地址,再把目标地址存放的数据取出来

经过我的测试实验,True\False\None的id都是固定的,整型数据中从-5到256的id也是固定的,符合实验一的现象,既分别给a和b赋同一个常量值,他们的id是一样的,但是如果查出这个范围,比如-6,进行下一个实验

实验三:a = -6,b = -6,这时id(a) == 2518190220080,id(b) == 2518190220496,两个变量的id不同,但是值相同,说明他们的值分别另外开辟了空间,存储了相同的值-6

实验四:在实验三的基础上,b=a,这时id(a) == 2518190220080,id(b) == 2518190220080,他们的id相同,指向了同一个地址。

经过实验,把-6换成浮点数、元组和列表,也符合实验三和实验四

实验五:a=[1,2],b=a,a.append(3),这时,id(a)和id(b)相同,并且b的值也变成了[1,2,3],这验证了上面说的,变量其实并没有存放变量值,而是存放了目标地址,取变量值的时候,先去目标地址,再把值取出来




以上是关于关于C语言的 变量 地址 和 值的主要内容,如果未能解决你的问题,请参考以下文章

通过C学Python关于语言数值类型和变量

在c语言编程中,传值方式和传引用方式之间有啥区别?

C语言关于取值和取址

C语言指针学习总结

C语言中关于枚举类型

汇编语言调用c语言