Ich habe mit einem Problem in PSET4 (whodunit) konfrontiert. Ich verstehe wirklich nicht, warum im folgenden Fall Fehler auftreten, obwohl compile keine Warnung gibt.Strukturen in C
In diesem Problem sollte ich jedes Pixel der angegebenen .bmp-Datei lesen, jedes rote Pixel durch weißes Pixel ersetzen und neues Bild in eine neue .bmp-Datei schreiben.
Hier sind zwei Versionen meines Codes. In der ersten Auflistung gibt es eine korrekte Version des Codes, und das Programm funktioniert ordnungsgemäß, wie ich es wollte. In der zweiten Liste gibt es ein Beispiel für Code, der erfolgreich kompiliert wurde, aber Pixel entweder immer noch gleich oder passiert etwas seltsam.
richtige Version
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
// iterate over pixels in scanline
for (int j = 0; j < bi.biWidth; j++)
{ //CORRECT VERSION
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
if((triple.rgbtRed == 0xff) && (triple.rgbtGreen == 0x00) && (triple.rgbtBlue == 0x00))
{
triple.rgbtBlue = 0xff;
triple.rgbtGreen = 0xff;
triple.rgbtRed = 0xff;
}
// write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
unkorrekte Version
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
// iterate over pixels in scanline
for (int j = 0; j < bi.biWidth; j++)
{ //INCORRECT VERSION
// temporary storage
RGBTRIPLE triple[i][j];
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
if((triple[i][j].rgbtRed == 0xff) && (triple[i][j].rgbtGreen == 0x00) && (triple[i][j].rgbtBlue == 0x00))
{
triple[i][j].rgbtBlue = 0xff;
triple[i][j].rgbtGreen = 0xff;
triple[i][j].rgbtRed = 0xff;
}
// write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
Nach dem "Arrays" lessons (und zB mit "Studenten" Struktur in CS50), ist es erforderlich, was um die Indizes [i] und [j] für die Array- und Strukturvariablen während der Ausführung von "for" -loop einzuschließen. Aber in diesem Fall wird alles ungültig, wenn ich diese Indizes in den Code lege. Und alles ist in Ordnung, wenn ich diese Indizes nicht schreibe. Warum bricht diese Logik hier mit Strukturen?
Sie ... was haben Sie getan. – Havenard
@Havenard was ist los? –
Wie von dasblinkenlight in seiner Antwort darauf hingewiesen wurde, sollten Sie den Index des Arrays angeben, wenn Sie darauf zugreifen, nicht wenn Sie es deklarieren. Bei der Deklaration sollten Sie die Gesamtgröße angeben, die vom Index 0 bis zur Größe 1 reicht. Und wenn Sie ein Element pro Iteration behandeln, sollten Sie das Array außerhalb der Schleife deklarieren, als ob Sie es innerhalb der Schleife tun würden. Es wird jedes Mal neu deklariert und es können Inkonsistenzen auftreten (auch undefiniertes Verhalten). – Havenard