Keil C指针与存储区详解:避坑指南

4星 · 超过85%的资源 需积分: 4 1 下载量 181 浏览量 更新于2024-09-13 收藏 31KB DOC 举报
"本文主要探讨了Keil C中指针与存储区间的关联及特性,讲解了各种存储类型的含义,并通过实例分析了指针声明时使用不同存储类型关键字的影响。" 在Keil C编程环境中,了解指针与存储区的关系至关重要,因为这直接影响到程序的运行效率和内存管理。首先,我们要知道C51(即用于8051微控制器的C编译器)中有几种不同的存储类型,它们与特定的存储区域相对应: 1. **data** - 可寻址的片内RAM,用于常规变量存储。 2. **bdata** - 可位寻址的片内RAM,适合存储位变量。 3. **idata** - 允许访问全部内部RAM的存储区,与data相似但范围更广。 4. **pdata** - 分页寻址片外RAM,适用于MOVX@R0指令,每个页256字节。 5. **xdata** - 可寻址64KB范围的片外RAM,适用于大规模数据存储。 6. **code** - 程序存储区,存放代码和常量,对应MOVC@DPTR指令。 当我们声明一个变量或指针时,可以指定其存储类型。例如,`uchardata x` 和 `data uchar x` 都是在内RAM中分配一个字节的变量。而对于指针变量,我们可以指定它自身存储的位置以及它所指向的数据存储位置,如 `uchar xdata *datapstr`,这里`*`号后的`data`表示指针变量存储在内RAM,而`xdata`则表示指针所指向的变量位于xdata存储区。 然而,如果不正确地使用存储类型关键字,可能会导致问题。以下两个例子展示了如何正确和错误地使用指针: **第一种情况**: ```c uchar xdata tmp[10]; uchardata *datapstr; datapstr = tmp; ``` 这里的错误在于,虽然`tmp`是在xdata区域,但是由于`*datapstr`被声明为`data`类型,编译器会将其视为内RAM中的指针。因此,当试图通过`datapstr`访问`tmp`时,编译器只会生成访问内RAM的指令,而不是访问64KB的片外RAM,导致无法正确访问`tmp`数组。 **第二种情况**: ```c uchar xdata tmp[10]; uchar xdata *datapstr; datapstr = tmp; ``` 在这种情况下,`datapstr`被声明为`xdata`类型,这意味着它自身存储在内RAM,同时指向的`tmp`也位于xdata区域。因此,编译后的汇编代码将正确处理64KB片外RAM的寻址,使得可以通过`datapstr`访问`tmp`数组。 理解这些存储类型和指针的关系,有助于避免在编程时出现难以察觉的错误,特别是在大型项目中,合理使用存储类型可以有效优化内存使用,提高程序性能。在实际编程过程中,根据数据的大小、访问频率和存储需求,选择合适的存储类型和指针声明方式是非常关键的。