指针变量定义及引用

1指针是什么

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元空间。

编译系统根据程序中定义的变量类型,分配一定长度的空间。

内存的管理将内存抽象看作一个很大的一维字符数组,对内存中的每一个字节分配一个32位或64位的编号(与32位或者64位处理器相关),把对这个编号分配称之内存处理。

例如, 为整数变量分配4个字节(32位),为单精度浮点型变量分配4个字节,为字符型变量分配1个字节。内存区的毎一个字节有一个编号,这就是“地址”。在地址所标志的内存单元中存放的数据,由于通过地址能找到所需的变量单元,地址指向该变量单元。将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元。

在 C 语言中,数据是分类型的,对不同类型的数据,在内存中分配的存储单元大小(字节数)和存储方式是不同的。如果只是指定了地址1010,希望从该单元中调出数据,这是做不到的,虽然能找到所指定的存储单元空间地址,但无法确定是从1个字节中取信息(字符数据),还是从2个字节取信息(短整型),抑或是从4个字节取信息(整型),未说明按何种存储方式存取数据(整数和单精度实数都是4个字节,但存储方式是不同的),只知地址根本提取不了。为了有效地存取一个数据,除了需要位置信息外,还需要有该数据的类型信息(如果没有该数据的类型信息,只有地址位置信息是无法对该数据进行存取的)。 C 语言中的地址包括位置信息(内存编号)和它所指向的数据的类型信息,或者说它是“带类型的地址”。如&a ,一般称它为“变量 a 的地址”,确切地说,它是“整型变量 a 的地址”。

内存空间随使用随时分配,不用立即释放空间,这说明依靠地址找到存放在地点,根据类型找到存放位置,按随用随分配,不用立即让出,以是否工作确定是否分配空间,说明根据地址及指向变量类型确定首个对象就是存取对象,因此指针变量既要地址及指向对象的类型。

若有 int 型变量 a 和 float 型变量 b ,如先后把它们分配在2000开始的存储单元中,&a 和&b的信息是不相同的,虽然存储单元的地址编号相同,但它们的数据类型不同,存取编号地址相同,但是存取位置小地点(存储单元内容类型)是不同的。

区分数据类型的本质作用,是为了合理的利用内存空间。基本类型:char,short,int,long,float,double,

char占用1个字节空间

char ch;

printf( " sizeof (ch)=%d\ n ",sizeof( ch));

//ch占一个字节

int num;

