c语言中指针是一种保存变量地址的变量。
指针变量举例:
int x = 1, y=2;
int *p; /*p是指向int类型的指针*/
p = &x; /*p现指向x*/
y = *p /*y的值现为1*/
/*编写代码时要注意,你可能觉得自己只是在修改*p变量的值,
但你忘了p中存了x变量的地址,
修改*p的值相当于修改了p指向的变量的值
*/
*p = 0 /*x的值现在为0*/
指针形参:
先看一个错误例子,大多数c语言课本中都会有这个例子:交换两个变量的值
void swap(int x, int y)
{
int temp;
temp = x;
x = y ;
y = temp;
}
int a = 1, b = 2;
然后你在main 函数中swap(a, b),这样你就错了,a和b的值在调用swap前后都不会变。
这是因为swap(a, b)开始的时候相当于作了简单的赋值运算:
x = a, y = b;其实仅仅相当于x = 1, y = 2; c语言中的形参值传递
当进入函数swap(a, b)后改来改去改的都是swap函数中的局部变量a, b
而main函数的中的x, y对于swap函数来说已经无法访问到了,更不要说操作并且改变它的值了
带有指针形参的函数就可以很好的解决这个问题
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y ;
*y = temp;
然后你在main函数中
int a = 1, b = 2;
swap(&a, &b);
需要说明的是声明了指针形参变量的函数在调用时,传递的是地址
其实下面这两指针用法的个方式的理解也很重要
int a = 1;
int *p = &a;这句等价于下面两句:
int *p;
p = &a;
最容犯的错误是int *p = a,这么写编译器可能会警告你把一个整型的值赋给了一个指针类型的变量,没有做强制类型转换
这时候你可能困惑了*a到底应该赋给地址值,还是普通变量值, 这个时候你的具体情况分析
如swap函数:*x单独拿出来用,那么*x是一个整体, 如下面的swap函数体重第三行和第四行
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y ;
*y = temp;
其实就给整型变量赋值(第三行左侧*x看作整型变量m, 第三行左侧*y看作整型变量n),
*x = 2;<==>m=2
*y=1;<===>n=1
其实在这之前x和y指针变量已经拿到了地址值,就是这句swap(&a, &b)相当于
x = &a;
y = &b;
因为c 语言在使用一个变量时,编译器会检查它是否已经被初始化了,否则编译会报警告或者错误,
一些没有被初始化变量的程序看着编译过去了,运行时会可能停止掉。
其实只要心中记住指针变量存的是地址,int *p应该这么去看(int *) p