指针其实很简单。同C语言中其他变量一样,把指针也看成是一种变量即可,这种变量专门存储地址值。
1 |
<span class="hljs-keyword">int</span> a = <span class="hljs-number">100</span>; <span class="hljs-keyword">int</span>* b = &a; |
上面的代码很清晰,a是一个整形变量,值为100;b是一个指针变量,值是变量a的地址。变量和指针的类型必须相同。
本文主要讲利用指针变量如何读写地址中的值。
1、首先来假设一个场景:交换a和b两个变量的值。看下面的例子:
1 |
<span class="hljs-keyword">void</span> swap(<span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y) { <span class="hljs-keyword">int</span> tmp = x; x = y; y = tmp; } <span class="hljs-keyword">void</span> change() { <span class="hljs-keyword">int</span> a = <span class="hljs-number">100</span>; <span class="hljs-keyword">int</span> b = <span class="hljs-number">200</span>; swap(a, b); } |
结果a,b的值并没有交换成功。原因是:C程序在调用函数时使用“按值调用”,这意味着变量的值直接从调用函数复制到被调函数的实参中,“按值调用”是C语言中调用函数的唯一方式。
第一类:创建指针变量,“ 基本类型+ * ”。
1 |
<span class="hljs-keyword">int</span>* iptr; <span class="hljs-keyword">char</span>* cptr; <span class="hljs-keyword">double</span>* dptr; |
第二类:给指针变量赋值,“ &+变量 ”。
1 |
<span class="hljs-keyword">int</span> a = <span class="hljs-number">100</span>; <span class="hljs-keyword">char</span> b = <span class="hljs-string">'o'</span>; <span class="hljs-keyword">double</span> c = <span class="hljs-number">100.5</span>; <span class="hljs-keyword">int</span>* iptr; <span class="hljs-keyword">char</span>* cptr; <span class="hljs-keyword">double</span>* dptr; iptr = &a; cptr = &b; dptr = &c; |
第三类:取指针变量保存的地址中的值,“ * + 指针变量”。
1 |
<span class="hljs-keyword">int</span> a = <span class="hljs-number">100</span>; <span class="hljs-keyword">int</span>* iptr = &a; <span class="hljs-keyword">int</span> b = <span class="hljs-variable">*iptr</span>; |
于是,上面的代码改写成:
1 |
void swap(<span class="hljs-keyword">int</span>* <span class="hljs-keyword">x</span>, <span class="hljs-keyword">int</span>* <span class="hljs-keyword">y</span>) { <span class="hljs-keyword">int</span> tmp = <span class="hljs-variable">*x</span>; <span class="hljs-variable">*x</span> = <span class="hljs-variable">*y</span>; <span class="hljs-variable">*y</span> = tmp; } void change() { <span class="hljs-keyword">int</span> a = <span class="hljs-number">100</span>; <span class="hljs-keyword">int</span> b = <span class="hljs-number">200</span>; swap(&a, &b); } |
3、一个函数只能访问自己的栈帧。
但是,通过指针,一个函数可以间接地读写另一个栈帧中的变量值。
值得注意的是,函数之间利用指针读写是有方向的。如果函数F1调用F2,则F2可以读写F1中的变量值,反之不行。很好理解,F2得栈帧先出栈,出栈后变量都没有了,F1还读写什么呢?
指针并不难。