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

C指针(2)——指针在函数中的应用(程序讲解)的更多相关文章

  1. C语言中指针变量如何向函数中传递

    指针变量存储的是地址,所以在函数调用的时候我们能否将指针变量传递给函数?如果不知道结果,那我们可以直接问电脑,输入如下一段代码. void GetMemory(char *p) { p = (char ...

  2. c++中函数中变量内存分配以及返回指针、引用类型的思考

    众所周知,我们在编程的时候经常会在函数中声明局部变量(包括普通类型的变量.指针.引用等等). 同时,为了满足程序功能的需要,函数的返回值也经常是指针类型或是引用类型,而这返回的指针或是引用也经常指向函 ...

  3. golang(3):strings和strconv使用 & 时间和日期类型 & 指针类型 & 流程控制 & 函数

    strings和strconv使用 . strings.HasPrefix(s string, prefix string) bool: // 判断字符串s是否以prefix开头 . . string ...

  4. Keil C51 中的函数指针和再入函数

    函数指针是C语言中几个难点之一.由于8051的C编译器的独特要求,函数指针和再入函数有更多的挑战需要克服.主要由于函数变量的传递.典型的(绝大部分8051芯片)函数变量通过堆栈的入栈和出栈命令来传递. ...

  5. C++中的函数指针和指针函数

    C++中的函数指针和指针函数       数组名一般可以被当成指向数组第一个元素的常量指针,同样的情况,在函数中,函数名可以本当成指向函数的常量指针,假如一个函数已经定义,那么它在计算机中一定有特定的 ...

  6. 深入理解JS函数中this指针的指向

    函数在执行时,会在函数体内部自动生成一个this指针.谁直接调用产生这个this指针的函数,this就指向谁. 怎么理解指向呢,我认为指向就是等于.例如直接在js中输入下面的等式: console.l ...

  7. C++中的指针,指针函数和函数指针

    指针是C或C++中的一大难题,因此弄懂指针对C和C++的学习有很大的帮助,最近一直在研究指针,因此写一篇随笔把心得记录一下. 简单来说指针也是一种变量,只不过指针变量所存储的不是我们直观上看到的,而是 ...

  8. C++中的指针、数组指针与指针数组、函数指针与指针函数

    C++中的指针.数组指针与指针数组.函数指针与指针函数 本文从刚開始学习的人的角度,深入浅出地具体解释什么是指针.怎样使用指针.怎样定义指针.怎样定义数组指针和函数指针.并给出相应的实例演示.接着,差 ...

  9. 【407】C函数中的指针

    注意:如果对于函数中指针参数的对应值进行修改,当调用该函数后,实参会被修改,所以如果不想要实参被修改,需要为函数的形参定义一个 str_copy 的量,通过 strcpy() 进行将字符串复制给 st ...

随机推荐

  1. 华为HCNP实验 防火墙安全区域及安全策略配置(USG6000)

    防火墙安全区域及安全策略配置   一.学习目的 掌握防火墙安全区域的配置方法 掌握安全策略的配置方法   二.拓扑图         三.场景 你是公司的网络管理员.公司总部的网络分成了三个区域,包括 ...

  2. July 16th 2017 Week 29th Sunday

    Opportunities are like sunrises, if you wait too long, you miss them. 机会如同日出,等得太久就会错过. Indecision is ...

  3. July 13th 2017 Week 28th Thursday

    No dream is too big, and no dreamer is too small. 梦想再大也不嫌大,追梦的人再小也不嫌小. Hold on to your dreams, but b ...

  4. 用eclipse pydev 创建一个新py文件时 文件的coding设置问题

    问题: 当安装好eclipse和pydev后,创建一个project, 创建一个新的py文件,文件头都会自带中文时间.这样在编译的时候会报错. 解决办法之一: 通过设置,可以使新建的文件的文件头自动带 ...

  5. ZOJ Monthly, January 2019 Little Sub and Isomorphism Sequences 【离线离散化 + set + multiset】

    传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5868 Little Sub and Isomorphism Seque ...

  6. javascript 构造函数方式定义对象 (转载)

    javascript 构造函数方式定义对象   javascript是动态语言,可以在运行时给对象添加属性,也可以给对象删除(delete)属性 <html> <head> & ...

  7. 使用cmd命令创建vue(ivieiw)项目

    条件,安装好nodejs 第一步:先使用 vue create 命令创建一个项目,等待创建完成. 1.切换目录 2.创建项目  vue create [项目名称] 第二步:切换到项目中. 第三步:使用 ...

  8. 锐捷交换机实验案例:vlan间互访的配置与验证

    组网需求: 1.如下图所示,某用户内网被划分为VLAN 10.VLAN 20.VLAN 30,以实现相互间的2 层隔离: 2.3 个VLAN 对应的IP 子网分别为192.168.10.0/24 .1 ...

  9. SQL SERVER 对权限的授予GRANT、拒绝DENY、收回REVOKE

    -----对用户member授权,允许其具有对数据表person的更新和删除的操作权限:GRANT UPDATE,DELETE ON personTO member WITH GRANT OPTION ...

  10. String.Format() 方法

    一 定义 String.Format() 是将指定的 String类型的数据中的每个格式项替换为相应对象的值的文本等效项. string p1 = "Jackie"; string ...