printf( sizeof (num)=%d\ n ",sizeof( num)); //4个字节

1Byte存放8位二进制位

1bit只能存放 0或1

指针变量:

编号(地址):内存中每一个字节分配一个编码,

定义一个变量存放上面的号码这样的变量叫做指针变量。

存储单元的地址和存储单元的内容是有区别,假设程序已定义了3个整型变量 i,j,k ,在程序编译时,系统可能分配地址为2000~2003的4个字节给变量i,2004~2007的4个字节给 j,2008~2011的4个字节给 k (不同的编译系统在不同次的编译中,分配给变量的存储单元的地址更是不相同的,因为随用随分配,用完即让出空间)。

在程序中一般是通过变量名来引用变量的值,这里指输出。例如:

printf ("% d \n", i );

由于在编译时,系统已为变量 i 分配了按整型存储方式的4个字节,并建立了变量名和地址的对应表,因此在执行上面语句时,首先通过变量名找到相应的地址,从该4个字节中按照整型数据的存储方式读出整型变量 i 的值,然后按十进制整数格式输出。

注意:对变量的访问(这里指录入数据,输入变量值对应地址,直接存入数据到对应地址)都是通过地址进行的。

假如有输入语句

scanf( "% d ",&i);

在执行时,把键盘输入的值送到地址为2000开始的整型存储单元中。如果有语句

k=i j;

则从2000~2003字节取出 i 的值(如i=3),再从2004~2007字节取出 j 的值(如j=6),将它们相加后再将其和(k=9)送到 k 所占用的2008~2011字节单元中。

这种直接按变量名进行的访问,称为“直接访问”方式。

还可以采用另一种称为“间接访问”的方式,即将变量 i 的地址存放在另一地址变量中,然后通过该地址变量来找到变量 i 的地址,从而访问 i 变量。

在 C 语言程序中,可以定义整型变量、浮点型(实型)变量、字符变量等,也可以定义一种特殊的变量,用它存放地址。假设定义了一个变量 i_pointer (变量名可任意取),用来存放整型变量的地址。可以通过下面语句将 i 的地址(2000)存放到 i_pointer 中。

//将 i 的地址存放到 i_pointer 中i_pointer =& i ;(把对应地址赋值给地址变量,不是指针变量,是专门存地址编号的变量,类似普通变量,未赋值*p的指针变量p=&i,是间接访问。

这时, i _ pointer 的值就是2000(即变量 i 所占用单元的起始地址,变量占4字节)。根据存储空间编号起始址加上类型决定的长度,间接存取指定变量。

void test()

int num =100;

//取变量的地址用&

// &num 代表标量 num 的起始地址

int *p

printf (" p \ n ", &num );

//定义一个指针变量,保存 num的地址

//在定义的时候:*说明 p 是指针变量,而不是普通变量 int *p= null;

printf (" sizeof ( p ) =d \ n ", sizeof ( p ));

// num的地址与p建立关系

p=&num ;

printf (" num = d \ n ", num );

//使用中;*p表示取 p 保存的地址编号对应空间的内容

printf (" p = d \ n ", *p );

//100

要存取变量 i 的值,既可以用直接访问的方式,也可以采用间接访问的方式:先找到存放“变量 i 的地址”的变量 i_pointer ,从中取出 i 的地址(2000),然后到2000字节开始的存储单元中取出 i 的值。

直接访问:根据变量名直接向变量 i 赋值,由于变量名与变量的地址有一一对应的关系,因此就按此地址直接对变量 i 的存储单元进行访问(如把数值3存放到变量 i 的存储单元中)。i=3;

间接访问:先找到存放变量 i 地址的变量 i _ pointer ,从其中得到变量 i 的地址(2000),从而找到变量 i 的存储单元,然后对它进行存取访问。

为了表示将数值3送到变量中,可以有两种表达方法:

(1)将3直接送到变量 i 所标识的单元中,例如“ i =3;”。

(2)将3送到变量 i_pointer 所指向的单元(即变量 i 的存储单元),例如“* i _ pointer =

3;”,其中* i _ pointer 表示 i_pointer 指向的对象。

指向就是通过地址来体现的。假设 i_pointer 中的值是变量 i 的地址(起始地址编号为2000),这样就在 i_pointer 和变量 i 之间建立起一种联系,即通过 i _ pointer 能知道 i 的地址,从而找到变量i 的内存单元。

由于通过地址能找到所需的变量单元,因此说,地址指向该变量单元。将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元(如同根据地址2000就能找到变量 i 的存储单元一样)。

如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”。上述的 i _ pointer 就是一个指针变量。指针变量就是地址变量,用来存放地址,指针变量的值是地址(即指针)。

区分“指针”和“指针变量”这两个概念。

例如,可以说变量 i 的指针是2000,而不能说 i 的指针变量是2000。指针是一个地址(起始地址编号),而指针变量是存放地址的变量。

2指针变量

存放地址的变量是指针变量,它用来指向另一个对象(如变量、数组、函数等)。

内存区的每一个字节都有一个编号,这就是“地址”。

指针的实质就是内存“地址”。指针就是地址,地址就是指针。

指针是内存单元的编号,指针变量是存放地址的变量

任意类型的指针在32位平台都是4字节(32位)。

2.1定义和使用指针变量

例:通过指针变量访问(提取)整型变量。

先定义2个整型变量,再定义2个指针变量,分别指向这两个整型变量,通过访问指针变量,可以找到它们所指向的变量,再提取这些变量的值。

编写程序:

# include < stdio.h >

int main( )

int a =100,b=10;

int *pointer _1,pointer_2;

pointer _1=& a;

pointer _2=& b ;

printf (" a =% d,b =% d \ n",a,b );

printf (" pointer _1=% d , pointer _2=% d \ n" , *pointer _1, *pointer _2);

//定义整型变量a,b,并初始化

//定义指向整型数据的指针变量 pointer _1, pointer _2

//把变量 a 的地址赋给指针变量 pointer _1

//把变量 b 的地址赋给指针变量 pointer _2

//输出变量 a 和 b 的值

//输出变量 a 和 b 的值

return 0;

运行结果:

a =100, b=10

*pointer _1=100, *pointer _2=10;

(1)在开头处定义了两个整型指针变量* pointer _1和*pointer _2。规定它们可以指向整型变量,至于指向哪一个整型变量,要在程序语句中指定。使 pointer _1指向 a,pointer _2指向b,此时 pointer _1的值为& a , pointer _2的值为& b 。

(2)输出变量 a 和 b 的值100和10。输出* pointer _1和* pointer _2的值。其中的“*”表示“向”。* pointer _1表示“指针变量pointer _1所指向的变量”,也就是变量 a 。“ pointer _2表示“指针变量pointer2所指向的变量”,也就是变量 b 。从运行结果看到,它们的值也是100和10。

(3)程序中有两处出现 pointer _1和 pointer _2,二者的含义不同。* pointer _1和* pointer _2表示定义两个指针变量,变量名为 pointer _1和 pointer _2。它们前面的“*”只是表示该变量是指针变量。程序最后一行 printf 函数中的* pointer _1和 *pointer_2则代表指针变量pointer_1和 pointer _2所指向的变量。

定义指针变量时,左侧应有类型名,否则就不是定义指针变量。如:

int * pointer _1;

2.2怎样定义指针变量

定义指针变量的一般形式为

类型名 *指针变量名;

如:

int *pointer _ 1 , *pointer _2;

左端的 int 是在定义指针变量时必须指定的“基类型”。指针变量的基类型用来指定此指针变量可以指向的变量的类型,并不是地址类型

例如,上面定义的基类型为 int 的指针变量 pointer _1和 pointer _2,可以用来指向整型的变量 i 和 j ,但不能指向浮点型变量 a 和 b 。

基本的数据类型如 int , char , float 等,既然有这些类型的变量,就可以有指向这些类型变量的指针,因此,指针变量是基本数据类型派生出来的类型,它不能离开基本类型而独立存在。

下面都是合法的定义: float * pointer _3;

char *pointer _4;

可以在定义指针变量时,同时对它初始化,一般不在定义时赋值。如:

int * pointer _1=& a ,* pointer _2=& b ;上面程序应改写成

int * pointer _1,* pointer _2 ;

pointer _1=& a ;

pointer _2=& b ;

因为 a 的地址是赋给指针变量名为 pointer _1,而不是把a地址赋给 *pointer _1(相当变量 a本身 )。

说明:在定义指针变量时要注意:

(1)指针变量前面的“*”表示该变量为指针型变量。指针变量名是 pointer _1和pointer _2,而不是* pointer _1和着* pointer _2。这是与定义整型或实型变量的形式不同的。

(2)在定义指针变量时必须指定基类型。有人认为既然指针变量是存放地址的,那么只须指定其为“指针型变量”即可,为什么还要指定基类型呢?

要知道不同类型的数据在内存中所占的字节数和存放方式是不同的。

指向一个整型变量和指向一个实型float变量,其物理上的含义是不同的。

指針变量是用来存放地址的,C 的地址信息包括存储单元的位置(内存编号)和类型信息(存储长度)。指针变量的属性应与之匹配。

如:

int a ,* p ;

p =& a ;

& a 不仅包含变量 a 的位置(如起始編号为2000的存储单元),还包括“存储的数据是整型”的信息。现在定义指针变量 p 的基类型为 int ,

即它所指向的只能是整型数据。这时 p 能接受& a 的信息。如果改为

float * p;

p =&a ;

& a 是“整型变量 a 的地址”。

在用 Vicual C 6.0编译时就会出现一个警告( warning ):“把一个 int 型数据转换为 float 数据”。在赋值时,系统会把& a 的基类型自动改换为 float 型,然后赋给 p 。但是 p 不能用这个地址指向整型变量。可以知道指针或地址是包含有类型信息的。应该使赋值号两侧的类型一致,以避免出现意外结果。

一个变量的指针的含义包括两个方面,一是以存储单元编号表示的纯地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如 int , char , float 等)。

2.3引用指针变量

在引用指针变量时,可能有3种情况

(1)给指针变量赋值。如:

p =& a ;

指针变量 p 的值是变量 a 的地址, p 指向 a 。

(2)引用指针变量指向的变量。

如果已执行“ p =& a ;”,即指针变量 p 指向了整型变量 a ,则 printf ("% d ",* p );输出指向的对象。

其作用是以整数形式输出指针变量 p 所指向的变量的值,即变量 a 的值。

如果有以下赋值语句;

* p =1;

表示将整数1赋给 p 当前所指向的变量,如果 p 指向变量 a ,则相当于把1赋给 a ,即“ a = 1;”。改为int a=1;

int *p;

p=&a;

(3)引用指针变量的值。如: printf ("%",p );

作用是以八进制数形式输出指针变量 p 的值,如果 p 指向了 a ,就是输出了 a 的地址,即& a

&取地址运算符。& a 是变量 a 的地址。

*指针运算符(或称“间接访问”运算符),* p 代表指針变量 p 指向的对象。

指针变量的用法讲解(指针变量定义及引用)(1)

解密代码

,