【问题标题】:explain why the location of a variable's declaration disables me from changing its value解释为什么变量声明的位置使我无法更改其值
【发布时间】:2013-04-12 05:46:57
【问题描述】:

我有一个行为不同的变量,具体取决于我在同一函数中声明的位置。我想了解正在发生的事情。

在这个函数中,我在两个地方都包含了变量声明和初始化,它们会产生不同的结果,只是为了说明正在发生的事情。当我运行程序时,我没有在任何地方声明两次,只声明一次。

我指的是变量 temp,我已经评论了场景 1 和场景 2

C 函数

    int main(int argc, char* argv[])
    {
        // ensure proper usage
        if (argc != 4) // we need four arguments
        {
            printf("Usage: copy infile outfile\n");
            return 1;
        }

        // remember filenames
        char* infile = argv[2];
        char* outfile = argv[3];

        // the factor
        int n = argv[1][0] - '0';

        // SCENARIO 1) HERE HERE HERE HERE THIS IS THE VARIABLE I AM DISCUSSING!!!!!!!
->      int temp = n; // WHEN DECLARED HERE AND INITIALIZED AT TIME OF CREATION
                      // gdb displays its value equal to the value of n


        // open input file 
        FILE* inptr = fopen(infile, "r");
        if (inptr == NULL)
        {
            printf("Could not open %s.\n", infile);
            return 2;
        }

        // open output file
        FILE* outptr = fopen(outfile, "w");
        if (outptr == NULL)
        {
            fclose(inptr);
            fprintf(stderr, "Could not create %s.\n", outfile);
            return 3;
        }

        // read infile's BITMAPFILEHEADER
        BITMAPFILEHEADER bf;
        fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

        // read infile's BITMAPINFOHEADER
        BITMAPINFOHEADER bi;
        fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

        // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
        if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
            bi.biBitCount != 24 || bi.biCompression != 0)
        {
            fclose(outptr);
            fclose(inptr);
            fprintf(stderr, "Unsupported file format.\n");
            return 4;
        }

        //gdb break to check the previous values


        // SCENARIO 2) HERE HERE HERE HERE THIS IS THE VARIABLE I AM DISCUSSING!!!!!!!!
->      int temp = n; // WHEN DECLARED HERE AND INITIALIZED THE VARIABLE HERE
                      // gdb displays its value equal to 0 and not n

        // write outfile's BITMAPFILEHEADER
        fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

        // write outfile's BITMAPINFOHEADER
        fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);

        // determine padding for scanlines
        int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

        //gdb break to check the new values

        // 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++)
            {
                // temporary storage
                RGBTRIPLE triple;

                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

            // skip over padding, if any
            fseek(inptr, padding, SEEK_CUR);

            // then add it back (to demonstrate how)
            for (int k = 0; k < padding; k++)
                fputc(0x00, outptr);
        }

        // close infile
        fclose(inptr);

        // close outfile
        fclose(outptr);

        // that's all folks
        return 0;
    }

为什么当代码以任何方式更改 n 或 temp 时,我会得到不同的值?

【问题讨论】:

  • 你声明变量2次吗?
  • @llmo Euro 正如我在我的问题中提到的“当我运行程序时,我没有在任何一个地方声明变量两次,只有一次。现在试图弄清楚为什么我会得到不同的结果。”
  • 好的。你在什么时候检查temp?在这两种情况下都在初始化之后?
  • 你的代码是用-g编译的,没有优化?
  • 也许你的编译器看到,那个 temp 从未被使用过,并且根本没有初始化它(他为什么要这样做)

标签: c variables declaration


【解决方案1】:

因此,如果我理解您的代码,那么您在初始化后永远不会阅读 tempn。在第二种情况下,编译器可能已经发现了这一点(取决于优化级别)并将其删除。

【讨论】:

  • 我在已删除的答案中也这么认为,但为什么程序在场景 1 中表现得很好?!?
  • n 只是在案例 1 中设置。也许那里的优化窗口小到只能前后“看到”一些语句。
  • 如果优化足够激进以使用整个main 函数作为优化窗口,它可以删除temps 以​​及n 作为只写变量。
  • @Idav1s 你能澄清一下这部分吗?我在初始化后从不读取 temp 或 n (你的意思是我从不使用变量?)如果是这样,从你的回答中,我可以假设在 SCENARIO 2 中,如果我在声明后使用变量, temp 的值应该 = n 并且不是0?谢谢
  • 在你初始化 n 之后,它从未被使用过,除了初始化 temp,它随后从未被使用过。我假设这里正在发生一些窗口优化。在这两种情况下,tempn 的存储都不会被优化掉。在第一种情况下,您刚刚计算了n,窗口还看不到main 的末尾。但设置temp 只是一两条指令。在第二种情况下,可能窗口可以看到main的结尾,所以它没有设置temp,因为它没有被使用。
猜你喜欢
  • 2022-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
相关资源
最近更新 更多