2017-12-02 20:29:42 Zhanganliu 阅读数 589
  • 《C语言基础》 之 第7章 指针

    课程内容:指针—地址的外号&、指针与变量、一级指针的类型、如何定义一个指针变量、使用指针访问变量空间、指针的好处指针的好处、普通传参与指针传参的回顾

    2011 人正在学习 去看看 张先凤

1.函数指针
定义:将函数首地址(入口地址)赋予一个指针变量,使指针指向函数,则通过指针可找到并调用此函数,就是“函数指针变量”。
例如: int (*p)(){}

2.指针型函数
定义:函数的返回值类型是指针(即地址),称为“指针型函数”
例如:int *p(){}
int* p(){}
这两种都是正确的。

3.用一个程序来举例这两种情况:
#include <stdio.h>
int* test(int i);
int main()
{
int* (*p)()= test;
printf(“%d”,*(*p)(2));
return 0;
}
int* test(int i)
{
int b= i * i;
return &b;
}
此函数中定义了一个指针型函数 int test(int i),然后定义了一个函数指针指向test函数,并且此函数指针也是同样的指针型函数,即int (**p)()=test;
test函数体中的返回值可以看到是一个地址,由于返回值是指针型,并且函数指针也是指针型函数,因此能够将b的地址中的值取出,得到结果输出4.

2019-04-03 11:56:24 xishiquanqiu 阅读数 34
  • 《C语言基础》 之 第7章 指针

    课程内容:指针—地址的外号&、指针与变量、一级指针的类型、如何定义一个指针变量、使用指针访问变量空间、指针的好处指针的好处、普通传参与指针传参的回顾

    2011 人正在学习 去看看 张先凤

单片机C语言变量分别有char型,int型,long型,float型等,它们分别占用内存为1个单元,2单元,4单元,4单元等,另外数组和字符串则占用了内存某段连续的单元。这些变量的共同特征是它们都装的数值。那如果一个变量里面装的不是数值,而是地址,这个变量则称为指针变量。所以指针变量用于存储器的地址号。

那么问题又来了,指针变量占多大内存呢?比如char *p,p指针变量前面用char修饰,莫非占一个单元?再例如 long *r,r指针变量前用long修饰,莫非是占4个单元?我们知道C51中,RAM的地址号是从0到255,ROM则是从0到65535。最大的地址号是正整数65535,显然有两个字节便可装下。因此C51中指针变量自身只占两个单元。
既然如此那这些类型修饰符可以不要?我们知道,指针变量中装的是一个地址,也就是说通过这个地址,我便可以找到这个地址中的信息。如果指针指向的是一个char型变量,那么其通过指针(装载char型变量的地址)我找到了这个变量。但如果是指向一个float型变量呢,如果没有这个float来修饰指针变量,那么我们巡着指针只能找到一个字节的数据,而一个float型有4个字节,显然计算机就分不清是不是该把指针后面的三个字节视为一个完整的数据。所以指针变量前面的类型修饰符不是用于修饰指针变量自身所占用的地址数量,而是用于修饰指针变量中所存储的地址与后续地址之间的关联情况。

接下来我们用一个实验来感受下指针的用法。

实验、从单片机发送字符串0123456789到桌面串口调试助手。

#include "reg51.h"
#define u16 unsigned int
#define u8 unsigned char
 
void delay(u16 x)
{
	while(x--);
}
 
void Uart_Init() //串口初始化
{
	SCON=0x50; //8位异步模式
	TMOD|=0x20;	//定时器1工作方式2
	TH1=253;//9600bit/s
	TR1=1;
}
 
void Send_Byte(u8 dat)	  //串口发送一个字节
{
	SBUF=dat; //启动发送,只需要把发送内容给SBUF这个寄存器
	while(TI==0); //等待发送完成,因为TI为1时表示在发送停止位
	TI=0;
}
 
 void Send_String(u8 *str)	 //发送一个字符串	*str为字符串第一个字符的地址
 {
	while(*str)
	{
		Send_Byte(*str);
		str++;
	}
 
 }
 
void main()
{
	Uart_Init();
	while(1)
	{
	   Send_String("0123456789");
	   Send_Byte(10); //回车键
	   delay(60000);
	   delay(60000);
	}
}

