左值
左值指等号(=)左边的值,它是一个对象。表示存储区域里面的一个位置,即指内存中存储数据的那块地址;并且将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