一、传递指针给函数
1、传地址或指针给函数
当函数的形参类型是指针类型时,使用该函数时,需要传递指针、地址或者数组给该形参。
#include <stdio.h>
void func(int *); // 函数原型声明
int main()
{
int num = 100;
int *ptr = #
func(&num);
printf("num = %d \n", num);
func(ptr);
printf("num = %d \n", num);
return 0;
}
// 定义函数
void func(int *p)
{
*p += 1;
}
num = 101
num = 102
2、传数组给函数
#include <stdio.h>
double arr_ptr_avg(double *ptr, int len)
{
double sum = 0;
for (int i = 0; i < len; i++)
{
// sum += ptr[i];
// sum += *(ptr+i);
sum += *(ptr++);
}
return sum / len;
}
double arr_ptr_avg2(double arr[],int len){
double sum2=0;
for (int i = 0; i < len; i++)
{
sum2+=arr[i];
}
return sum2/len;
}
int main()
{
double num[5] = {10.1, 20.1, 30.1, 40.1, 50.1};
int len = sizeof(num) / sizeof(num[0]);
double avg = arr_ptr_avg(num, len);
double avg2 = arr_ptr_avg2(num, len);
printf("%.2lf\n", avg);
printf("%.2lf\n", avg2);
return 0;
}
30.10
30.10
问:如果在函数中,通过指针修改了数组的值,那么main函数中的数组的值是否会相应变化?
答:会的,因为函数中的指针,指向的就是main函数中的数组。
二、指针函数
1、基本介绍和使用
如果函数的返回值是一个指针,这样的函数称为指针函数。
语法规则:
返回值类型 * 指针函数名(参数列表)
例子 请编写一个函数 strlong(),返回两个字符串中较长的一个。
#include <stdio.h>
#include <string.h>
// 定义一个比较两个字符串长度的函数
char *strLong(char *str1, char *str2)
{
return strlen(str1) > strlen(str2) ? str1 : str2;
}
int main()
{
// 指针函数:本身是一个函数,返回值是一个指针
char str1[30], str2[30], *str;
printf("请输入第一个字符串 \n");
scanf("%s",str1);
printf("请输入第二个字符串 \n");
scanf("%s",&str2);
str = strLong(str1,str2);
printf("Longer string is:%s \n",str);
return 0;
}
2、应用案例
编写一个函数,它会生成10个随机数,并使用数组名作为返回值。
说明:生成随机数可以使用 rand()
函数,由C语言标准库 <stdlib.h>
提供,可以返回一个随机整数。
#include <stdio.h>
#include <stdlib.h>
// 定义一个指针函数,返回值是一个数组
int *rand_array()
{
// 定义static静态数组,用来把静态局部数组的数据作为返回值使用
static int arr[10];
for (int i = 0; i < 10; i++)
// 产生0-49之间的10个随机数
arr[i] = rand() % 50;
return arr;
}
int main()
{
// 定义指针变量接收函数的返回值(是一个数组)
int *ptr = rand_array();
for (int i = 0; i < 10; i++)
printf("%d,", *(ptr++));
return 0;
}
41,17,34,0,19,24,28,8,12,14,
三、指针运算
1、指针加减整数
指针与整数的加减运算,表示指针所指向的内存地址的移动(加,向后移动;减,向前移动),指针移动多少,与指针指向的数据类型有关,数据类型占据多少个字节,每单位就移动多少个字节,比如一个 int 类型指针,+1 向后移动 4 个字节,-2 向前移动 8 个字节。
数组的元素在内存中连续存储的,我们通过数组元素来演示指针加减整数的情况。
#include <stdio.h>
int main()
{
int arr[]={10,20,30,40,50}; //定义一个整型数组arr,并初始化
int *ptr=&arr[0]; //定义一个整型指针ptr,并使其指向数组的第一个元素
printf("%d,%p\n",*ptr,ptr); //输出指针ptr所指向的值以及指针ptr本身的地址
ptr+=3; //指针ptr向后移动3个位置
printf("%d,%p\n",*ptr,ptr); //输出指针ptr所指向的值以及指针ptr本身的地址
ptr-=2; //指针ptr向前移动2个位置
printf("%d,%p\n",*ptr,ptr); //输出指针ptr所指向的值以及指针ptr本身的地址
return 0;
}
10,0000005d6a5ffb40
40,0000005d6a5ffb4c
20,0000005d6a5ffb44
2、指针自增自减
指针自增、自减本质上就是指针加减整数,自增地址后移,自减地址前移。下面我们利用指针的自增自减实现数组的遍历,代码如下:
#include <stdio.h>
int main()
{
int arr[]={10,20,30,40,50}; //定义一个整型数组arr,并初始化
int len=sizeof(arr)/sizeof(arr[0]); //计算数组的长度
int *ptr=arr; //将数组的地址赋给指针ptr
for(int i=0;i<len;i++){ //遍历数组
printf("%d,%d,%p\n",i,*ptr,ptr); //打印指针所指向的值和指针的地址
ptr++; //指针向后移动一位
}
printf("\n=================================================\n");
for (int j=len-1;j>=0;j--){ //逆序遍历数组
ptr--; //指针向前移动一位
printf("%d,%d,%p\n",j,*ptr,ptr); //打印指针所指向的值和指针的地址
}
return 0;
}
0,10,00000065da3ff8d0
1,20,00000065da3ff8d4
2,30,00000065da3ff8d8
3,40,00000065da3ff8dc
4,50,00000065da3ff8e0
=================================================
4,50,00000065da3ff8e0
3,40,00000065da3ff8dc
2,30,00000065da3ff8d8
1,20,00000065da3ff8d4
0,10,00000065da3ff8d0