C指针(2)——指针在函数中的应用(程序讲解)

2018-12-04 07:12:47来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

3-1.c指针用作函数参数

#include<stdio.h>
  typedef unsigned char uint8_t;   //类型自定义,通过typedef语句重新把unsigned char命名为uint8_t,目的为了方便
  extern void swapdata(uint8_t dat_x,uint8_t dat_y);
int main(void)
{
  uint8_t x,y;
  printf("请输入x,y:");
  scanf("%d,%d",&x,&y);
  printf("交换前:x=%d,y=%d\n",x,y);
  swapdata(x,y);
  printf("交换后:x=%d,y=%d\n",x,y);
  return 0;
}
  void swapdata(uint8_t dat_x,uint8_t dat_y)  
{
  uint8_t temp;
  temp=dat_x;
  dat_x=dat_y;
  dat_y=temp;
}

目的:是为了通过swapdate()函数把实参x,y的值进行交换,上述例子是将形参dat_x,dat_y的值进行交换,但是形参的交换并没有改变实参的交换,因为函数在调用时给形参分配了单独的内存空间,实参的值传递给形参实际是把实参的值放在形参的内存空间,形参的值是实参的备份,因此形参交换,实参并不会交换,不能达到交换实参的目的。 

 结果:

请输入x,y:30,20
交换前:x=30,y=20
交换后:x=30,y=20

 

3-2 函数调用时,把指针作为函数参数进行传递,即传递变量的地址。在被调函数中,通过指针操作相应的变量,实际操作变量本身。在被调函数中对形参的操作实际就是对实参的操作。

#include <stdio.h>
typedef unsigned char uint8_t;
extern void swapdata(uint8_t *dat_x,uint8_t *dat_y);  //函数参数变成指针
int main(void)
{
  uint8_t x,y;
  uint8_t *p_x,*p_y;
  printf("请输入x,y:");
  scanf("%d,%d",&x,&y);
  p_x=&x;
  p_y=&y;
  printf("交换前:x=%d,y=%d\n",x,y);
  swapdata(p_x,p_y);
  printf("交换后:x=%d,y=%d\n",x,y);
  return 0;
}
  void swapdata(uint8_t *dat_x,uint8_t *dat_y)   //形参为两个指针变量,目的是为了承接实参的值,实参是指针类型,
{
  uint8_t temp;
 temp=*dat_x;    //通过取值运算符*与指针变零dat_x结合,访问实参x;调用swapdate()后,指针变量dat_x指向实参x,对*dat_x的操作实际是对实参x的操作。
 *dat_x=*dat_y;
 *dat_y=temp;
}

 结果:

请输入x,y:10,20
交换前:x=10,y=20
交换后:x=20,y=10

  对比3-1和3-2的根本区别是:前者调用函数,实参是x,y的值;后者调用函数时,实参是x,y的指针,即二者的地址。

      结论:要在被调函数中改变主调函数中的变量值,需要将主函数中变量的指针作为实参,传递给被调函数。

 

3-3指向结构体的指针变量作为函数参数

#include<stdio.h>
#define BUF_LEN_MAX 3         //宏定义定义buf的大小
#define DATA_LEN_MAX 3        //定义存放data字段的buf大小
typedef unsigned char uint8_t;  //给unisigned char 命名为uint8_t
typedef struct
{
  uint8_t head;
  uint8_t len;
  uint8_t add;
  uint8_t data[DATA_LEN_MAX];
  uint8_t chk;
}RF_FRAME;                    //定义结构体,用typedef语句把结构体重新命名为RF_FRAME,然后用该类型定义其他变量
RF_FRAME txbuf[BUF_LEN_MAX]={{0xAA,5,0x00,0x11,0x12,0x13,0x14},    //定义一个RF_FRAME类型的数组txbuf[]数组,并进行初始化;该数组的所有元素都是RF_FRAMR类型,包含head,len,add,data[],chk等成员
                              {0xAA,5,0x01,0x12,0x13,0x13,0x14},
                              {0xAA,5,0x02,0x13,0x14,0x13,0x14}};
void output(RF_FRAME *p_ptr);
int main(void)
{
   RF_FRAME *ptr_tmp;         //定义RF_FRAME的指针变量ptr_tmp
   ptr_tmp=txbuf;             //给指针变量ptr_tmp进行赋值,让它指向txbuf。即ptr_tmp是指向结构体的指针变量
   output(ptr_tmp);          
   return 0;
}
void output(RF_FRAME *p_ptr)    //传递实参ptr_tmp的值,因为是指针变量,实际是让形参p_ptr指向实参ptr_tmp所指向的数据。也就是实参ptr_tmp和形参p_ptr同时指向数组bxbuf[]
{
   uint8_t i,j;
   for(i=0;i<BUF_LEN_MAX;i++)
  {
      printf(" %x", p_ptr[i].head);    //p_ptr指向数组txbuf[],所以p_ptr[i].head相当于txbuf[i].head
      printf(" %x", p_ptr[i].len);
      printf(" %x", p_ptr[i].add);
       for(j=0;j<DATA_LEN_MAX;j++)
        {
          printf(" %x", p_ptr[i].data[j]);
         }
      printf(" %x\n", p_ptr[i].chk);
   }
} 

  结果:

 aa 5 0 11 12 13 14
 aa 5 1 12 13 13 14
 aa 5 2 13 14 13 14

 

3-4.c指向函数的指针变量

#include<stdio.h>
void output(void);    //output函数的声明
int main(void)
{
  void (*p_output)();   //定义一个指向函数的指针变量,变量名为p_output,没有返回值,函数指针   
  p_output=output;      //初始化,让指向函数的指针变量p_output指向函数output()
  (*p_output)();        //通过指针变量*p_output调用函数output()
  return 0;
}
 void output(void)
{
  printf("Fujian 2018\n");
}

  结果:

Fujian 2018

  函数指针和指针函数

  • 函数指针:int  (*p_output)( );   定义一个指向函数的指针变量p_output;让其指向某个函数;*先与p_output结合决定他是一个指针变变量
  • 指针函数:int *p_output( );返回值是指针;这个指针指向int型;p_output先与()结合决定了他是一个函数

 

补充:main函数

  • 单进程系统中main的返回值是没有实际意义的,所以定义main函数时,使用void也可以,虽然这样不符合规范
  • 在多进程中的操作系统下,main函数的返回值是返回给操作系统的

       最新的C99标准:

int main(void)
int main(int argc,char *argv[])

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:C/CPP代码审计&lt;splint/flawfinder&gt;

下一篇:C语言学习记录