skip to content

C
C 指针

什么是指针 & 指针变量

指针就是变量的内存地址,而用来存储指针的变量则是指针变量。

指针变量的声明

/* type *var-name; */
int    *ip;
double *dp;
float  *fp;
char   *ch;
  1. 在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。
  2. 所有实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。
  3. 不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

举个例子

#include <stdio.h>

int main() {
  int  v         = 1;  /* 声明实际变量*/
  int* v_pointer = &v; /* 声明指针变量*/
  printf( "变量 : %i\n", v );
  printf( "指针 : %i\n", &v );
  printf( "指针变量 : %i\n", v_pointer );
  printf( "使用指针变量访问变量: %i\n", *v_pointer );
  return 0;
}
/* 
  变量 : 1
  指针 : 6422036
  指针变量 : 6422036
  使用指针变量访问变量: 1
 */

* 运算符和 & 运算符恰好相反。

& 运算符接收一个数据,然后告诉你这个数据保存在哪里;

* 运算符接收一个地址,然后告诉你这个地址中保存的是什么数据。

为什么用指针呢

首先看一个问题

#include <stdio.h>

void add( int v ) {
  v = v + 1;
}

int main() {
  int x = 10;
  printf( "增加前 : %i\n", x );
  add( x );
  printf( "增加后 : %i\n", x );
  return 0;
}

这段代码的本意是想通过 add 函数,使变量 x 增加 1

但是当调用 add 函数的时候,它只是将变量 x 赋值给了 v 并使用,这只是一个单纯的赋值过程

所以后续的 v = v + 1 只会改变 v 的值,并不会对 x 产生任何效果。

那怎么办呢?

简单来讲,可以让 add 函数把结果返回出去,并重新赋值给 x

#include <stdio.h>

int add( int v ) {
  v = v + 1;
  return v;
}

int main() {
  int x = 10;
  printf( "增加前 : %i\n", x );
  x = add( x );
  printf( "增加后 : %i\n", x );
  return 0;
}

这此好多了,结果也符合预期,但是还有没有其他方法呢?

答案是有,那就是使用指针

#include <stdio.h>

void add( int* v ) { // 定义指针变量
  *v = *v + 1; // 通过指针变量操作指针指向的变量
}

int main() {
  int x = 10;
  printf( "增加前 : %i\n", x );
  add( &x ); // 传递指针
  printf( "增加后 : %i\n", x );
  return 0;
}

指向指针的指针

讲真这块有点老千层饼了,不过也不难

#include <stdio.h>

int main() {
  int   v;
  int*  p1;
  int** p2;
  v  = 10;
  p1 = &v;
  p2 = &p1;
  printf( "实际变量 v %i\n", v );
  printf( "指针变量 p1 %i\n", p1 );
  printf( "指针变量 p2 %i\n", p2 );
  printf( "使用p2访问p1 %i\n", *p2 );
  printf( "使用p1访问实际变量 %i\n", *p1 );
  printf( "使用p2访问实际变量 %i\n", **p2 );
  printf( "p1 与  *p2 %i\n", p1 == *p2 );
  printf( "v  与  *p1 %i\n", v == *p1 );
  printf( "v  与 **p2 %i\n", v == **p2 );
  return 0;
}