指针和指针变量
指针就是地址,地址是一种数据类型。指针变量也是变量,但只能存放地址类型的数据,可以称为“地址型”变量。
1)内存单元和地址
一个程序运行时,程序本身和程序中用到的数据都要保存在计算机的内部存储器中。内部存储器是由多个内存单元(字节)组成的,每个单元都有自己独有的,相互不同的地址,称内存单元地址。
2)变量与地址。
char ch=‘A‘; short s =5; float f; 他们分别是1个字节,2个字节,4个字节。(也就是内存单元)
如果出现这样的赋值语句“f=s+ch;”,操作过程是:
1.在变量地址对照表中找到变量a,取出s的地址(2010),考虑到其数据类型是短整型,所以从该地址开始的2个字节中取出1个整数(5);
2。根据同样的方法去除变量ch中的字符‘A’(想当于整数65),相加获得表达式的值为70.
3.然后再变量与地址对照表中找到变量f的地址,考虑到其数据是单精度型,所以将结果70转换成单精度实行的70.0,再存入变量f对应的4个字节中。
以上操作,通过变量名查取变量的地址,再从变量对应地址的字节中取得值或将某值存入变量对应地址的字节中称为直接存取方式,由于地址能起到寻找“操作队形”的作用,就像一个指向“操作对象”的指针,所以常把地址称为“指针”。
3)数组与地址
除了变量以外,程序中还可以用数组来存放数据。每个数组元素也要占用连续的内存单元。一个数组占用的总字节数等于数组长度乘以每个数组元素占用的字节数。
在源程序进行编译时,每遇到一个数组,按其数据类型和长度分配内存单元,同时在“数组与地址对照表”中记录数组名、数据类型、数组长度、数组首地址。
例如这个语句 short a[3]={1,2,3};
在数组地址对照表中找到数组a,取出首地址,按公式计算出数组元素a[0]的地址:3210+0*2=3210,从该地址开始的2个字节(3210、3211)中取出整数1;按相同的方法取出数组元素a[2](地址是3210+2*2=3214)中的整数3,进行相加,得到结果4.然后通过公式计算出a[1]的地址:3210+1*2=3212,再将计算结果4存入3212开始的2个字节(3212、3213)中。上述操作中,通过查表获得数组首地址,通过计算元素地址的方式先获得元素的地址,然后通过这个地址取得元素的值,或将值存入元素的方式也是直接存取方式。
4)指针变量
先把要存取的变量的地址存入一个“特殊变量”,然后通过这个其值为地址的“特殊变量”来存取变量的值,这种存取方式由于通过一种存放地址的“特殊变量”来实现的,所以称为间接存取方式。
这种存放地址值的“特殊变量”就是指针变量。
使用指针变量:
通过间接存取方式完成赋值语句“a[1]=i*j;”的操作。事先将变量i、j和数组元素a[1]的地址分别存入指针变量p_i、p_j、p。以后的操作过程如下:先从指针变量p_i中取出i的地址,再从内存该地址中取出变量i的值;按同样方法,通过指针变量p_j取出变量j的值进行相乘;再从指针变量p中取出数组元素a[1]的地址,将运算结果存入内存的该地址中。
指针变量的使用方式
1)给指针变量赋值
格式为:指针变量=地址型表达式。
取地址的运算符是“&”,运算对象是变量或数组元素名,运算结果是对应变量或数组元素的地址。
例如:变量 i 的地址应写成地址表达式“&i”,数组元素a[1]的地址应写成地址表达式“&a[1]”。
注意:虽然地址是一个整数,但是,在C语言中不允许把整数看成“地址常量”。所以这的“地址型表达式”不能是整数。
例如:int i , *p_i
p_i = &i //使指针变量p_i指向变量i,这的&i 就是地址型表达式。
p_i = 100; //企图使指针变量p_i指向地址为100的内存单元,这是错误的。
2)直接使用指针变量名。
需要用到地址时,可以直接引用指针变量名。
例如:int i,j, *p=&i,*q;
q=p; //将指针变量p的值(i的地址)赋予指针变量q。
scanf("%d,%d",q,&j); //使用指针变量q接受输入数据存入q指向的变量i。
3)通过指针变量来引用它所指向的变量。
使用格式为:*指针变量名。
例如:int i =1,j=2,k,*p=&i;
k=*p+j; //由于p指向i,所以*p就代表i,结果k等于3.
注意:取地址运算符的运算对象必须是已定义过的变量或数组元素,但不可以是数组名。运算结果是运算对象的地址。例如,定义了变量a,数组b[10],则&a,&b[0],&b[9]均合法,分别代表变量a地址,数组元素b[0]的地址,数组元素b[9]的地址;而&b则是错误的。
(未完。。。。)