首页 > 解决方案 > 如何实现cs50的pset3频率并理解notes.c

问题描述

我对cs50的音乐有几个问题。

1)中有一行for (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)notes.csizeof( string ) 是什么意思?我可以理解 sizeof(NOTES),这里的 NOTES 是一个字符串数组。但是sezeof( string )中的字符串是什么意思呢?我无法得到它。

2)这是我对“频率”的实现:

int frequency(string note)
{
    char N[2];
    int octave;
       //parsing the string into a note...
    strncpy(N, note, (strlen(note) - 1));
    //...and its octave
    octave = note[strlen(note) - 1] - '0';
    //add semitones
    int semitone;
    if (strcmp(N, "C") == 0)
        semitone = 1;
    if (strcmp(N, "C#") == 0 || strcmp(N, "Db") == 0)
        semitone = 2;
    if (strcmp(N, "D") == 0)
        semitone = 3;
    if (strcmp(N, "D#") == 0 || strcmp(N, "Eb") == 0)
        semitone = 4;
    if (strcmp(N, "E") == 0)
        semitone = 5;
    if (strcmp(N, "F") == 0)
        semitone = 6;
    if (strcmp(N, "F#") == 0 || strcmp(N, "Gb") == 0)
        semitone = 7;
    if (strcmp(N, "G") == 0)
        semitone = 8;
    if (strcmp(N, "G#") == 0 || strcmp(N, "Ab") == 0)
        semitone = 9;
    if (strcmp(N, "A") == 0)
        semitone = 10;
    if (strcmp(N, "A#") == 0 || strcmp(N, "Bb") == 0)
        semitone = 11;
    if (strcmp(N, "B") == 0)
        semitone = 12;
    //calculate freq: semitones
    float freq = 440 * (powf(2, (semitone -10) / (float)12));
    //calculate freq: multiply by num of octaves
    return round(freq * (powf(2, octave - 4)));
}

./notes 之后的输出是:

 C4: 262
C#4: 922746880
 D4: 294
helpers.c:55:12: runtime error: value 5.85908e+09 is outside the range of representable values of type 'int'
D#4: -2147483648
 E4: 330
 F4: 349
F#4: -2147483648
 G4: 392
G#4: -2147483648
 A4: 440
A#4: -2147483648
 B4: 494

代码本身有效,但在 notes.c 中无效。

请帮助我了解问题所在。

标签: ccs50

解决方案


string一个错误1​​类型的别名char *(指向 的指针char)。C 没有实际的“字符串”数据类型;字符串表示为字符值序列,后跟一个 0 值终止符。例如,字符串"hello"由序列表示{'h', 'e', 'l', 'l', 'o', 0}。终止 0 很重要 - 没有它,各种库例程就像strcpyandstrlen并且printf不会将序列识别为字符串。

字符串存储在char. 在大多数情况下,“array of”类型的表达式char将被转换(“decay”)为“pointer to char”(char *)类型的表达式。所以,大多数时候,char *当我们处理字符串时,我们是在处理表达式。

然而,这并不意味着 achar * 一个字符串。Achar *可以指向字符串的开头(即以零结尾的字符值序列),也可以指向不是字符串的字符值序列的开头,也可以指向单个不属于更大序列的字符。

抛开那些咆哮...

因为string == char *,是a中2sizeof (string) == sizeof (char *)的字节数。显然是 的数组,因此数组中的字节数也是。除以给我们数组 中元素的数量。char *NOTESchar *sizeof(NOTES)NOTESsizeof(NOTES)sizeof(string)NOTES


  1. cs50.h文件创建了stringtypedef,我想抽象出 C 的,呃,唯一的字符串和数组语义。不幸的是,这在 CS50 学生中造成了很大的困惑。我个人认为创建 CS50 课程的人犯了一个错误。
  2. 从技术上讲,“存储单元”,但存储单元实际上是一个字节。


推荐阅读