C语言学习(指针二——指针和函数)

一、传递指针给函数

1、传地址或指针给函数

当函数的形参类型是指针类型时,使用该函数时,需要传递指针、地址或者数组给该形参。

#include <stdio.h>
void func(int *); // 函数原型声明
int main()
{
  int num = 100;
  int *ptr = &num;
  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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值