C指针(2)——指针在函数中的应用(程序讲解)
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)——指针在函数中的应用(程序讲解)的更多相关文章
- C语言中指针变量如何向函数中传递
指针变量存储的是地址,所以在函数调用的时候我们能否将指针变量传递给函数?如果不知道结果,那我们可以直接问电脑,输入如下一段代码. void GetMemory(char *p) { p = (char ...
- c++中函数中变量内存分配以及返回指针、引用类型的思考
众所周知,我们在编程的时候经常会在函数中声明局部变量(包括普通类型的变量.指针.引用等等). 同时,为了满足程序功能的需要,函数的返回值也经常是指针类型或是引用类型,而这返回的指针或是引用也经常指向函 ...
- golang(3):strings和strconv使用 & 时间和日期类型 & 指针类型 & 流程控制 & 函数
strings和strconv使用 . strings.HasPrefix(s string, prefix string) bool: // 判断字符串s是否以prefix开头 . . string ...
- Keil C51 中的函数指针和再入函数
函数指针是C语言中几个难点之一.由于8051的C编译器的独特要求,函数指针和再入函数有更多的挑战需要克服.主要由于函数变量的传递.典型的(绝大部分8051芯片)函数变量通过堆栈的入栈和出栈命令来传递. ...
- C++中的函数指针和指针函数
C++中的函数指针和指针函数 数组名一般可以被当成指向数组第一个元素的常量指针,同样的情况,在函数中,函数名可以本当成指向函数的常量指针,假如一个函数已经定义,那么它在计算机中一定有特定的 ...
- 深入理解JS函数中this指针的指向
函数在执行时,会在函数体内部自动生成一个this指针.谁直接调用产生这个this指针的函数,this就指向谁. 怎么理解指向呢,我认为指向就是等于.例如直接在js中输入下面的等式: console.l ...
- C++中的指针,指针函数和函数指针
指针是C或C++中的一大难题,因此弄懂指针对C和C++的学习有很大的帮助,最近一直在研究指针,因此写一篇随笔把心得记录一下. 简单来说指针也是一种变量,只不过指针变量所存储的不是我们直观上看到的,而是 ...
- C++中的指针、数组指针与指针数组、函数指针与指针函数
C++中的指针.数组指针与指针数组.函数指针与指针函数 本文从刚開始学习的人的角度,深入浅出地具体解释什么是指针.怎样使用指针.怎样定义指针.怎样定义数组指针和函数指针.并给出相应的实例演示.接着,差 ...
- 【407】C函数中的指针
注意:如果对于函数中指针参数的对应值进行修改,当调用该函数后,实参会被修改,所以如果不想要实参被修改,需要为函数的形参定义一个 str_copy 的量,通过 strcpy() 进行将字符串复制给 st ...
随机推荐
- QT的组合键
https://www.cnblogs.com/Jace-Lee/p/5859293.html
- laravel中delete()方法和destroy()方法的区别
delete()方法是实例方法,需要查询到相应的数据并通过模型实例调用 destroy()方法可以直接调用,通过索引删除记录 举个栗子: /*delete()方法删除*/ //先查找记录 $blog ...
- easyui学习笔记9—手风琴格子的增,删和选择
这一篇中我们将看看如何给手风琴动态的增加,删除格子,怎样选择某一个格子的. 1.先看看引用的资源 <link rel="stylesheet" href="jque ...
- 修改WSAD的默认工作区(转)
如果要一直用某个目录作为工作区,可以在启动WSAD的时候将该目录设为默认工作区,这样启动时直接启动,方便.快捷.但是如果设置后在想换工作区就比较麻烦了,因为没有可供选择的界面了,跟网上搜了一下总结共有 ...
- SpringMVC WEB应用上传照片的实现
使用是SpringMVC+Hibernate搭建的WEB应用,使用jsp写的前端页面. 如何将文件上传到服务器呢?我这里使用的是Multipart的形式将文件上传. 这里有两大步:一是配置multip ...
- luogu3368树状数组模板2
题目链接:https://www.luogu.org/problemnew/show/P3368 题意:与模板1不同的是这题的操作是树状数组并不在行的区间更新和单点查找,如果按照模板1那样写肯定会T. ...
- Codeforces Round #527 (Div. 3) D1. Great Vova Wall (Version 1) 【思维】
传送门:http://codeforces.com/contest/1092/problem/D1 D1. Great Vova Wall (Version 1) time limit per tes ...
- [19/03/31-星期日] IO技术_四大抽象类_字符流( 字符输入流 Reader、 字符输出流 Writer )(含字符缓冲类)
一.概念 Reader Reader用于读取的字符流抽象类,数据单位为字符. int read(): 读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值,即Unicode ...
- docker-1-简介
Dockers的出现: 一款产品从开发到上线,从操作系统,到运行环境,再到应用配置.作为开发+运维之间的协作我们需要关心很多东西, 这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不 ...
- SQL Server遍历所有表统计行数
DECLARE CountTableRecords CURSOR READ_ONLY FOR SELECT sst.name, Schema_name(sst.schema_id) FROM sys. ...