从仿真串口接收器来看,这个程序运行得很好。现在我把void Send_String(u8 *str)修改为void Send_String(u16 *str),重新编译并仿真,运行得到

13579?跟着一串乱码,这又是为什么?u16是一个无符号int型,Send_String函数每次会取两个单元作为一个数传进来,进入while循环后,第一次就取"0"*256+"1"传给了Send_Byte函数,而Send_Byte只能装下u8型即一个单元数据,就就是高位的0要溢出,就只剩下1了。所以一直取到了9,之后因为while(*str),继续取字符串后续的内存单元,而这些内存单元里面是什么并不确定,所以显示乱码。

同样我们可以尝试void Send_String(long *str)等等。另外补充一个知识点,定义chara; char *p; p=&a; 其中&是C语言求首地址运算符。

作者:爱学控制的猫
来源:CSDN
原文:https://blog.csdn.net/a514371309/article/details/73557931
版权声明:本文为博主原创文章,转载请附上博文链接!

2010-12-13 16:55:00 xmmcuduck 阅读数 6186
  • 《C语言基础》 之 第7章 指针

    课程内容:指针—地址的外号&、指针与变量、一级指针的类型、如何定义一个指针变量、使用指针访问变量空间、指针的好处指针的好处、普通传参与指针传参的回顾

    2011 人正在学习 去看看 张先凤

      我们都知道,单片机串口传输的单位是字节,而浮点型数是占四个字节,简单思路是用一个char型指针指向浮点型数据,利用指针寻址即可以将浮点数拆成四个char数据。接收端接收到四个char型数,为了还原成float型数据,采用共用体是一不错的方式。测试代码如下:

      

      程序运行结果如下:

     

 

      注意:结构体中如果用有符号字符型数据,在printf打印时有出点小问题,大家可以试试看的,嘿嘿

               当然还有个嵌入式常说的大小端问题,相信大家都明白咋咋回事了。

2009-05-10 10:28:00 zyboy2000 阅读数 1829
  • 《C语言基础》 之 第7章 指针

    课程内容:指针—地址的外号&、指针与变量、一级指针的类型、如何定义一个指针变量、使用指针访问变量空间、指针的好处指针的好处、普通传参与指针传参的回顾

    2011 人正在学习 去看看 张先凤

 一般指针

一般指针的声明和使用均与标准C相同,不过同时还可以说明指针的存储类型,例如:

long * state;为一个指向long型整数的指针,而state本身则依存储模式存放。

char * xdata ptrptr为一个指向char数据的指针,而ptr本身放于外部RAM区,以上的long,char等指针指向的数据可存放于任何存储器中。

 

一般指针本身用3个字节存放,分别为存储器类型,高位偏移,低位偏移量。 2. 存储器指针

 

基于存储器的指针说明时即指定了存贮类型,例如:

 

char data * str;str指向data区中char型数据

int xdata * pow; pow指向外部RAMint型整数。

这种指针存放时,只需一个字节或2个字节就够了,因为只需存放偏移量。

 

 

/*.........................................................................................

char * xdata ptr       //ptr本身放在Xdata(XRAM)

 

char xdata * ptr;       //ptr指向的数据放在Xdata(XRAM)

........................................................................................*/

 

 

char xdata * px

char xdata * data px

data char xdata * px

3者有什么不同??

 

char xdata * px

px本身存在于自动分配的空间,一般位于data,指向的内容位于xdata

char xdata * data px

px本身存在于data空间,指向的内容位于xdata

data char xdata * px =char xdata *data px

 

 

data:固定指前面0x00-0x7f128RAM,可以用acc直接读写的,速度最快,生成的代码也最小。

idata:固定指前面0x00-0xff256RAM,其中前128data128完全相同,只是因为访问的方式不同。idata是用类似C中的指针方式

访问的。汇编中的语句为:mox ACC,@Rx.(不重要的补充:cidata做指针式的访问效果很好)

xdata:外部扩展RAM,一般指外部0x0000-0xffff空间,用DPTR访问。

pdata:外部扩展RAM的低256个字节,地址出现在A0-A7的上时读写,用movx ACC,@Rx读写。这个比较特殊,而且C51好象有对此BUG建议少用。但也有他的优点,具体用法属于中级问题,这里不提。

 

 

 

 

