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[])

最新文章

  1. CF memsql Start[c]UP 2.0 B
  2. 常用SQL语句
  3. 都昌 DCWriter电子病历编辑器演示文档截屏
  4. nginx地址重写
  5. Codeforces Round #367 (Div. 2) B. Interesting drink (模拟)
  6. [Linked List]Partition List
  7. Ubuntu Server 安装部署 Cacti 服务器监控
  8. Unity 5 Stats窗口
  9. wampserver安装错误 应用程序无法正常启动0xc000007b解决方法
  10. SNS团队Beta阶段第一次站立会议(2017.05.22)
  11. Hadoop配置第2节-JDK的安装
  12. Windows下Flume的安装
  13. [Css] css3的flex布局
  14. yum 彻底删除nodejs,重新安装
  15. readlink 获取进程的绝对路径
  16. HL-D793G七位蓝色+PT6311驱动
  17. hello2代码的简单分析
  18. Tomcat的简单归纳总结
  19. react-native 新手爬坑经历(unable to load script from assets 和could not connect to development server.)
  20. Python Tornado集成JSON Web Token方式登录

热门文章

  1. Docker_3 数据卷
  2. VS断点不生效
  3. Python学习---Python下[字符串]的学习
  4. Deep Learning Drizzle
  5. ieHTTPHeaders使用方法
  6. 关于cmake输出动态链接库名字的问题
  7. GO语言(八) defer注意点
  8. calcurse 日程管理软件
  9. 第一章 介绍Django
  10. HTML和CSS实现常见的布局