CS50 Pset3 音乐 - sizeof(string) 在做什么?
CS50 Pset3 Music - what is sizeof(string) doing?
在 CS50 的 pset3 中,我们应该理解 notes.c 文件:
// 打印频率并输出所有音符都在一个八度音程中的 WAV 文件
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include "helpers.h"
#include "wav.h"
// Notes in an octave
const string NOTES[] = {"C", "C#", "D", "D#", "E", "F",
"F#", "G", "G#", "A", "A#", "B"
};
// Default octave
#define OCTAVE 4
int main(int argc, string argv[])
{
// Override default octave if specified at command line
int octave = OCTAVE;
if (argc == 2)
{
octave = atoi(argv[1]);
if (octave < 0 || octave > 8)
{
fprintf(stderr, "Invalid octave\n");
return 1;
}
}
else if (argc > 2)
{
fprintf(stderr, "Usage: notes [OCTAVE]\n");
return 1;
}
// Open file for writing
song s = song_open("notes.wav");
// Add each semitone
for (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
{
// Append octave to note
char note[4];
sprintf(note, "%s%i", NOTES[i], octave);
// Calculate frequency of note
int f = frequency(note);
// Print note to screen
printf("%3s: %i\n", note, f);
// Write (eighth) note to file
note_write(s, f, 1);
}
// Close file
song_close(s);
}
我无法理解的部分是:
对于 (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
要使 sizeof(string)
正常工作,难道不需要在代码中的某处有一个名为 string
的变量吗?例如一个实际上叫做 string
的字符串?
不太确定它指的是什么。
For sizeof(string)
to work, wouldn't there need to be a variable named string
somewhere in the code?
不,sizeof
运算符可用于 "type" 的操作数,如 sizeof(int)
。引用规范(强调我的)
The sizeof
operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type. [....]
你可以在你的代码中看到string
的用法:
const string NOTES[] = {"C", "C#", "D", "D#", "E", "F",
"F#", "G", "G#", "A", "A#", "B"
};
所以,NOTES
是类型的数组string
,string
这里是类型名
表达式
for (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
是一个非常糟糕的尝试计算数组中的成员,它可以被重写为
for (int i = 0, n = sizeof(NOTES) / sizeof(NOTES[0]); i < n; i++)
这基本上是将整个数组的大小除以一个元素的大小,从而产生成员的数量,以便于阅读。
要添加确切的来源,Check the header file <cs50.h>
,string
被定义为类型。
确切的定义是:
/**
* Our own data type for string variables.
*/
typedef char *string;
sizeof
可用于 variables/expressions 以及类型。这里,string
是一个类型,而 NOTES
是一个变量(数组)的实例。
问题的根源是由 CS-50 typedef char* string;
引起的。总体而言,该代码是混淆的完美示例。将指针隐藏在 typedef 后面被广泛认为是糟糕的做法。
代码实际上是这样说的:
const char* NOTES[] = { ...
...
sizeof(NOTES) / sizeof(NOTES[0])
如果它像上面这样写,那么毫无疑问它的作用是:将数组的大小除以每个成员的大小,得到数组中的项数。
我建议停止使用 CS-50 教程。
在 CS50 的 pset3 中,我们应该理解 notes.c 文件:
// 打印频率并输出所有音符都在一个八度音程中的 WAV 文件
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include "helpers.h"
#include "wav.h"
// Notes in an octave
const string NOTES[] = {"C", "C#", "D", "D#", "E", "F",
"F#", "G", "G#", "A", "A#", "B"
};
// Default octave
#define OCTAVE 4
int main(int argc, string argv[])
{
// Override default octave if specified at command line
int octave = OCTAVE;
if (argc == 2)
{
octave = atoi(argv[1]);
if (octave < 0 || octave > 8)
{
fprintf(stderr, "Invalid octave\n");
return 1;
}
}
else if (argc > 2)
{
fprintf(stderr, "Usage: notes [OCTAVE]\n");
return 1;
}
// Open file for writing
song s = song_open("notes.wav");
// Add each semitone
for (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
{
// Append octave to note
char note[4];
sprintf(note, "%s%i", NOTES[i], octave);
// Calculate frequency of note
int f = frequency(note);
// Print note to screen
printf("%3s: %i\n", note, f);
// Write (eighth) note to file
note_write(s, f, 1);
}
// Close file
song_close(s);
}
我无法理解的部分是: 对于 (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
要使 sizeof(string)
正常工作,难道不需要在代码中的某处有一个名为 string
的变量吗?例如一个实际上叫做 string
的字符串?
不太确定它指的是什么。
For
sizeof(string)
to work, wouldn't there need to be a variable namedstring
somewhere in the code?
不,sizeof
运算符可用于 "type" 的操作数,如 sizeof(int)
。引用规范(强调我的)
The
sizeof
operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. [....]
你可以在你的代码中看到string
的用法:
const string NOTES[] = {"C", "C#", "D", "D#", "E", "F",
"F#", "G", "G#", "A", "A#", "B"
};
所以,NOTES
是类型的数组string
,string
这里是类型名
表达式
for (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
是一个非常糟糕的尝试计算数组中的成员,它可以被重写为
for (int i = 0, n = sizeof(NOTES) / sizeof(NOTES[0]); i < n; i++)
这基本上是将整个数组的大小除以一个元素的大小,从而产生成员的数量,以便于阅读。
要添加确切的来源,Check the header file <cs50.h>
,string
被定义为类型。
确切的定义是:
/**
* Our own data type for string variables.
*/
typedef char *string;
sizeof
可用于 variables/expressions 以及类型。这里,string
是一个类型,而 NOTES
是一个变量(数组)的实例。
问题的根源是由 CS-50 typedef char* string;
引起的。总体而言,该代码是混淆的完美示例。将指针隐藏在 typedef 后面被广泛认为是糟糕的做法。
代码实际上是这样说的:
const char* NOTES[] = { ...
...
sizeof(NOTES) / sizeof(NOTES[0])
如果它像上面这样写,那么毫无疑问它的作用是:将数组的大小除以每个成员的大小,得到数组中的项数。
我建议停止使用 CS-50 教程。