博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
左值、右值、指针、传址、传值与数组
阅读量:6801 次
发布时间:2019-06-26

本文共 2709 字,大约阅读时间需要 9 分钟。

左值

左值指等号(=)左边的值,它是一个对象。表示存储区域里面的一个位置,即指内存中存储数据的那块地址;并且将locator定义作为左值的定义左值。通常都是标识符(标识符由字母、数字、下划线_组成。例如一个函数add(),那么add就是一个标识符)。左值(标识符)可以修改值,但是可以修改,但左值不能具有数组类型、不完整的类型或带[1]const 特性的类型.

以下任一 C 表达式可为左值表达式:

  • 整型、浮点、指针、结构或联合类型的标识符

  • 计算结果不为数组的下标 ([ ]) 表达式

  • 成员选择表达式(–> 或 .)

  • 不引用数组的一元间接寻址 (*) 表达式

  • 包含在括号内的左值表达式

  • const 对象(不可修改的左值)

右值

右值指等号(=)右边的值,表示左值存储位置里面的值,即数据值。唯一值得注意的,有左值就一定有右值,但有右值不一定得有左值。例如:

a++(右值):

有一个临时变量指:

int temp =a;temp=a+1;return temp;

++a指代(左值):

a=a+1return a

而且左值是非临时对象,右值则是临时对象。右值只有在所在的当前语句有效。

地址

在计算机中,每一块内存的位置都有它自己的地址(唯一),地址的第一位是0,第二位是1,第二位是3依次类推。内存的地址就像是一本书籍的索引,而书的正文内容就是值。例如当在全局声明一个变量:

float f;

这条语句其实就是在告诉计算机:“声明一个叫f的位置,这个位置可以存放一个浮点型的值”。当这段程序运行的时候计算机会把变量f存储在内存的某个地方,并且这个地方的地址在内存里面是固定不变的地址(但是值的存放地点是可以改变的)。假如f的地址是0x000200,当创建一个赋值的时候,如下:

f=3.14

在程序运行的时候,编辑器会把它翻译成:“把3.14加载到一个叫f的地方,这个地方的地址是0x000200”。

计算机总是通过地址去存储或查找值。

指针

指针是指向内存的址的标尺。

#include 
int main(){    int i,j;    int *p;   /* int型的指针 */    printf("%d  %d\n", p, &i);    p = &i;    printf("%d  %d\n", p, &i);    return 0;}

运行上面这段代码得到的结果是:

0  118034660118034660  118034660

上面这段代码是:当声明一个int型的指针p的时候,因为指针p没有初始化,所以它的地址起始值是0或者是一些随机值.当代码执行到p = &i的时候,就把i的地址赋值给了p.这样p指向的地址与i指向的地址是一样的。

传址与传值

#include 
int main(){    int i;    int *p;       p = &i;    *p=5;    printf("%d %d\n", i, *p);    return 0;}

上面代码中的p = &i就是把i的赋给p,那么p指向的地址与i指向的地址是相同的。最后输出的结果是

5  5

上面的结果相同的原因是因为把p指向的地址,该地址的值赋值成5。因为p与i指向同一地址所以最后i的结果也是5.

数组

数组是拥有固定大小或固定范围地址的内存存储区间。只能存储固定大小的值;

#include 
int main (){   double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};   double *p;   int i;   p = balance;       printf( "Using pointer\n");   for ( i = 0; i < 5; i++ ){       printf("*(p + %d) : %f\n",  i, *(p + i) );   }   printf( "array value using balance as address\n");   for ( i = 0; i < 5; i++ ){       printf("*(balance + %d) : %f\n",  i, *(balance + i) );   }   return 0;}

上面这段代码是声明一个指向数组的指针,p=balance是的意思是告诉计算机把指针指向数组的起始位置。这样指针p的指向的地址与数组balance指向的地址都是一样的:

Using pointer*(p + 0) : 1000.000000*(p + 1) : 2.000000*(p + 2) : 3.400000*(p + 3) : 17.000000*(p + 4) : 50.000000array value using balance as address*(balance + 0) : 1000.000000*(balance + 1) : 2.000000*(balance + 2) : 3.400000*(balance + 3) : 17.000000*(balance + 4) : 50.000000

形参与实参

形参指变量,不确定的参数就相当于指针与数组一样,一块存储区间,但是值可以是与形参同类型的任意值;

实参指常量,确切的值。

int add(int x,int y){    return x+y;}int mian(){    printf("%d\n",add(1,2));}

上面代码中的x,y是形参也是变量,1与2是实参也是常量。

作用域

作用域指代改对象的有效范围:

int add(int x,int y){    int a=1;    return x+y+a;}int subtract(int x,int y){    return x-y+a;}int mian(){    printf("%d\n",add(1,2));}

上面代码中的i在add函数中有效,但是在subtract函数中使用就会报错。a的作用范围只在add函数里面并不会逃离到subtract里面。

 参考文献:

[1] CONST关键字:http://baike.baidu.com/subview/1065598/5048428.htm

转载于:https://my.oschina.net/websec/blog/368933

你可能感兴趣的文章
动画绘制水波纹
查看>>
安装xenomai的记实
查看>>
梦幻星空动画
查看>>
用Easing函数实现碰撞效果
查看>>
Python简介
查看>>
泛函编程(13)-无穷数据流-Infinite Stream
查看>>
XML与HTML
查看>>
[Java 泥水匠] Java Components 之二:算法篇之项目实践中的位运算符(有你不懂的哦)...
查看>>
[android]android自动化测试十之单元测试实例
查看>>
Java SecurityManager
查看>>
谁说阿里云不能跑Oracle,让驻云架构师告诉你怎么办!
查看>>
[LeetCode]*84.Largest Rectangle in Histogram
查看>>
[华为机试练习题]8.汽水瓶
查看>>
PostgreSQL 某单机插入性能测试 1200万行/s, 4.2GB/s
查看>>
taskset - retrieve or set a process's CPU affinity (affect SYSTEMTAP TIME)
查看>>
坏消息:Flutter官方暂时不会开发热更新(Code push)了。
查看>>
webpack4.x实战四,js和css独立打包
查看>>
数据一致性(一) - 接口调用一致性
查看>>
使用 core.js 解决 GraphQL Mock Server 跨域问题
查看>>
达文西,我要的是属性节点,不是属性!
查看>>