指针C51.
- 格式:doc
- 大小:34.00 KB
- 文档页数:3
C51的指针指针是C语言的一个特殊的变量,它存储的数值被解释成为内存的一个地址。
指针定义的一般形式如下。
数据类型*指针变量名;例如:int i,j,k,*i_ptr; //定义整型变量i,j,k和整型指针变量i_ptr。
指针运算包括以下两种:(1)取地址运算符。
取地址运算符&是单目运算符,其功能是取变量的地址,例如:i_ptr=&i; //变量i的地址送给指针变量i_ptr(2)取内容运算符。
取内容运算符“*”是单目运算符,用来表示指针变量所指单元的内容,在星号“*”运算符之后跟的必须是指针变量。
例如:j=*i_ptr; //将i_ptr所指的单元的内容赋给变量j可以把数组的首地址赋予指向数组的指针变量。
例如:int a[5],*ap;ap=a; //数组名表示数组的首地址,故可赋予指向数组的指针变量也可以写成:ap=&a[0]; //数组第一个元素的地址也是整个数组的首地址,也可赋予指针变量ap 还可以采用初始化赋值的方法:int a[5],*ap=a;也可以把字符串的首地址赋予指向字符类型的指针变量。
例如:unsigned char *cp;cp="Hello World!";这里应该说明的是,并不是把整个字符串装入指针变量,而是把存放该字符串的字符数组的首地址装入指针变量。
对于指向数组的指针变量,可以进行加减运算,例如:cp--; //cp指向上一个数组元素ap++; //ap指向下一个数组元素例如:定义了指针类型的形式参数如下:uchar *str;该形式参数表示一个无符号字符型变量的地址。
可以采用以下赋值语句:SBUF=*(str+k); //将单元地址为str+k的内容赋给专用寄存器SBUF,启动发送在调用该函数时,直接把数组trdata[]的数组名作为实际参数代入即可,因为数组名表示数组的首地址,故可直接赋予指向数组的指针变量。
c51指针用法
C51是一种常用的单片机,使用指针可以更灵活地操作内存和外设。
在C51中,指针可以用于访问和操作内存中的数据,也可以用于操作外设寄存器。
首先,我们可以使用指针来访问和操作内存中的数据。
在C51中,内存被分为不同的存储区域,如代码区、数据区和堆栈区。
通过使用指针,我们可以直接访问和修改这些存储区域中的数据。
例如,我们可以使用指针来读取和修改数组中的元素,而不需要使用数组索引。
这种方法可以提高程序的执行效率。
其次,指针还可以用于操作外设寄存器。
在单片机编程中,外设寄存器用于控制和配置外部设备,如GPIO(通用输入输出)、定时器和串口等。
通过使用指针,我们可以直接访问和修改这些寄存器的值,从而控制外部设备的行为。
例如,我们可以使用指针来设置GPIO引脚的状态,或者配置定时器的工作模式。
除了访问和操作内存和外设寄存器,指针还可以用于动态内存分配和数据结构的操作。
在C51中,我们可以使用指针来动态分配内存,并在运行时根据需要分配和释放内存。
这种灵活的内存管理方式可以提高程序的效率和灵活性。
此外,指针还可以用于创建和操作复杂的数据结构,如链表和树等。
通过使用指针,我们可以方便地插入、删除
和修改数据结构中的元素。
总之,C51中的指针用法非常重要,可以帮助我们更灵活地操作内存和外设。
通过使用指针,我们可以提高程序的执行效率,实现动态内存分配,以及创建和操作复杂的数据结构。
因此,熟练掌握C51指针的用法对于单片机编程非常重要。
C51 指针问题一般指针一般指针的声明和使用均与标准C 相同,不过同时还可以说明指针的存储类型,例如:long * state;为一个指向long 型整数的指针,而state 本身则依存储模式存放。
char * xdata ptr;ptr 为一个指向char 数据的指针,而ptr本身放于外部RAM 区,以上的long,char 等指针指向的数据可存放于任何存储器中。
一般指针本身用3 个字节存放,分别为存储器类型,高位偏移,低位偏移量。
2.存储器指针基于存储器的指针说明时即指定了存贮类型,例如:chardata * str;str 指向data 区中char 型数据int xdata * pow; pow 指向外部RAM 的int 型整数。
这种指针存放时,只需一个字节或2 个字节就够了,因为只需存放偏移量。
/*.........................................................................................char * xdata ptr;//ptr 本身放在Xdata(XRAM)区char xdata * ptr;//ptr 指向的数据放在Xdata(XRAM)区........................................................................................*/char xdata * pxchar xdata * data pxdata char xdata * px 这3 者有什么不同??char xdata * pxpx 本身存在于自动分配的空间,一般位于data 中,指向的内容位于xdatachar xdata * data pxpx 本身存在于data 空间,指向的内容位于xdatadata char xdata * px =char xdata *data pxdata:固定指前面0x00-0x7f 的128 个RAM,可以用acc直接读写的,速度最快,生成的代码也最小。
C51的数据类型引言概述:C51是一种常用的单片机型号,它具有丰富的数据类型,这些数据类型在嵌入式系统中具有重要的作用。
本文将详细介绍C51的数据类型,包括基本数据类型、指针类型、数组类型、结构体类型以及枚举类型。
一、基本数据类型1.1 位类型(bit):C51提供了位类型,用于表示一个二进制位的数据。
位类型可以用于节省内存空间,特别适用于对一个变量的各个位进行操作的场景。
1.2 字符类型(char):C51的字符类型用于表示一个字符的数据,它占用一个字节的内存空间。
字符类型可以用于表示ASCII码字符,也可以用于表示整数。
1.3 整数类型(int):C51的整数类型用于表示整数数据。
根据不同的编译器和硬件平台,整数类型的长度可以不同,一般为2个字节或4个字节。
二、指针类型2.1 指针类型(*):C51的指针类型用于表示一个变量的地址。
通过指针类型,可以实现对变量的间接访问,提高程序的灵活性和效率。
2.2 空指针(NULL):C51提供了空指针常量NULL,用于表示一个无效的指针。
空指针在程序中常用于初始化指针变量或判断指针是否有效。
2.3 指针运算:C51支持指针的运算,包括指针的加法、减法和比较运算。
指针运算可以用于实现数组的访问和遍历。
三、数组类型3.1 一维数组:C51的一维数组用于存储相同类型的数据,可以通过下标访问数组元素。
一维数组在嵌入式系统中广泛应用,用于存储大量的数据。
3.2 多维数组:C51的多维数组是一种特殊的一维数组,它可以存储多维的数据。
多维数组可以用于表示矩阵、图像等复杂的数据结构。
3.3 字符串数组:C51的字符串数组是一种特殊的字符数组,用于存储字符串数据。
字符串数组在嵌入式系统中常用于存储文本信息。
四、结构体类型4.1 结构体定义:C51的结构体类型用于表示一组相关的数据,可以包含不同类型的成员变量。
通过结构体类型,可以方便地组织和操作复杂的数据结构。
4.2 结构体成员访问:C51使用点操作符(.)来访问结构体的成员变量。
C51的数据类型C51是一种常用的单片机型号,广泛应用于嵌入式系统和微控制器开发中。
在C51编程中,数据类型是非常重要的概念,它决定了变量在内存中的存储方式和所占用的空间大小。
本文将详细介绍C51的数据类型及其特点。
一、基本数据类型1. 位(bit):C51的最小存储单位是位,它只能存储0或1。
位类型的变量在内存中占用1位空间。
2. 位域(bit-field):位域是一种特殊的数据类型,它允许将一个字节中的位划分为多个字段,并为每个字段指定不同的位数。
位域可以节省内存空间,提高程序的执行效率。
3. 字节(byte):字节是C51中最基本的数据类型,它占用8位空间,可以存储-128到127之间的整数。
4. 无符号字节(unsigned byte):无符号字节是字节的一种特殊类型,它只能存储0到255之间的整数。
5. 半字(halfword):半字是由两个字节组成的数据类型,它占用16位空间,可以存储-32768到32767之间的整数。
6. 无符号半字(unsigned halfword):无符号半字是半字的一种特殊类型,它只能存储0到65535之间的整数。
7. 字(word):字是由四个字节组成的数据类型,它占用32位空间,可以存储-2147483648到2147483647之间的整数。
8. 无符号字(unsigned word):无符号字是字的一种特殊类型,它只能存储0到4294967295之间的整数。
二、扩展数据类型1. 长整型(long):长整型是C51中的扩展数据类型,它占用4个字节空间,可以存储更大范围的整数,从-2147483648到2147483647之间。
2. 无符号长整型(unsigned long):无符号长整型是长整型的一种特殊类型,它只能存储0到4294967295之间的整数。
3. 单精度浮点型(float):单精度浮点型是一种用于表示带小数部分的数值的数据类型,它占用4个字节空间,可以存储小数。
C51的数据类型引言概述:C51是一种常用的微控制器,广泛应用于嵌入式系统中。
在C51编程中,了解和正确使用数据类型是非常重要的。
本文将详细介绍C51的数据类型,包括基本数据类型、派生数据类型、数组和指针、结构体和联合体、枚举类型。
一、基本数据类型:1.1 位类型(bit):C51中最小的数据类型,只能存储0或1,用于表示开关状态等。
1.2 字符类型(char):用于存储一个字符,占用一个字节的内存空间,范围为-128到127。
1.3 整数类型(int):用于存储整数值,占用两个字节的内存空间,范围为-32768到32767。
二、派生数据类型:2.1 无符号整数类型(unsigned):用于存储非负整数值,范围为0到65535。
2.2 短整数类型(short):用于存储较小的整数值,占用一个字节的内存空间,范围为-128到127。
2.3 长整数类型(long):用于存储较大的整数值,占用四个字节的内存空间,范围为-2147483648到2147483647。
三、数组和指针:3.1 数组:C51中的数组是一种存储相同类型数据的集合,可以按照索引访问其中的元素。
数组的大小在声明时确定,可以是一维或多维的。
3.2 指针:指针是一种特殊的数据类型,用于存储内存地址。
在C51中,指针可以指向任何类型的数据。
通过指针,可以实现对内存中数据的直接访问和操作。
四、结构体和联合体:4.1 结构体:结构体是一种自定义的数据类型,可以将不同类型的数据组合在一起,形成一个新的数据类型。
结构体的成员可以是基本数据类型或其他结构体。
4.2 联合体:联合体是一种特殊的结构体,所有成员共享同一块内存空间。
联合体的大小取决于最大成员的大小,只能同时存储一个成员的值。
五、枚举类型:5.1 枚举类型:枚举类型用于定义一组命名的常量,可以提高程序的可读性。
在C51中,枚举类型的取值范围为整数类型。
总结:C51的数据类型包括基本数据类型(位类型、字符类型、整数类型)、派生数据类型(无符号整数类型、短整数类型、长整数类型)、数组和指针、结构体和联合体、枚举类型。
Keil C51 中的函数指针和再入函数,函数指针与overlay=====调用树的保存C51不把函数参数压栈(除非使用再入函数)。
函数参数和全局变量被存入寄存器或固定的存储空间。
这样阻止函数的再入。
例如,一个函数调用它自己,它将覆盖它自己的参数或存储空间。
函数的再入问题通过关键字“reentrant”来解决。
函数指针的非再入函数的副作用,在执行中出现问题。
MAIN函数调用FUNC和FUNC_CALLER(根据调用树)。
用函数的指针来传递参数,调用树往往会出错。
=====转这篇文章是由Keil C51 的英文文档翻译过来的,很多语句都是根据自己的理解翻译的,肯定还有许多地方需要推敲。
希望读者能吸取到有用的部分,不要被误解了,自己多理解。
Overlay修改用于数据覆盖的调用树。
如果在用户程序里使用了函数指针,或者使用了像实时操作系统中调度器那样的跳转(k 指的是指针方式的调用吗?),那么,修改程序调用树将是很有必要的。
混合编程:函数名符号名解释viod func(void) FUNC 无参数传递,或不含寄存器参数的函数名不作改变转入目标文件中,名字只是简单地转为大写形式viod func(char) _FUNC 带寄存器参数的函数名加入“_”字符前缀,它表明这类函数包含寄存器内的参数传递viod func(viod) reentrant _?FUNC “_?”表示可重入,它表明该行数包含栈内的参数传递。
====将下面这篇的难点内容提到前面使用函数指针的附加说明如果你在C51中使用函数指针编程,有几个附加的说明你必须注意。
参数列表的限制通过函数指针传递参数给函数必须把所有的参数存入寄存器。
在大部分情况下,3个参数能够自动通过寄存器传递。
在C51的用户手册中能找到传递参数进入寄存器的运算法则。
但是并不保证,任何的3个数据类型可以传递。
因为C51在寄存器中传递3个参数,用于传递参数的存储空间是不被分配的,除非函数指向一个要求更多参数的函数。
C51常用数据类型引言概述:在C51单片机编程中,数据类型是非常重要的概念,不同的数据类型决定了数据在内存中的存储方式和范围。
了解C51常用数据类型对于编写高效、可靠的程序至关重要。
一、基本数据类型1.1 位类型(bit)- 位类型是C51中最基本的数据类型,只能存储0或者1,用于表示逻辑状态。
- 位类型在C51中占用1位的存储空间,通常用于控制寄存器的位操作。
- 位类型的声明方式为bit,例如:bit flag = 1;1.2 无符号整型(unsigned int)- 无符号整型用于表示非负整数,范围为0到65535。
- 无符号整型在C51中占用2个字节的存储空间,通常用于存储计数器、计时器等变量。
- 无符号整型的声明方式为unsigned int,例如:unsigned int count = 100;1.3 有符号整型(int)- 有符号整型用于表示带符号的整数,范围为-32768到32767。
- 有符号整型在C51中同样占用2个字节的存储空间,通常用于存储温度、速度等带符号的数据。
- 有符号整型的声明方式为int,例如:int temperature = -20;二、扩展数据类型2.1 无符号长整型(unsigned long)- 无符号长整型用于表示较大的非负整数,范围为0到4294967295。
- 无符号长整型在C51中占用4个字节的存储空间,通常用于存储较大的计数值。
- 无符号长整型的声明方式为unsigned long,例如:unsigned long total = 100000;2.2 有符号长整型(long)- 有符号长整型用于表示较大的带符号整数,范围为-2147483648到2147483647。
- 有符号长整型在C51中同样占用4个字节的存储空间,通常用于存储较大的带符号数据。
- 有符号长整型的声明方式为long,例如:long distance = -50000;2.3 浮点型(float)- 浮点型用于表示带小数点的数值,范围和精度较高。
keil c51指针参数调用在嵌入式系统开发中,Keil C51是一种常用的编译器,特别适用于C语言的嵌入式开发。
在Keil C51中,指针参数的调用是一种常见的编程技巧,本文将介绍指针参数的概念、用法以及一些注意事项。
一、指针参数的概念指针是C语言中一种非常重要的数据类型,它存储了一个变量的内存地址。
通过指针,我们可以间接地访问和修改对应的变量。
指针参数是指在函数的参数列表中使用指针作为形参的一种方式。
二、指针参数的用法在Keil C51中,使用指针参数可以实现函数间的数据共享和传递。
具体而言,指针参数可以用于以下几个方面:1. 传递数组数组在C语言中是一种连续存储的数据结构,通过指针参数可以高效地传递数组给函数。
在函数中,可以通过指针来访问和修改数组元素的值。
2. 传递结构体结构体是C语言中一种用户自定义的数据类型,由多个不同类型的成员变量组成。
通过指针参数,可以将结构体传递给函数,并在函数中对结构体的成员进行操作。
3. 函数返回多个值在某些情况下,一个函数可能需要返回多个值。
通过指针参数,可以将多个变量的地址传递给函数,并在函数中将结果保存到这些地址对应的变量中。
三、指针参数的注意事项使用指针参数需要注意以下几个问题:1. 空指针检查在使用指针参数之前,需要先检查指针是否为空。
如果指针为空,可能导致程序崩溃或者产生不可预料的结果。
2. 指针的生命周期在使用指针参数时,需要注意指针的生命周期。
确保指针指向的内存空间在使用期间一直有效,避免访问已经释放的内存。
3. 指针的类型匹配指针参数的类型必须与实际参数的类型匹配,否则会导致编译错误。
在使用指针参数时,需要注意类型的一致性。
四、示例代码下面是一个简单的示例代码,演示了如何在Keil C51中使用指针参数:```c#include <stdio.h>// 传递数组给函数void printArray(int *arr, int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]);}printf("\n");}// 传递结构体给函数struct Point {int x;int y;};void printPoint(struct Point *p) {printf("(%d, %d)\n", p->x, p->y); }// 函数返回多个值void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;}int main() {int arr[] = {1, 2, 3, 4, 5};int size = sizeof(arr) / sizeof(int);printArray(arr, size);struct Point p = {10, 20};printPoint(&p);int a = 10, b = 20;swap(&a, &b);printf("a = %d, b = %d\n", a, b);return 0;}```在上述示例代码中,我们定义了三个函数:`printArray`用于打印数组,`printPoint`用于打印结构体,`swap`用于交换两个变量的值。
C51常用数据类型引言概述:C51是一种广泛应用于嵌入式系统开辟的单片机系列,其常用数据类型对于程序的编写和数据处理起着重要的作用。
本文将详细介绍C51常用的数据类型及其特点,包括基本数据类型、数组类型、结构体类型、指针类型和枚举类型。
正文内容:1. 基本数据类型1.1 位数据类型:C51提供了位数据类型bit,用于表示一个二进制位,可以进行逻辑运算和位操作。
1.2 字符数据类型:C51中的字符数据类型char用于表示一个字符,可以进行字符操作和ASCII码的转换。
1.3 整数数据类型:C51提供了不同长度的整数数据类型,如unsigned char、unsigned int和unsigned long,用于表示不同范围的整数。
2. 数组类型2.1 一维数组:C51支持一维数组,可以存储一组相同类型的数据,通过索引访问数组元素。
2.2 二维数组:C51还支持二维数组,可以存储表格型数据,通过两个索引访问数组元素。
2.3 多维数组:C51还支持多维数组,可以存储多维表格型数据,通过多个索引访问数组元素。
3. 结构体类型3.1 定义结构体:C51允许定义结构体类型,结构体可以包含多个不同类型的成员变量,用于表示复杂的数据结构。
3.2 访问结构体成员:通过结构体变量和成员运算符“.”,可以访问结构体的各个成员变量。
3.3 结构体作为函数参数:结构体可以作为函数的参数传递,方便地传递和处理复杂的数据结构。
4. 指针类型4.1 定义指针变量:C51支持指针类型,可以定义指向不同类型的指针变量。
4.2 指针的运算:指针可以进行运算,如指针的加减运算、指针与整数的运算等。
4.3 指针的应用:指针在C51中有广泛的应用,如动态内存分配、数组和字符串的处理等。
5. 枚举类型5.1 定义枚举类型:C51支持枚举类型,可以定义一组具有相同属性的常量。
5.2 枚举常量的使用:通过枚举类型定义的常量可以直观地表示某种状态或者选项。
C51常用数据类型引言概述:C51是一种常用的单片机系列,广泛应用于嵌入式系统开发中。
在C51的编程过程中,数据类型的选择对程序的性能和可靠性有着重要影响。
本文将介绍C51常用的数据类型及其特点。
一、基本数据类型1.1 位(bit):C51中最小的数据类型,只能表示0或1。
1.2 位域(bitfield):用于将一个字节中的一部分位定义为一个字段。
1.3 字节(byte):C51中最基本的数据类型,占用一个字节。
二、整型数据类型2.1 char:有符号字符型,占用一个字节。
2.2 unsigned char:无符号字符型,占用一个字节。
2.3 int:有符号整型,一般占用两个字节。
三、浮点数据类型3.1 float:单精度浮点型,一般占用四个字节。
3.2 double:双精度浮点型,一般占用八个字节。
3.3 long double:长双精度浮点型,一般占用十二个字节。
四、指针数据类型4.1 char *:指向字符型数据的指针。
4.2 int *:指向整型数据的指针。
4.3 void *:通用指针类型,可以指向任意类型的数据。
五、其他数据类型5.1 enum:枚举类型,用于定义一组有名字的整型常量。
5.2 struct:结构体类型,用于将不同类型的数据组合在一起。
5.3 union:联合类型,用于共享内存空间,不同成员共用同一块内存。
总结:C51常用的数据类型包括基本数据类型、整型数据类型、浮点数据类型、指针数据类型以及其他数据类型。
在编程过程中,选择合适的数据类型能够提高程序的效率和可维护性。
熟练掌握各种数据类型的特点和用法,是提高C51编程技能的关键之一。
C51的数据类型引言:C51是一种常用的单片机系列,它具有丰富的数据类型,这些数据类型在嵌入式系统中起着至关重要的作用。
本文将详细介绍C51的数据类型,包括整数类型、浮点数类型、字符类型和指针类型。
一、整数类型1.1 无符号整数类型:C51提供了多种无符号整数类型,如unsigned char、unsigned int和unsigned long等。
这些类型的取值范围分别是0到255、0到65535和0到4294967295,用于表示非负整数。
1.2 有符号整数类型:C51也提供了有符号整数类型,如signed char、signed int 和signed long等。
这些类型的取值范围分别是-128到127、-32768到32767和-2147483648到2147483647,用于表示正负整数。
1.3 位域类型:C51还支持位域类型,用于在一个字节中定义多个字段。
通过位域类型,可以有效地利用存储空间,提高程序的效率。
二、浮点数类型2.1 单精度浮点数类型:C51提供了float类型,用于表示单精度浮点数。
float类型占用4个字节,可以表示大约6到7位有效数字的浮点数。
2.2 双精度浮点数类型:C51还提供了double类型,用于表示双精度浮点数。
double类型占用8个字节,可以表示大约15到16位有效数字的浮点数。
三、字符类型3.1 字符类型:C51使用char类型来表示字符。
char类型占用1个字节,可以表示ASCII码字符或扩展字符。
3.2 字符串类型:C51中的字符串是由一系列字符组成的,以null字符'\0'结尾。
字符串常常用于存储文本信息,如显示在LCD屏幕上的文字。
四、指针类型4.1 指针类型:C51支持指针类型,用于存储变量的地址。
指针可以指向任何类型的数据,包括整数、浮点数、字符和结构体等。
4.2 空指针类型:C51还提供了空指针类型void*,用于表示一个不指向任何具体类型的指针。
C51数据类型引言概述:C51是一种常用的单片机开发平台,其数据类型是编程过程中至关重要的一部分。
正确使用和理解C51的数据类型可以提高程序的效率和可靠性。
本文将介绍C51的数据类型及其使用方法。
一、基本数据类型1.1 无符号整数类型(unsigned)- 无符号整数类型用于表示非负整数,范围从0到最大值。
- 无符号整数类型在内存中以二进制形式存储,可以使用关键字"unsigned"声明。
- 无符号整数类型的大小取决于单片机的位数,如8位单片机的无符号整数类型为8位。
1.2 有符号整数类型(signed)- 有符号整数类型用于表示正负整数,范围从最小值到最大值。
- 有符号整数类型在内存中以二进制补码形式存储,可以使用关键字"signed"声明。
- 有符号整数类型的大小也取决于单片机的位数,如8位单片机的有符号整数类型为8位。
1.3 浮点数类型(float)- 浮点数类型用于表示带小数部分的数值。
- 浮点数类型在内存中以IEEE 754标准表示,可以使用关键字"float"声明。
- 浮点数类型的大小为32位,可以表示较大范围的数值和较高的精度。
二、扩展数据类型2.1 长整数类型(long)- 长整数类型用于表示较大范围的整数,范围从最小值到最大值。
- 长整数类型在内存中以二进制补码形式存储,可以使用关键字"long"声明。
- 长整数类型的大小为16位或32位,取决于单片机的位数。
2.2 字符类型(char)- 字符类型用于表示单个字符,可以是字母、数字或特殊字符。
- 字符类型在内存中以ASCII码形式存储,可以使用关键字"char"声明。
- 字符类型的大小为8位。
2.3 布尔类型(bit)- 布尔类型用于表示真(1)或假(0)的值。
- 布尔类型在内存中以1位存储,可以使用关键字"bit"声明。
C51常用数据类型在C51单片机编程中,常用数据类型是指用于存储不同类型数据的变量类型。
C51常用数据类型包括整型、字符型、浮点型和指针型。
下面将详细介绍每种数据类型的特点和用法。
1. 整型数据类型整型数据类型用于存储整数值,包括有符号整型和无符号整型。
有符号整型可以表示正数、负数和零,而无符号整型仅能表示非负数(正数和零)。
C51常用的整型数据类型有:- char:有符号字符型,占用1个字节(8位),表示范围为-128到127。
- unsigned char:无符号字符型,占用1个字节(8位),表示范围为0到255。
- int:有符号整型,占用2个字节(16位),表示范围为-32768到32767。
- unsigned int:无符号整型,占用2个字节(16位),表示范围为0到65535。
- long:有符号长整型,占用4个字节(32位),表示范围为-2147483648到2147483647。
- unsigned long:无符号长整型,占用4个字节(32位),表示范围为0到4294967295。
整型数据类型适合于存储整数值,如计数器值、传感器数据等。
2. 字符型数据类型字符型数据类型用于存储单个字符,采用ASCII码表示。
C51常用的字符型数据类型是char,占用1个字节(8位)。
字符型数据类型适合于存储字母、数字、标点符号等单个字符。
3. 浮点型数据类型浮点型数据类型用于存储带有小数部份的数值。
C51常用的浮点型数据类型是float,占用4个字节(32位)。
浮点型数据类型适合于存储需要进行精确计算的数值,如测量数据、传感器数据等。
4. 指针型数据类型指针型数据类型用于存储变量的地址。
C51常用的指针型数据类型是指针变量名加之"*"符号。
指针变量存储的是内存地址,可以通过指针访问该地址上存储的数据。
指针型数据类型适合于需要直接操作内存地址的情况,如动态内存分配、函数指针等。
C51单片机指针变量的定义及应用一。
指针变量的定义指针变量定义与一般变量的定义类似,其形式如下:数据类型[存储器类型1]* [存储器类型2]标识符;[存储器类型1]表示被定义为基于存储器的指针。
无此选项时,被定义为一般指针。
这两种指针的区别在于它们的存储字节不同。
一般指针在内存中占用三个字节,第一个字节存放该指针存储器类型的编码(由编译时由编译模式的默认值确定),第二和第三字节分别存放该指针的高位和低位地址偏移量。
存储器类型的编码值如下:存储类型IIdata/data/bdataxdatapdataCode编码值0x000x010xFE0xFF[存储类型2]用于指定指针本身的存储器空间。
1、char * c_ptr;int * i_ptr;long * l_ptr;上述定义的是一般指针,c_ptr指向的是一个char型变量,那么这个char型变量位于哪里呢?这和编译时由编译模式的默认值有关,如果Menory Model—Variable—Large:XDATA,那么这个char型变量位于xdata区:如果Menory Model—Variable—Compact:PDATA,那么这个char型变量位于pdata 区:如果Menory Model——Variable——Small:DATA,那么这个char型变量位于data区。
而指针c_ptr,i_ptr,l_ptr变量本身位于片内数据存储区中。
2、char * data c_ptr;int * idata i_ptr;long * xdata l_ptr;上述定义,c_ptr,i_ptr,l_ptr变量本身分别位于data ,idata,xdata区。
3、。
Keil C51中函数指针的使用3■江西理工大学 朱博 许伦辉 函数指针在C语言中应用较为灵活。
在单片机系统中,嵌入式操作系统、文件系统和网络协议栈等一些较为复杂的应用都大量地使用了函数指针。
K eil公司推出的C51编译器是事实上80C51C编程的工业标准,它针对8051系列CPU硬件在标准ANSI C的基础上进行了扩展;但由于编译器及8051体系结构的限制,造成了在使用函数指针时有很多与ANSI C不同的地方。
下面举例说明在不同的情形下函数指针的使用。
以下代码均在K eilμVision3、v8.08 C51、默认优化等级的开发环境下验证通过。
1 指向固定地址的指针在程序设计中,常需要跳转到某一特定的地址上执行,如引导程序的设计。
可通过如下C语言实现: int main(void){((void(code3)(void))0x2000)();return0;}此代码使得主函数执行位于0x2000地址的程序代码。
其中((void(code3)(void))是一种数据类型,表示一指向代码段函数的指针,该函数无参数和无返回值。
它对数据0x2000进行了强制类型转换,使函数指针指向地址为0x2000的代码段地址。
关于复杂类型的声明详见参考文献[1]。
通过反汇编窗口可看到编译器生成了如下汇编代码: C:0x000F 122000 LCALL C:2000由上可以看出,Keil C51是非常高效的编译器,产生了非常简洁的输出。
这正是我们所期望的。
2 无参数的函数指针Keil C51中不带参数的函数指针的使用方法与ANSI3国家自然科学基金项目(No:60664001):基于分布式多智能体的城市交通协调控制理论及应用研究。
C基本相同。
示例如下: void foo(void){ return;}int main(void){ void(3pfoo)(void);//声明函数指针pfoo pfoo=foo;//对该指针赋值,使该指针指向某一函数 (3pfoo)();//通过指针调用其指向的函数 return0;}3 带参数的函数指针一般来说,函数参数是通过堆栈来传递,用PUSH和POP汇编指令来实现的;但由于8051体系及其编译器的一些限制,使得其函数参数的传递需要一些特殊的方法。
C51编译器-语言扩展(3)-指针Pointers指针Cx51支持使用字符*来声时一个指针类型的变量。
Cx51的指针可以完成标准C的所有功能。
然而,由于8051及其变种的特殊构架,Cx51使用两种类的指针: memory-specific pointers and generic pointers(特定存储器类型指针和通用指针),Generic Pointers通用指针的定义方法与标准C指针的定义方法相同。
通用指针总是使用三个字节来存储。
第一个字节是存储器类型。
第二字节是偏移量的高位,第三字节是偏移量的低位。
通用指针可以访问所用的变量,而不论变量位于8051的哪一个存储区内。
因为这个原因,许多8051的运行时库都使用这个种指针。
通过使用通用指针,函数可以访问所有的内存区域注意:使用通用指针产生的代码比用特定存储器类型指针生成的代码执效率要低得多。
这是因为在运行前变量的内存区域是不知道的。
编译器不能优化存储器的访问,而是要生成适合所有存域的代码。
如果要获得高的运行速度,最好使用特定存储器类型指针。
为运行速度考虑,也可以设定指针的存储区,在声明指针时前面加上储存区类型标识就可以把指针放在特定的存储器区域。
char * xdata strptr; /* generic ptr stored in xdata */int * data numptr; /* generic ptr stored in data */long * idata varptr; /* generic ptr stored in idata */在上面的例子中,指针指向的内容可以放在任何一个空间内,但指针必须放在xdata, data, and idata中。
Memory-specific Pointers特定存储器类型指针在声明时总是包含了内存类型的声明,并且只能指向特定的内存区域。
如:char data *str; /* ptr to string in data */int xdata *numtab; /* ptr to int(s) in xdata */long code *powtab; /* ptr to long(s) in code */因为在编译的时候内存的类型就已经确定了,通用指针的存储器类型就不再需要了。
指针可以放在一个字节(idata, data, bdata, pdata)或两个字节(code, xdata)中。
根通用针一样,我们可以指特定存储器类型指针的存储区域,如char data * xdata str; /* ptr in xdata to data char */int xdata * data numtab; /* ptr in data to xdata int */long code * idata powtab; /* ptr in idata to code long */在上面的例子中,指针指向的内容可以放在任何一个空间内,但指针必须放在xdata, data, and idata中Pointer Conversions指针变换Cx51可以使通用指针和特定存储类型指针相互转换,这种转换可以通过程序代码声时转换,也可以由编译器强迫执行。
当一个特定存储器类型指针的参数传给一个便用指针做参数的函数,Cx51编译器就进行指针类型的转换。
当一个特定存储器类型指针传给一个函数,而这个函的原型又没有出现时总是转换成通用指针。
而如果这个函数使用的是短指针,这时就会发生错误。
为了避免在程序中出现这种错误,使#include文件,并声明所有外部函数的原型。
转换细节generic * to code * The offset section (2 bytes) of the generic pointer is used.generic * to xdata * The offset section (2 bytes) of the generic pointer is used.generic * to data * The low-order byte of the generic pointer offset is used.The high-order byte is discarded.generic * to idata * The low-order byte of the generic pointer offset is used.The high-order byte is discarded.generic * to pdata * The low-order byte of the generic pointer offset is used.The high-order byte is discarded.转换细节xdata * to generic * The memory type of the generic pointer is set to 0x01 for xdata.The 2-byte offset of the xdata * is used.code * to generic * The memory type of the generic pointer is set to 0xFF for code.The 2-byte offset of the code * is used.idata * to generic * The memory type of the generic pointer is set to 0x00 for idata / data.data * to generic * The 1-byte offset of the idata * / data * is converted to an unsigned int and used as the offset.pdata * to generic * The memory type of the generic pointer is set to 0xFE for pdata.The 1-byte offset of the pdata * is converted to an unsigned int and used as the offset.Abstract Pointers抽象指针抽象指针可以访问位于任何存储区域的固定的存储器。
也可以使用抽象指针调用位于固定位置或结对地址的函数。
固定指针举例:先定义变量:char xdata *px; /* ptr to xdata */char idata *pi; /* ptr to idata */char code *pc; /* ptr to code */char c; /* char variable in data space */int i; /* int variable in data space */以下例子把main C函数的地址赋给一个指向code空间的char类型的指针(存储在数据区)Source: pc=(void *)main;Object: 0000 750000 R MOV pc,#HIGH main0003 750000 R MOV pc+01H,#LOW main以下代码把变量i的地址赋给指向idata区的char类型的指针Source: pi=(char idata *) &i;Object: 0000 750000 R MOV pi,#LOW i以下代码把一个指向xdata区域的char类型的指针赋给一个指向idata区域的char类型的指针。
由于前者占用两个字节而后都占用一个字节,所以在赋值的时候只把低位字节进行了赋值,所以达不到想要的效果Source : pi = (char idata *) px;Object : 0000 850000 R MOV pi,px+01H以下例子把0x1234做为一个指针赋给一个指向code区的char类型的指针:Source:pc = (char code *) 0x1234;Object : 0000 750012 R MOV pc,#012H0003 750034 R MOV pc+01H,#034H以下例子把0xff00转换成了一个没有参数且返回值为int类型的函数指针,调用这个函数,并且把返回值赋给变量i。
通过在函数指针后面的参数列表里添加参数,编译器会正确地调用这个函数。
Source:i = ((int (code *)(void)) 0xFF00) ();Object: 0000 12FF00 LCALL 0FF00H0003 8E00 R MOV i,R60005 8F00 R MOV i+01H,R7以下代码把0x8000转换成一个指向code存储区的char类型的指针,并把这个指针指向的内容赋给变量c。
Source: c = *((char code *) 0x8000);Object : 0000 908000 MOV DPTR,#08000H0003 E4 CLR A0004 93 MOVC A,@A+DPTR0005 F500 R MOV c,A以下代码把0xff00转换成一个指向xdata区的确良char类型的指针,并把指针指向的内容加上变量c,再赋给变量cSource : c += *((char xdata *) 0xFF00);Object : 0000 90FF00 MOV DPTR,#0FF00H0003 E0 MOVX A,@DPTR0004 2500 R ADD A,c0006 F500 R MOV c,A以下代码把0xf0转换成一个指向idata区域的char类型的指针,并把指针指向的内容加上变量c再赋给变量cSource : c += *((char idata *) 0xF0);Object : 0000 78F0 MOV R0,#0F0H0002 E6 MOV A,@R00003 2500 R ADD A,c0005 F500 R MOV c,A以下代码把经0xe8转换成一个指向pdata区char类型的指针,并把指针指向的内加到变量上cSource : c += *((char pdata *) 0xE8);Object : 0000 78E8 MOV R0,#0E8H0002 E2 MOVX A,@R00003 2500 R ADD A,c0005 F500 R MOV c,A以下代码把0x2100转换成一个指向code区int类型的指针,并把指针指向的内容赋给变量iSource : i = *((int code *) 0x2100);Object : 0000 902100 MOV DPTR,#02100H0003 E4 CLR A0004 93 MOVC A,@A+DPTR0005 FE MOV R6,A0006 7401 MOV A,#01H0008 93 MOVC A,@A+DPTR0009 8E00 R MOV i,R6000B F500 R MOV i+01H,A以下代码把0x4000转换成一个指针,这个指针指向一个指针,这个被指向的指针位于xdata区域并指向xdata区域的char类型,把这个被指向的指针赋给pxSource : px = *((char xdata * xdata *) 0x4000);Object : 0000 904000 MOV DPTR,#04000H0003 E0 MOVX A,@DPTR0004 FE MOV R6,A0005 A3 INC DPTR0006 E0 MOVX A,@DPTR0007 8E00 R MOV px,R60009 F500 R MOV px+01H,A上面的例子相同,以下代码把0x4000转换成一个指向指针的指针,被指向的指针位于xdata区并指向xdata区char类型。