左值、右值、指针、传址、传值与数组

左值

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

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

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

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

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

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

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

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


右值

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

a++(右值):

有一个临时变量指:

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

++a指代(左值):

a=a+1
return a

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

地址

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

float f;

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

f=3.14

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

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

指针

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

#include <stdio.h>

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  118034660
118034660  118034660

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

传址与传值

#include <stdio.h>

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 <stdio.h>
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.000000
array 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值