首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C变量变量

C变量变量
EN

Stack Overflow用户
提问于 2010-07-24 02:55:08
回答 8查看 2.8K关注 0票数 2

在PHP中,我有类似这样的东西

代码语言:javascript
复制
function doStuff($in, $value)  
{  
   $var = "V_" . $in;  
   $$var = $value;
}

有没有办法用C语言做类似的事情?

基本上,我正在试图弄清楚如何制作一种库,使在AVR上使用IO引脚变得更容易。因此,例如,将有一个函数来设置输出的特定引脚。AVR中的引脚是PORTB的一部分。将其设置为输出并为其赋值需要引用DDRBPORTB常量并设置它们的值。我希望能够调用像SetMode(Pin #, Mode);这样的函数,而不是经历所有这些。我只是想不出该怎么做。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-07-28 12:36:44

你的问题仍然有点不清楚(正如答案中的各种解释所表明的那样)。我假设您希望通过物理引脚编号来引用引脚。如果这不正确,请澄清您的问题,以便我们提供更好的答案。

以下是如果有人拿枪指着我的头,我会怎么做:

免责声明:我没有测试过这一点,也没有特别小心地检查文档。该代码是为Linux上的avr-gcc/avr-libc编写的,尽管它也可以在其他地方运行。

代码语言:javascript
复制
// Map from physical pin number to associated direction register.
volatile uint8_t *ddr_map[] = {
    NULL, // Vcc, GND, or some other non-IO pin.
    &DDRB,
    &DDRB,
    &DDRC,
    // etc...  Values will vary for different target chips.
};

// Map from physical pin number to port mask.
uint8_t mask_map[] = {
    0x00,
    _BV(0),
    _BV(1),
    _BV(0),
    // etc...  Values will vary for different target chips.
}

typedef enum {
    IN,
    OUT
} PinDir;

void setMode(int pin, PinDir dir) {
    if(dir == OUT) {
        *ddr_map[pin] |= mask_map[pin];
    } else {
        *ddr_map[pin] &= ~mask_map[pin];
    }
}

请参阅http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass

这就是为什么它不是一个好主意的原因:

  1. 它不会抽象出任何有意义的行为(它实际上删除了抽象--物理引脚编号比逻辑端口/引脚的级别更低)。此外,对于不同的封装格式,物理管脚编号不一定相同。不能将PORTB的引脚分配给QFP封装上与PDIP封装相同的物理引脚编号。所以这段代码实际上更令人困惑,

  1. ,它增加了开销。你有一个额外的函数调用(它消耗周期和堆栈)和两个(或更多)用于查找的数组(它们消耗AVR上的闪存和RAM,除非你采取特殊措施,在这种情况下,它们消耗额外的周期和闪存或EEPROM),更不用说所有的间接(数组查找,指针解除引用)和额外的比较和分支。在桌面和web开发中,你可以嘲笑我对如此小的成本的担忧,但在AVR上,这种浪费的影响要大得多。(注意:您也许能够说服编译器对其中的一些内容进行优化,但如果您使用的是-Os,这将是困难的。现在你担心的是比before...)
  2. The提供的更低层次的细节,操纵引脚的方法并不复杂,因此不值得以这种方式隐藏。你应该习惯于在十六进制和二进制之间进行转换(这并不难)。即使您不想搞乱十六进制,_BV()宏使引脚操作变得非常容易(或者只使用(1 << x),它更可移植,并且将被更多的programmers).

识别

顺便说一下,PORTBDDRB等不是常量。它们是绑定到特定地址或寄存器的变量。尝试使用类似于CONST_THINGY |= 0x03的内容修改常量会产生编译器错误。

变量

C没有你所描述的特性。它是一种低级语言(有时被描述为“高级汇编”),没有提供很多奇特的功能(按照今天的标准)。这就是为什么它是AVR的首选语言--您想要接近硬件,并且不想有太多额外的开销。

C所拥有的就是指针。根据你的问题和评论,我猜你对它们不是很熟悉,所以这里有一个快速的解释:

  • &操作符返回一个指向变量的指针,其用法如下:pointer = &variable;
  • *实际上有两个用途。
    • 第一个用法是声明一个指针变量(即保存指针的变量,而不是int、char或int *pointer; ):注意,您必须指定它将指向的变量类型。
    • 第二个用法是所谓的取消引用指针。基本上,这意味着通过指针访问变量。如果pointer指向variable*pointer = 42;会将variable设置为等于42,而other_var = *pointer会将other_var设置为variable.

的值

  • 这里也有指针算法,但这超出了这个答案的范围。

所有这一切的要点是,您可以有效地将变量本身视为值,存储它们并传递它们。除了操作它们的值之外,您不能真正以任何有意义的方式修改它们,但您也不需要这样做。

票数 4
EN

Stack Overflow用户

发布于 2010-07-24 02:57:16

简而言之,不,在C中没有变量,你可以做的是制作某种类型的变量的哈希图,以名称作为键,并使用它。

票数 3
EN

Stack Overflow用户

发布于 2010-07-24 06:07:22

预处理器定义或宏是在C中实现所需目标的典型方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3321424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档