指针变量的几个常见问题

一、指针变量的初始化问题

指针变量同普通变量一样,使用之前不仅要定义说明,而且必须进行初始化,指针的初始值必须是一个地址,决不允许赋予任何其他数据,通常是一个数据的地址或地址变量或空指针。

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)主调函数中就可以使用这些改变了值的变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值