初识C指针(2)

来源:互联网 发布:走步软件 编辑:程序博客网 时间:2024/06/01 19:56
       当在程序中定义一个变量时,系统就在内存中为该变量分配一个大小合适的存储空间,这个存储空间的大小由变量的类型决定,一个int型变量占2个字节,一个float的变量占4个字节,数组int a[5]则占有2*5个字节。

        由于变量在内存中所占的存储空间大小不一,为了便于对变量地址的访问,将变量存储单元的起始地址定义为变量的地址。在变量定义完成后,这些变量在内存中就具有了唯一的存储空间,也就具有了唯一的变量地址,可以通过变量的地址对其进行访问。

        变量存储空间、变量地址与变量内容的关系就好像是仓库、仓库号与货物的关系。

        通常情况下,可以直接通过变量名对变量内容进行访问,而无需知道变量在内存中的地址,系统会自动将访问转换为对内存单元的访问,这种通过变量名来对变量存储单元进行访问的方式称为“直接访问”。

       C语言还支持对变量的内存单元进行“间接访问”。这种访问形式,允许将变量的地址赋给另一个特殊的变量,程序中可以利用这个特殊的变量来访问变量的内存单元。这个特殊变量称为指针。也就是说通过指针访问内存单元叫做间接访问。

指针的定义:指针变量就是用来存放内存地址的变量。
定义方式:
类型 *变量名    /*定义单个指针变量*/
类型 *变量名1,*变量名2……  /*定义多个同类型的指针变量*/
需要注意的是,定义指针变量时,每个指针变量前都要加 * 这个符号。指针变量的值只能是内存中存在的一个地址,而不是一个任意的整数。

int *pi;       /* pi 是一个整型指针变量 */
float *pf;     /* pf 是一个浮点型指针变量*/
char *pc;      /* pc 是一个字符型指针变量*/
char (*sp)[5]; /* sp 是一个字符数组指针变量*/
int **pi;      /* pi 是一个指针变量,它是一个指向整型指针的指针变量*/
int (*pf)();   /* pf 是一个函数指针变量,它指向一个函数,该函数返回一个整型值*/
int *(*pf)();  /* pf 是一个函数指针变量,它指向一个函数,该函数返回指向一个整值的指针*/

下面这些不是指针变量:

char *str[5];  /* str 是一个字符串数组,这个数组有5个元素,每个数组元素是指向一个字符串的指针*/
int *pf();     /* pf 是一个函数,这个函数返回指向一个整型值的指针*/

对指针变量的引用,由取地址运算符 “&” 和取值运算符 “*” 来完成。
故名思意 “&” 就是用来得到变量的内存地址。“*” 就是用来得到内存地址里所存储的值。
在指针运算中,取地址运算符 “&” 可用来将变量的地址赋给指针变量。如:

char c='a'; /*定义字符型变量*/
char *cp; /*定义字符型指针*/
cp=&c;   /*将变量c的地址赋给指针cp*/

值得注意的是,在为指针赋地址时,指针的类型应该与所指地址的变量数据类型一致。并且取址运算符 “&” 只能用于变量或数组元素,而不能用于表达式或数字常量,如下面用法就是错误的:
int *p,x,a[10];
p=&(x+1);
p=&234;

在对指针赋值后,就可以通过指针来进行对该变量地址的访问了。对指针内容的访问由取值运算符 “*”来执行。
char c;   /*定义一个字符变量c*/
char *cp; /*定义一个字符指针变量cp*/
cp=&c;    /*给指针cp赋值,即取得字符变量c的内存地址*/
*cp='b'; /*把值存入内存空间。相当于c='b'*/

在使用指针时,应该注意以下事项:
1、在对指针变量进行访问之前,一定要先为其赋地址,否则将发生不可预料的错误。
下面所示的是错误的使用方法:
int *p;
*p=100;
如果执行这段程序,将引起程序崩溃,因为没有对指针 p 赋内存地址,在执行语句 *p=100时,*p指向不可知的内存地址,而对不可知内存地址时行赋值,必将导致程序出错。


2、为指针变量赋值时,还可以用其他的指针或使用NULL来进行。
例如:
int *p,*q;
int n;
p=&n;
q=p;
p=NULL;
上面的程序执行后,指针q将指向整型变量n所在的内存地址,指针p指向空。


3、除NULL外,指针必须指向内存中实际存在的地址,不可以在程序中用非地址表达式给指针变量赋值。
下面的方法是错误的:
int *p,i=100;
p=i+100;    /*不能用非地址表达式来为指针赋值*/
p=1000;     /*不能用常量为指针赋值*/
*p=999;     /*没有对指针变量p赋内存地址*/