什么是指针
指针是一种特殊的数据类型,使用它可以定义指针变量,
指针变量储存的是整形数据,代表了内存的编号,通过
这个编号可以访问到对应的内存。
为什么使用指针
1、函数与函数之间是相互独立的,但是有些时候需要共
享变量
传参是单向值传递(内存的拷贝);//原因1
全局变量容易命名冲突; //2
使用数组还需要传递长度; //3
函数的命名空间是相互独立的,但是地址空间是同
一个,所以指针可以解决这个问题。 //4
2、由于函数传参是值传递,对于字节数较多的变量,值
传递的效率比较低,如果传递的是变量的地址,只需
要传递4|8字节。
3、堆内存无法取名,它不像stack、bss、data让变量名
与内存建立关系,只能使用指针来记录堆内存的地址
编号从而使用该堆内存。
如何使用指针
定义
类型* 变量名_p;
例子:int* p;
1、指针变量与普通变量的使用上有很大的区别,为了
以示区分,建议在变量名后面加上_p。
2、指针的类型表示该指针变量存储的是什么类型变量
的地址,指针的内型决定了可以通过指针变量访问
的字节数。
3、一个*只能定义一个指针变量。
int* p1,p2,p3;//p1是指针,p2,p2是int
int *p1,*p2,*p3;//p1,p2,p3都是指针变量
4、指针变量与普通变量一样的是默认值是随机的,一
般初始化为NULL。
赋值(引用)
变量名_p = 地址;
//地址必须是一个有权限且有意义的内存地址
指向栈内存:
int num;
int* p = NULL;
p = #
指向堆内存:
int* p = NULL;
p = malloc(4);
解引用
*p
通过指针变量中记录的内存编号来访问对应的内存,该过程可能会产生段错误,但是原因是储存了非法的内存编号。
注意:访问的字节数是由指针变量的类型决定的。
练习1
实现一个变量交换的函数,调用它对一个数组进行排序。
提示:void swap(int* a,int* b);
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap(int* p1,int* p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
void sort(int arr[],int len)
{
for(int i = 0;i<len-1; i++)
{
for(int j = i+1; j<len; j++)
{
if(arr[i] > arr[j])
{
swap(&arr[i],&arr[j]);
}
}
}
}
int main(int argc,const char* argv[])
{
srand(time(NULL));
int num1 = 10,num2 = 20;
swap(&num1,&num2);
printf("num1=%d num2=%d\n",num1,num2);
int arr[10]={};
for(int i=0;i<10;i++)
{
arr[i] = rand()%300;
printf("%d ",arr[i]);
}
printf("\n");
sort(arr,10);
for(int i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
}
注意:想要获取多个返回值,可以借助指针返回。
练习2
实现一个函数,计算两个整数的最大公约数、最小公倍数,最大公约数用return返回,最小公倍数使用指针处理。
#include <stdio.h>
int max_min(int num1,int num2,int* p)
{
int max = 0;
for(int i = 1;i<=num1;i++)
{
if(0 == num1%i && 0 == num2%i)
{
max = i;
}
}
for(int i = num1*num2; i>=num1; i--)
{
if(0 == i%num1 && 0 == i%num2)
{
*p = i;
}
}
return max;
}
int main(int argc,const char* argv[])
{
int num1 = 0,num2 = 0;
printf("请输入两个整数:");
scanf("%d%d",&num1,&num2);
int max = 0,min = 0;
max= max_min(num1,num2,&min);
printf("max=%d min=%d\n",max,min);
}