C中最重要、最复杂的概念之一就是指针(pointer)
指针是用于存储地址的变量
例如:scanf()函数中使用地址作为参数
当需要改变调用函数中的某个值时,任何被调用的无返回值的C函数都需要使用地址参数完成该任务
一、地址运算符&
一元运算符&:可以取得变量的地址(a为变量,&a为该变量的地址)
一个变量的地址代表该变量在内存中的位置
示例代码:
#include <stdio.h>
int main(void)
{
int num = 10;
printf("the value of num is: %d \n", num); // 打印变量num的值
printf("the address of num is: %d \n", &num); // 打印变量num的地址
}
运行结果:
1)变量名相同但地址不同,本质上为2个变量,在不同函数中声明的同名变量是完全不同的
2)函数调用时将实参的值传递给形参,但只是进行了数值传递,两个变量(实参和形参)分别保持原来的特性
3)每个C函数都使用自己的变量,原变量不因被调函数中操作的副作用而意外地改变
二、改变调用函数中的变量
示例代码:
#include <stdio.h>
void value_exchange(int m, int n);
int main(void)
{
int i = 20;
int j = 30;
printf("before exchange, i is %d, j is %d \n", i, j);
value_exchange(i, j);
printf("after exchange, i is %d, j is %d \n", i, j);
return 0;
}
void value_exchange(int m ,int n)
{
int temp;
printf("before exchange, m is %d, n is %d \n", m, n);
temp = m;
m = n;
n = temp;
printf("after exchange, m is %d, n is %d \n", m, n);
}
运行结果:
结果:并没有像预想中那样交换i和j两个变量的值,只是改变了被调函数中m和n的值
因为value_exchange()函数使用的变量独立于函数main(),因此交换m和n的值对i和j无任何影响
解决方法:使用指针
指针是一个其数值为地址的变量,是一个数据对象,指针变量的数值表示的是地址
指针的用途之一:作为函数参数
将某个指针变量命名:
ptr = & a; // 把变量a的地址赋给ptr
// ptr指向a
如果ptr指向a,可以用间接运算符 *(也称取址运算符)获取a中存放的数值
val = *ptr; // 将ptr指向的值赋给val
ptr = &a;
val = *ptr;
//等效于
val = a;
指针声明:
int *a; // a是指向一个整数变量的指针
char *b; // b是指向一个字符变量的指针
float *c, *d; // c和d是指向浮点变量的指针
类型标识符表明了被指向变量的类型,星号(*)表明该变量为指针(例如,int *a表示a是一个指针,且*a是int类型的)
指针是一种新的数据类型,不是一种整数类型,虽然在大多数系统内部指针的值以一个无符号整数表示(ANSI C中指针的输出格式为 %p)
使用指针在函数间通信:解决上面示例中的问题
示例代码:
#include <stdio.h>
void value_exchange(int * m, int * n);
int main(void)
{
int i = 20;
int j = 30;
printf("before exchange, i is %d, j is %d \n", i, j);
value_exchange(&i, &j);
printf("after exchange, i is %d, j is %d \n", i, j);
return 0;
}
void value_exchange(int * m ,int * n)
{
int temp;
printf("before exchange, m is %d, n is %d \n", m, n);
temp = *m;
*m = *n;
*n = temp;
printf("after exchange, m is %d, n is %d \n", m, n);
}
运行结果:
1)函数调用时,传递的是i和j的地址而不是它们的值,即value_exchange()函数的参数是i和j的地址
2)通过使用指针和运算符*,函数获得相应存储地址的数据,进而改变这些数据
把变量的两类信息传递给一个函数:
function(x); // 形式一:此时传递的是x的值
function(&x); // 形式二:此时传递的是x的地址
函数定义:
int function(int n) // 形式一
int function(int * n) // 形式二
使用函数进行数据计算时可以使用形式一进行调用;但是如果需要改变调用函数中的多个变量的值时,需要使用形式二的调用方式
变量:名称、地址和数值
一个变量一般有两种属性:变量名和数值
程序被编译和加载后,同一变量在计算机中的两个属性是地址和数值
变量地址可以被看作是变量在计算机中的名称
C中可以使用运算符&对变量的地址进行操作
普通变量把其数值作为基本数值量,通过使用运算符&可以将其地址作为间接数值量