一、指针变量的初始化问题
指针变量同普通变量一样,使用之前不仅要定义说明,而且必须进行初始化,指针的初始值必须是一个地址,决不允许赋予任何其他数据,通常是一个数据的地址或地址变量或空指针。
void main()
{
int i,*p;
i=100;
*p=i;
printf("*p=%d\n",*p);
}
编译时会出现警告:warning C4700: 使用了未初始化的局部变量“p”。
程序中定义了一个指针变量 *p,但没有对其进行初始化,将该指针变量称为“野指针”。如果此后对该指针变量所指的存储空间进行操作,程序会出现严重的错误。因为在定义指针变量后,指针变量的值是不确定的,即指针随机指向某个内存地址,此时的指针所指的内存直接赋值操作,将该单元中原有的数据覆盖,使该数据丢失,若指针指向的是系统的数据区中,会导致系统运行的异常甚至死机。因此,C编程时要及时把指针变量赋值,使指针有正确的指向。
上面程序可修改为:
void main()
{
int i,*p;
i=100;
p=&i;
printf("*p=%d\n",*p);
}
程序编译成功。
二、指针赋值带来的内存“丢失”问题
在C语言中,指针之间是可以相互赋值的,但是使用不当可能会造成部分内存的“丢失” ,即这部分内存空间不能再被该任何程序访问。如:
#include<stdio.h>
#include<stdlib.h>
void main()
{
float *a,*b;
a=(float*)malloc( sizeof( float));
b=(float*)malloc( sizeof( float));
*a=float(227.5);
*b=float(163.9);
a=b;
printf("%f,%f",*a,*b);
}
上例中,将指针变量 b 赋给了指针变量 a,使 a 与 b 都指向分配给b的内存空间,而原先分配给a的内存空间未释放,不能再被其它任何程序访问,该内存空间成了“无效内存块”,内存空间“丢失”了。在大型软件系统中如果出现含类似程序段的函数,而该函数又反复被调用,将可能导致内存空间无故溢出。 解决方法:在将一个指针变量赋给另一个指针变量之前,应先用 free( ) 函数释放所占有的内存空间,以使这部分空间可以由系统重新支配,即应在赋值语句前执行:free (a)。
三、指针变量作为函数参数
指针变量作为函数的参数,是将一个变量的地址传送到另一个函数中。如,
void swap(int *p1,int *p2)
{
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
printf("*p1=%d,*p2=%d\n",*p1,*p2);
}
void main()
{
int a,b;
int *pointer_1,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_1=&a;pointer_2=&b;
if(a<b)
swap(pointer_1,pointer_2);
printf("a=%d,b=%d\n",a,b);
printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2);
}
运行情况:
5,9 <——(输入5,9)
*p1=9,*p2=5
a=9,b=5
*pointer_1=9,*pointer_2=5
程序说明:
swap 是用户定义的函数,它的作用是交换两个变量(a 和 b)的值。swap 函数的形参 p1、p2 是指针变量。程序运行时,先执行main函数,输入 a 和 b 的值。然后将 a 和 b 的地址分别赋给指针变量 pointer_1 和 pointer_2,使 pointer_1 指向 a,pointer_2 指向 b。接着执行 if 语句,由于 a〈b,因此执行 swap 函数。注意实参 pointer_1 和 pointer_2 是指针变量,在函数调用时,将实参变量的值传递给形参变量。采取的依然是“值传递”方式。因此虚实结合后形参 p1 的值为&a,p2 的值为&b。这时 p1 和 pointer_1 指向变量 a,p2 和 pointer_2 指向变量 b。接着执行执行 swap 函数的函数体使 *p1 和*p2 的值互换,也就是使 a 和 b 的值互换。函数调用结束后,p1 和 p2不复存在(已释放)。最后在main函数中输出的 a 和 b 的值是已经过交换的值。
请注意,不能企图通过改变形参指针的值(指向)而使实参指针的值改变。如,
#include<stdio.h>
void swap(int *p1,int *p2)
{
int *p;
p=p1;
p1=p2;
p2=p;
printf("*p1=%d,*p2=%d\n",*p1,*p2);
}
void main()
{
int a,b;
int *pointer_1,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_1=&a;pointer_2=&b;
if(a<b)
swap(pointer_1,pointer_2);
printf("a=%d,b=%d\n",a,b);
printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2);
}
运行情况:
5,9 <——(输入5,9)
*p1=9,*p2=5
a=5,b=9
*pointer_1=5,*pointer_2=9
C 语言中实参变量和形参变量之间的数据传递是单向的“值传递”方式。指针变量作为函数参数也要遵循这一规则。调用函数可以改变实参指针变量所指向变量的值,但不能改变实参指针变量的值(指向)。
总结:要通过函数调用得到 n 个要改变的值,可以:(1)在主调函数中设 n 个变量,用 n 个指针变量指向它们;(2)然后将指针变量作为实参,将 n 个变量的地址传给所调用的函数的形参;(3)通过形参指针变量,改变该 n 个变量的值(而不是改变形参指针变量的指向);(4)主调函数中就可以使用这些改变了值的变量。