In pset3 of CS50, we're supposed to make sense of the notes.c file:
// Prints frequencies of and outputs WAV file with all notes in an octave
#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);
}
The part I can't make sense of is : for (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
For sizeof(string)
to work, wouldn't there need to be a variable named string
somewhere in the code? e.g. a string actually called string
?
Not really sure what it's referring to.
For
sizeof(string)
to work, wouldn't there need to be a variable namedstring
somewhere in the code?
Nopes, sizeof
operator can be used on an operand of a "type", like sizeof(int)
. Quoting the spec (emphasis mine)
The
sizeof
operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. [....]
You can see the usage of string
type in your code:
const string NOTES[] = {"C", "C#", "D", "D#", "E", "F",
"F#", "G", "G#", "A", "A#", "B"
};
So, NOTES
is an array of type string
, string
is a type name here.
The expression
for (int i = 0, n = sizeof(NOTES) / sizeof(string); i < n; i++)
is a very poor attempt to count the members in the array, it could have been re-written as
for (int i = 0, n = sizeof(NOTES) / sizeof(NOTES[0]); i < n; i++)
which basically divides the size of the whole array by the size of one element, producing the count of members, for sake of readability.
To add the exact source, Check the header file <cs50.h>
, string
is defined to be a type there.
The exact definition is:
/**
* Our own data type for string variables.
*/
typedef char *string;