2

我正在尝试从字符串中的字符创建哔声。这是代码:

/*
 * Buzzer connected to Arduino uno digital pin 13
 * Switch connected to digital pin 2
 */ 

#include <avr/io.h>
#include <util/delay.h>

const int TBEEP = 1000;
const int TBEEEEP = 3500;
const int TGAP = 500;
const int TGAPLETTER = 2000;
int portb = 0x20;

void beep() {
    PORTB = ~portb; _delay_ms(TGAP);
    PORTB = portb; _delay_ms(TBEEP);
    PORTB = ~portb; _delay_ms(TGAP);
}

void beeeep() {
    PORTB = ~portb; _delay_ms(TGAP);
    PORTB = portb; _delay_ms(TBEEEEP);
    PORTB = ~portb; _delay_ms(TGAP);
}

void gapLetter() {
    PORTB = ~portb; _delay_ms(TGAPLETTER);
}

void morse_S() {
    beep(); beep(); beep();
    gapLetter();
}

void morse_M() {
    beeeep(); beeeep();
    gapLetter();
}

void morse_SMS() {
    morse_S(); morse_M(); morse_S();
}

void morse(char theString[]) {
    for (int i = 0; theString[i] != '\0'; i++)
    {
        if(&theString[i] == "S")
            morse_S();
        else if(&theString[i] == "M")
            morse_M();
    }
}

int main (void)
{
    DDRB = 0xFF;
    DDRD = 0x00;
    PORTD = 0x04;

    while (1) {
        if (PIND & 0x04) {
            PORTB = ~0x20;
        } else {
            //morse_SMS(); // it works
            morse("SMS"); // this one doesnt work like morse_SMS() PLEASE HELP!
        }
    }
    return 0;
}

在函数void morse(char theString[]) {...}中,我想从字符串“SMS”中的每个字符产生哔声。不幸的是,只有最后一个角色可以做到。

我正在使用 Atmel Studio 6。当我构建解决方案 (F7) 时,没有错误,但有我不理解的警告(对不起,我是个菜鸟)

与字符串文字比较会导致未指定的行为 [-Waddress]

如何强制每个角色一个接一个地发出哔哔声?

4

2 回答 2

4

First of all,

const int TBEEP = 1000;
const int TBEEEEP = 3500;

These made my day. :)


Apart from that, you should really get a good beginner C book. You can't compare strings using the == operator, because that compares pointers, not contents. If you want to compare strings, use the strcmp() function from the C standard library.

But: in your case, you don't want to compare strings. You want to compare characters. And that can be done with ==, just dereference the character pointer to obtain the actual character, and compare it with a character literal, not with a string literal:

if (theString[i] == 'S')
    morse_S();
else if (theString[i] == 'M')
    morse_M();

Oh, and probably you want to avoid that enormous chained if...else if...else monster. Assuming UTF-8 or at least ASCII encoding, where the character codes of English letters are in alphabetical order:

void (*morse_funcs[26])();
morse_funcs[0] = morse_A;
morse_funcs[1] = morse_B;
// ...
morse_funcs[25] = morse_Z;

// ...

void morse(const char *s)
{
    while (*s)
        morse_funcs[tolower(*s++) - 'a']();
}

Also, notice how I changed char * into const char *. If you don't modify a string, tell the compiler that you don't intend to modify it, so you can safely pass in string literals as well.

Even better: don't use a table of function pointers, but a table of Morse codes. Like this:

const char *mcodes[26] = {
    ".-",        // 'a'
    "-...",      // 'b'
    // etc...
    "--.."       // 'z'
};

void do_morse(const char *code)
{
    while (*code)
        if (*code++ == '-')
            beeeep();
        else
            beep();
}

void morse(const char *s)
{
    while (*s)
        do_morse(mcodes[tolower(*s++) - 'a']);
}
于 2013-07-28T07:47:58.467 回答
0

尝试这个:

void morse(char theString[]) {
    for (int i = 0; theString[i] != '\0'; i++)
    {
        if(theString[i] == 'S')
            morse_S();
        else if(theString[i] == 'M')
            morse_M();
    }
}
于 2013-07-28T07:54:06.890 回答