xdata unsigned char *p; 和 unsigned char  * xdata p; 完全一样。
因为C写法中允许“最前面的存储类型修饰符修饰最后面的对象

 

(1) unsigned char * xdata p

表明指针本身位于Xdata,至于指向什么类型的地址,自由变换.

例如

unsigned char a_data;

unsigned char xdata b_xdata;

 

当p = &a_data; *p等于a_data;它表示p指向的地址自动转换成data地址

当p = &b_xata; *p等于b_data;它表示p指向的地址自动转换成xdata地址

 

 

 

(2)unsigned char xdata * p   //注意:这种用法不推荐

表示指针指向的地址是xdata

 

unsigned char a_data;

unsigned char xdata b_xdata;

 

当p = &a_data; *p不等于a_data;因为尽管相对地址相同,但a_data的地址在data空间中,而p指向的地址是xdata空间。(KEIL也会提示空间匹配错误)

 

 

当p = &b_xata; *p等于b_data;因为b_data本身就放在xdata,而p指向的地址是xdata。所以没有问题。

 

所以在定义指针的时候,如果不确定传入的参数的空间范围是哪里,最好不要限定指针指向的地址。例如直接用unsigned char *p。它会根据不同参数的空间,自动寻找相应的地址!

unsigned char *p   //推荐

 

2019-11-02 23:12:43 ziqing0701 阅读数 5
  • 《C语言基础》 之 第7章 指针

    课程内容:指针—地址的外号&、指针与变量、一级指针的类型、如何定义一个指针变量、使用指针访问变量空间、指针的好处指针的好处、普通传参与指针传参的回顾

    2011 人正在学习 去看看 张先凤

include ''reg52.h" 单片机特殊功能寄存器定义文件

typedef 数据类型申明
例如 typedef unsigned int u16
定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:
char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针,
// 和一个字符变量;
以下则可行:
typedef char* PCHAR; // 一般用大写
PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针
虽然:
char *pa, *pb;
也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。

sbit 定义特殊功能寄存器的位变量。
例如sbit F=P1^4;//将F位定义为 P1.4

三极管放大管脚输出电流 驱动元器件
三极管应用
三极管的放大倍数与其物理结构有关,选择三极管时放大倍数β是必须考虑的重要技术指标之一,

三极管的电流方向以及三个极之间的电流关系如下图,IC=βIB,IE=IB+IC
在这里插入图片描述
三极管有饱和、放大和截止三个工作区间,下面介绍一些常见的用法;

(1)驱动放大,一般单片机、DSP、ARM、CPLD/FPGA等CPU的IO口驱动电流比较弱,无法直接驱动负载,最常用的是使用三极管进行电流驱动能力放大,如下图所示;
在这里插入图片描述
示意原理驱动LED灯,可以根据实际需要变换为其它负载,比如继电器、电机等;+5V电源也可以改变,比如12V/24V等,但所选三极管必须能够承受这个电压。

(2)逻辑取反,如下图所示,使用NPN三极管进行取反,十分方便,输入为高电平时,输出为低;输入为低电平时,输出为高(5V)。
在这里插入图片描述
(3)当电子开关使用,当电子开关时一般使用三极管的饱和区,通过控制基极使三极管处于饱和或截止区,从而实现三极管开通或断开,起到开关的作用。

code和data关键字
code的作用是告诉单片机,定义的数据要放在ROM(程序存储区)里面,写入后就不能再更改。因为C语言中没办法详细描述存入的是ROM还是RAM(寄存器),所以在软件中添加了这一个语句起到代替汇编指令的作用,对应的还有data是存入RAM的意思。

程序可以简单的分为code(程序)区,和data (数据)区,code区在运行的时候是不可以更改的,data区放全局变量和临时变量,是要不断的改变的,cpu从code区读取指令,对data区的数据进行运算处理。

c51中的存储类型:

code :程序存储区(64KB)

data :可直接寻址的内部数据存储区(128B)

idata:不可直接寻址的内部数据存储区(256B)

bdata:可位寻址内部数据存储区(16B)

xdata:外部数据存储区(64KB)

pdata:分页的外部数据存储区

C51单片机复习资料

阅读数 1424

没有更多推荐了,返回首页