C指针基础(二)

来源:互联网 发布:混凝土压力泌水率数据 编辑:程序博客网 时间:2024/05/01 05:41

这篇文章我们来谈谈指针在函数中的用法,即作为参数和作为返回值的用法。

指针作为参数

下面我们以一个比较经典的例子来说明这个问题——交换函数的实现来介绍这部分内容。下面是一种实现方法:

void swap(int a, int b){    int temp = a;    a = b;    b = temp;}

我们必须知道C语言中用值进行参数传递,所以函数调用中用作实际参数的变量无法改变,因此上面的方法是无效的。为了解决这个问题,我们不再传递变量ab作为函数的实际参数,而是提供&a&b,即指向ab的指针。我们通过间接引用符号*来间接改变ab中的值。下面是新的swap()函数:

void swap(int *a, int *b){    int temp = *a;    *a = *b;    *b = temp;}

另外我们需要再讨论另一个问题,那就是scanf()函数,对于这个函数,我想大部分人并不陌生。其实这个函数的第二个参数就是指针变量,因此我们在使用这个函数时,需要向其传递一个指针类型。很多人在使用这个函数时会产生一个误区:传递变量前必须有&符号,其实这是错误的,正如我们前面所说的,只要求是指针类型

int a, b;int *p = &b;scanf("%d", &a);  // 不要漏掉&符号scanf("%d", p);   // p是指针类型,可以不用&符号

假如我们不想让函数对传进来的指针进行修改我们该怎么办呢?你可能会想到const修饰符,但是const该如何使用呢?你可能会想到以下几种方式:

void f1(const int *p);void f2(int const *p)void f3(int* const p);void f4(const int* const p);

我们先来谈谈f1,它的参数是这样的const int *p,这种写法是限制我们不能修改指针所指向的对象的值。f2的作用和f1相同。而f3的作用是保护指针,即地址不被修改。我们刚刚说的是不能对指针进行修改,因此f3的这种写法符合我们的需要。其实这三种写法很好区分也很好记,对于f1f2const修饰的是*p,所以它保护的是指针所指向的值;对于f3const修饰的是p,所以它保护的是指针本身。对于f4,我想你已经猜出来了,它既对指针本身进行保护,也对指针指向的值进行保护。

  • 保护指针指向的值
void f(const int *p){  int j;  *p = 0;   /***错误***/  p = &j;   /***合法***/}
  • 保护指针本身
void f(int* const p){  int j;  *p = 0;   /***合法***/  p = &j;   /***错误***/}
  • 既保护指针,有保护指针指向的值
void f(const int* const p){  int j;  *p = 0;   /***错误***/  p = &j;   /***错误***/}

作为返回值

我们不仅可以为函数传递指针,还可以编写返回指针的函数。其实这很容易掌握,我们可以返回实际参数传入的指针的其中一个,也可以返回指向外部(全局)变量或者指向声明为static的局部变量的指针,但是我们不能返回指向局部变量的指针!

int *f(void){  int i;  ...  return &i;}

因为局部变量具有自动存储期限,函数调用时“自动”分配,函数返回时收回分配。因此一旦函数f返回,变量i就不存在了,所以指向变量i的指针是无效的。

参考资料

  1. somnik的博客:全局变量与局部变量的区别

  2. C语言程序设计现代方法, K.N.King, 人民邮电出版社

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

1 0
原创粉丝点击