1. 指针是什么?
指针是一种保存变量地址的变量。
在计算机中每个存储单元(一个字节)都有一个编号,这个编号称为变量地址。
普通变量的值是实际值,指针变量的值是变量的地址。
- 取地址
我们可以在变量名前加上&
,表示获取变量的地址。
int n = 10;
printf("&n=%p\n",&n);
printf("n=%d\n",n);
2. 指针怎么用?
2.1 定义指针
定义指针与定义变量的方式一样,只不过要在类型和变量名中间加上一个*星号。
类型* 指针变量;
指针变量只能使用同类型变量的地址赋值。
int n = 10;
int* p;
p = &n;
printf("&n=%p\n",p);
printf("n=%d\n",n);
也可以直接初始化
int n = 10;
int* p = &n;
printf("&n=%p\n",p);
printf("n=%d\n",n);
变量必须赋值后才能使用,指针也是必须赋值后才能使用。
2.2 解引用
指针的强大之处可以直接操作储存地址里面的数据。这种操作称为解引用。使用时需要在指针前加上*星号。
int n = 10;
int* p = &n;
printf("n=%d\n",n);
printf("*p=%d\n",*p);
n = 100;
printf("n=%d\n",n);
printf("*p=%d\n",*p);
*p = 1000;
printf("n=%d\n",n);
printf("*p=%d\n",*p);
在这里对*p
操作就是对n
操作;对n
操作就是对*p
操作。
访问变量两种方式:一是通过变量名直接访问,而是指针解引用访问。
int n = 10;
printf("*(&n) = %d\n",*(&n));
3. 指针与函数
3.1 值传递
试分析下面代码执行结果。
int func(int n){
n = 100;
}
int main(){
int n = 10;
func(n);
printf("n = %d\n",n);
}
3.2 指针/地址传递
试分析下面代码执行结果。
int func(int* n){
*n = 100;
}
int main(){
int n = 10;
func(&n);
printf("n = %d\n",n);
}
4.指针变量连续定义
#include <stdio.h>
int main()
{
int n = 10;
int* p,q;
p = &n;
q = &n;
printf("%d%d",p,q);
return 0;
}
5.变量指针 vs 数组指针
变量指针:指向单个变量的指针。
数组指针:指向数组的指针
#include <stdio.h>
int main () {
int n = 10;
int *p;
p = &n; // p指针指向变量
printf("*p = %d\n",*p);
int arr[] = {1,2,3,4,5,};
p = arr;// p指针指向数组
printf("*p = %d\n",*p);
printf("*(p+1) = %d\n",*(p+1));
printf("*(p+2) = %d\n",*(p+2));
printf("*(p+3) = %d\n",*(p+3));
printf("*(p+4) = %d\n",*(p+4));
return 0;
}
指针既可以指向一个基本类型变量又可以指向一个数组。所以在使用时要注意分辨。\
6. 实践
- 实现函数swap()交换两个变量的值。
void swap(int* a,int* b){
int t=*a;
*a=*b;
*b=t;
}
main(){
int m,n;
scanf("%d%d",&m,&n);
swap(&m,&n);
printf("m=%d,n=%d",m,n);
}
- 实现函数divmod()输入参数a和b,同时获取a与b的商和余数。
int divmod(int a,int b,int* div,int* mod){
if(!b)
return 0;
*div=a/b;
*mod=a%b;
return 1;
}
main(){
int m,n;
scanf("%d%d",&m,&n);
int div,mod;
if(divmod(m,n,&div,&mod))
printf("div=%d,mod=%d",div,mod);
else
printf("n不能为0");
}
指针在函数中有这两种应用,一种是即作为输入又作为输出;另一种只作为输出。