试想一下,不用return语句,通过调用普通函数来交换两个主函数变量的值。如主函数中:a=5,b=10,如何通过调用普通函数,使得最后在主函数中的输出为a=10,b=5。
什么是指针
- 指针就是地址,地址就是指针。
- 指针变量就是存放地址的变量。
- 指针和指针变量的区别:通常我们把指针变量简称为指针,但实际上他们含义不一样。指针的本质就是一个操作受限的数(不能加、乘、除,但可减)。
- 一个指针变量,无论它指向的变量占几个字节,该指针变量本身只占4个字节。
一些符号说明
*
:定义指针变量&
:取地址符,取出某个变量的地址
int * p; #p为变量的名字,int *表示p变量存放的是int类型变量的地址,p为一个指针变量。*p为一个int类型的变量
int i = 3;
p = &i;
printf("%d %d",*p,i); # 3 3
上面 “p = &i;”有以下含义:
- p保存了变量i的地址,因此p指向i。
- p和i没有任何关系,修改p的值不影响i的值,修改i的值不影响p的值。
- *p就等同于i。即如果一个指针变量指向了某个普通变量(p = &i;),则 指针变量 就完全等同于 普通变量(即出现指针变量 的地方都可换成普通变量,出现普通变量的地方都可换成 指针变量)。上述p=3。
变量名 | 地址 | 变量中的值 |
---|---|---|
i | 1000H | 3 |
p | 2000H | 1000H |
*p表示的是以p的内容为地址的变量,即 i
p所占大小为4个字节,其地址为这4个字节中的首个字节的地址
常见错误
int i = 5;
int * p;
int * q;
p = & i; # 此时*p就等同于i
*q = p; #错误。*q为一个int类型的变量,p为int *型的指针变量,类型不符,故错误。
q = p; #正确。两者都为int *型,而由于q没有赋值,其值为垃圾值,此时p也为垃圾值,不再是i的地址
printf("%d",*q); #错误。q的空间是属于本程序的,所以本程序可读取q中的值(为地址)。但是不能读取*q的内容,因为*q所代表的内存单元的控制权没有分配给本程序。
开头题的答案:
#include<stdio.h>
void change_num(int * q,int *p)
{
int t;
t = *q; # *q = a,则等同于t = a
*q = *p; # 同理 a = b
*p = t; # b = t
}
int main(void)
{
int a = 10;
int b = 5;
change_num(&a,&b); # q = &a,p = &b
printf("a= %d b= %d",a,b);
return 0;
}
结果:
指针与一维数组
- 关于一维数组名
一维数组名为一个指针常量,存放一维数组第一个元素的地址。
int a [5] = {1,2,3,4,5}; # a存放第一个元素1的地址,&a[0]等同于a。a为一个常量,其值不能更改。
2.下标和指针的关系
a[i]等同于*(a+i) 。a[i]为数组中第i-1个元素的值,*(a+1)为第一个元素的地址加上他们的间隔对应的变量的值。
3.函数的形参为数组
当一个函数的形参为数组时,要传递两个形参,一个为数字第一个元素的地址(数组名),另一个为数组的长度。例如下面程程序通过调用普通函数来输出数组的值。
#include<stdio.h>
void print(int * p,int length) #由于数组名为指针,所以应用指针变量p来接收
{
int i;
for(i = 0;i < length;i++){
printf("%d",p[i])
}
}
int main(void)
{
int a[5] = {1,2,3,4,5};
print(a,5); #传递数组名a和数组长度5
return 0;
}