一、指针是什么
int *pi;
pi 是一个指针,其实,它也只过是一个变量而已。与变量并没有实质的区别。
内存地址→ 6 7 8 9 10 11 12 13
-------------------------------------------------------------------------------------------------------
··· | 30 | 't' | | | | | ···
-------------------------------------------------------------------------------------------------------
变量 | → i ← |→ a ←| | → pi ← |
-------------------------------------------------------------------------------------------------------
··· | 30 | 't' | | | | | ···
-------------------------------------------------------------------------------------------------------
变量 | → i ← |→ a ←| | → pi ← |
<span style="font-size:18px;"> pi=&i;</span>
内存地址→ 6 7 8 9 10 11 12 13
-------------------------------------------------------------------------------------------------------
··· | 30 | 't' | | | 6 | ···
-------------------------------------------------------------------------------------------------------
变量 | → i ← |→ a ←| | → pi ← |
-------------------------------------------------------------------------------------------------------
··· | 30 | 't' | | | 6 | ···
-------------------------------------------------------------------------------------------------------
变量 | → i ← |→ a ←| | → pi ← |
<span style="font-size:18px;"></span><pre name="code" class="objc">
int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6};
pa = a;
for (i = 0; i <= 9; i++)
{
printf("%d\n", *pa);
pa++; /*注意这里,指针值被修改*/
}
可以看出,这段代码也是将数组各元素值输出。不过,你把循环体{}中的 pa改成 a 试试。你会发现程序编译出错,不能成功。看来指针和数组名还是不同的。其实上面的指针是指针变量,而数组名只是一个指针常量。指针 pa 在整个循环中,其值是不断递增的,即指针值被修改了。数组名是指针常量,其值是不能修改的,因此不能类似这样操作: a++。
三、const int *pi与int *const pi的区别
- const int *pi (当然 int const *pi 也是一样的,它们实际是一样的)
<span style="font-size:18px;">/* 代码开始 */ int i1 = 30; int i2 = 40; const int *pi = &i1; pi = &i2; /* 注意这里, pi 可以在任意时候重新赋值一个新内存地 址*/ i2 = 80; /* 想想看:这里能用*pi = 80 来代替吗?当然不能! */ printf("%d\n", *pi); /* 输出是 80 */ /* 代码结束 */</span>
pi 的值是可以被修改的。即它可以重新指向另一个地址的,但是,不能通过*pi 来修改 i2 的值。
首先 const 修饰的是整个*pi(注意,我写的是*pi 而不是 pi)。所以*pi 是常量,是不能被赋值的(虽然 pi 所指的 i2 是变量,不是常量)。
其次, pi 前并没有用 const 修饰,所以 pi 是指针变量,能被赋值重新指向另一内存地址的。
- int *const pi
int i1 = 30;
int i2 = 40;
int *const pi = &i1;
/* pi = &i2; 注意这里, pi 不能再这样重新赋值了,即不能再指向另一个新地址。(第 4 行的注释) */
/* 所以我已经注释了它。 */
i1 = 80; /* 想想看:这里能用 *pi = 80; 来代替吗?可以,这里可以通过*pi 修改 i1 的值。(第 5 行的注释) */
/* 请自行与前面一个例子比较。 */
printf("%d", *pi); /* 输出是 80 */
/* 代码结束 */
看了这段代码,你明白了什么?有没有发现 pi 值是不能重新赋值修改了。它只能永远指向初始化时的内存地址了。相反,这次你可以通过*pi 来修改 i1的值了。
1) pi 因为有了 const 的修饰,所以只是一个指针常量:也就是说 pi 值是不可修改的(即 pi 不可以重新指向 i2 这个变量 了)(请看第 4 行的注释)。
2)整个*pi 的前面没有 const 的修饰。也就是说, *pi 是变量而不是常量,所以我们可以通过*pi 来修改它所指内存 i1 的值 (请看第 5 行的注释)。
最后总结两句:
1) 如果 const 修饰在*pi 前,则不能改的是*pi(即不能类似这样:*pi=50;赋值)而不是指 pi。
2) 如果 const 是直接写在 pi 前,则 pi 不能改(即不能类似这样:pi=&i;赋值)。
四、指向另一指针的指针
int i=3;
int * pi;
pi=&i;
int ** ppi; //声明了一个指针变量 ppi,这个 ppi是用来存储(或称指向)一个 int * 类型指针变量的地址。
ppi=π //&pi 那就是取 pi 的地址,就是把 pi 的地址赋给了 ppi。
未完 待续 >>>>>>>>>>>>>>>