C 从动态数组存储和调用值时出错:程序输出不符合预期

C 从动态数组存储和调用值时出错:程序输出不符合预期,c,arrays,combinations,C,Arrays,Combinations,我已经编写了一个程序,将二进制数字1-8计算为四位,存储在一个数组中,然后打印生成的字符串。输出应该是:0000000 1001000110100…等等。但是我的程序正在打印:0000000 10000001,我似乎找不到问题,因此任何帮助都将不胜感激 #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> int main() { in

我已经编写了一个程序,将二进制数字1-8计算为四位,存储在一个数组中,然后打印生成的字符串。输出应该是:0000000 1001000110100…等等。但是我的程序正在打印:0000000 10000001,我似乎找不到问题,因此任何帮助都将不胜感激

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

int main()
{
      int no,i=0,j,val,small[3],l;
      int *d;
      d = malloc(sizeof(int)*500);
      l=0;
      if (d != NULL) {
      printf("1\n");
      } else {
      printf("0\n");
      }

      for(j=0;j<4;j++) //sets initial 0000 combination
      {
        d[j]=0;
      }

      for(no=1;no<8;no++)  //loop for numbers 1-8
      {
        val=no;
        while(val>0)         //decimal to binary conversion
        {

           small[i]=val%2;
           i++;
           val=val/2;
           l++;
        }
        i=0;
          printf("%d\n",l);
        if(l<4)                     //creating 4 bit binary number
        {
            if(l=1)
            {
                small[3]=small[0];
            }
            else
            {
                for(j=(l-1);j>=0;j--)
                {
                    small[(j+(4-l))]=small[j];
                }
            }
            for(j=0;j<(4-l);j++)
            {
                small[j]=0;
            }
        }
        l=0;
        for(j=0;j<4;j++)            //storing binary number in dynamic array
        {
            d[(4*no)+j]=small[j];
            small[j]=0;
        }
      }

      for(j=0;j<(4*(no-1))+4;j++) //printing array
      {
            printf("%d",d[j]);
      }

 }
该行:

if (l = 1)
应该是:

if (l == 1)
您应该非常谨慎地对待以下代码:

int i = 0;
…

for (no = 1; no < 8; no++) // loop for numbers 1-8
{
    val = no;
    while (val > 0)         // decimal to binary conversion
    {
        small[i] = val % 2;
        i++;
        val = val / 2;
        l++;
    }
    i = 0;
变量l也是令人费解的;在第一次迭代中,它与i同步,但与i不同,它在显示的循环之后使用

循环:

    for (j = 0; j < 4; j++)
    {
        d[(4 * no) + j] = small[j];
        small[j] = 0;
    }
实际上不需要使用malloc来分配数组d;它只需要是32,但int d[500];这也行。因此,不需要根据分配是否有效打印0或1的代码。如果分配失败,我们也不需要确保不使用未分配的空间。我们可以观察到,两者都没有使用,现在也没有必要了

初始清理 这导致初始部分清理代码,其中“远距离操作”问题未得到解决:

#include <stdio.h>

int main(void)
{
    int no, i = 0, j, val, small[4], l;
    int d[32];
    l = 0;

    for (j = 0; j < 4; j++) // sets initial 0000 combination
    {
        d[j] = 0;
    }

    for (no = 1; no < 8; no++) // loop for numbers 1-8
    {
        val = no;
        while (val > 0)         // decimal to binary conversion
        {
            small[i] = val % 2;
            i++;
            val = val / 2;
            l++;
        }
        i = 0;
        printf("%d\n", l);
        if (l < 4)                     // creating 4 bit binary number
        {
            if (l == 1)
            {
                small[3] = small[0];
            }
            else
            {
                for (j = (l - 1); j >= 0; j--)
                {
                    small[(j + (4 - l))] = small[j];
                }
            }
            for (j = 0; j < (4 - l); j++)
            {
                small[j] = 0;
            }
        }
        l = 0;
        for (j = 0; j < 4; j++)            // storing binary number in dynamic array
        {
            d[(4 * no) + j] = small[j];
            small[j] = 0;
        }
    }

    for (j = 0; j < (4 * (no - 1)) + 4; j++) // printing array
    {
        printf("%d", d[j]);
        if (j % 4 == 3)
            putchar('\n');
    }
}
继续这一进程 让我们来处理一些“远距离行动”问题。我假设您有C99,所以for循环可以在循环控件中声明变量,除非循环后需要值

#include <stdio.h>

int main(void)
{
    int small[4];
    int d[32];

    for (int j = 0; j < 4; j++)
        d[j] = 0;

    for (int no = 1; no < 8; no++)
    {
        int l = 0;
        int i = 0;
        int val = no;
        while (val > 0)
        {
            small[i] = val % 2;
            i++;
            val = val / 2;
            l++;
        }
        printf("%d\n", l);
        if (l < 4)
        {
            if (l == 1)
                small[3] = small[0];
            else
            {
                for (int j = (l - 1); j >= 0; j--)
                    small[(j + (4 - l))] = small[j];
            }
            for (int j = 0; j < (4 - l); j++)
                small[j] = 0;
        }
        for (int j = 0; j < 4; j++)
        {
            d[(4 * no) + j] = small[j];
            small[j] = 0;
        }
    }

    for (int j = 0; j < 4 * 8; j++)
    {
        printf("%d", d[j]);
        if (j % 4 == 3)
            putchar('\n');
    }
}
相同的错误输出。清理工作没有造成任何损害,即使尚不清楚是否有任何好处

将工艺改造成小型 填充小数组的循环将数字按与进入d相反的顺序放入small。它也不总是将4位数字中的每一位都设置为小写。最好每次只设置所有4位数字。然后我们需要按相反的顺序将4位数字从小复制到d。这会删除很多代码;它也开始产生正确的答案:

#include <stdio.h>

int main(void)
{
    int small[4];
    int d[32];

    for (int j = 0; j < 4; j++)
        d[j] = 0;

    for (int no = 1; no < 8; no++)
    {
        int val = no;
        for (int i = 0; i < 4; i++)
        {
            small[i] = val % 2;
            val = val / 2;
        }
        for (int j = 0; j < 4; j++)
            d[(4 * no) + j] = small[3 - j];
    }

    for (int j = 0; j < 4 * 8; j++)
    {
        printf("%d", d[j]);
        if (j % 4 == 3)
            putchar('\n');
    }
}
最终规范收紧 事实上,我们不需要小数组;我们可以直接把数字输入d。也不需要特别对待0:

#include <stdio.h>

int main(void)
{
    int d[32];

    for (int no = 0; no < 8; no++)
    {
        int val = no;
        for (int i = 4; i > 0; --i)
        {
            d[4 * no + i - 1] = val % 2;
            val /= 2;
        }
    }

    for (int j = 0; j < 4 * 8; j++)
    {
        printf("%d", d[j]);
        if (j % 4 == 3)
            putchar('\n');
    }
}

这仍然是一种稍微不寻常的处理数据的方法,但考虑到输出应该按照所需的顺序用d表示二进制数字,因此假设需要进行计算,而不是简单地为数组写出初始值设定项,这是半合理的。

关于最后一个示例,第行:“val/=2;”调用整数除法。当val=1或val=0时,将失败;建议:'val>>=1;'它将始终工作,调用一个简单的代码序列,该序列不调用整数除法函数,因此速度会快得多。请参见最后一个示例,第行:'d[4*no+i-1]=val%2;'调用模块函数。这将起作用,但不是必需的。建议一个简单的例子:“d[4*no+i-1]=val&0x01;”如果上面的'for'循环从3运行到>=0,那么可以从方程中删除'-1'。关于最后一个示例:line:'for int j=0;j<4*8;j++'1可能有编译器优化的常量乘法,但最好保持简单:“for int j=0;j<32;j++“建议通过define生成某些“幻数”,如“32”,而不是在代码上到处散落。最后,没有理由在数组中生成/保留生成的0/1值。只需在生成时打印即可。注意:这需要以正确的顺序生成0/1值。或者使用当前的生成过程,d[4]”将足够多,并且在生成4后立即输出数字。然后重用D[]数组,该数组将从计算的偏移量中删除“*4”项,并将其放入D[]@user3629249:val/=2是从何时开始的;val为1或0时失败?在这两种情况下,答案都是0,但这很好,是预期的和期望的。是的,您可以使用val>>=1;将正数除以2。你可能会发现编译器为你做了这些;这是不必要的微观优化。是的,除了val%2之外,还有其他获取最后一位的方法;同样,编译器可能会为您完成这项工作,这是一项微观优化。对您可以以不同的方式编写循环。
#include <stdio.h>

int main(void)
{
    int small[4];
    int d[32];

    for (int j = 0; j < 4; j++)
        d[j] = 0;

    for (int no = 1; no < 8; no++)
    {
        int l = 0;
        int i = 0;
        int val = no;
        while (val > 0)
        {
            small[i] = val % 2;
            i++;
            val = val / 2;
            l++;
        }
        printf("%d\n", l);
        if (l < 4)
        {
            if (l == 1)
                small[3] = small[0];
            else
            {
                for (int j = (l - 1); j >= 0; j--)
                    small[(j + (4 - l))] = small[j];
            }
            for (int j = 0; j < (4 - l); j++)
                small[j] = 0;
        }
        for (int j = 0; j < 4; j++)
        {
            d[(4 * no) + j] = small[j];
            small[j] = 0;
        }
    }

    for (int j = 0; j < 4 * 8; j++)
    {
        printf("%d", d[j]);
        if (j % 4 == 3)
            putchar('\n');
    }
}
1
2
2
3
3
3
3
0000
0001
0001
0011
0001
0101
0011
0111
#include <stdio.h>

int main(void)
{
    int small[4];
    int d[32];

    for (int j = 0; j < 4; j++)
        d[j] = 0;

    for (int no = 1; no < 8; no++)
    {
        int val = no;
        for (int i = 0; i < 4; i++)
        {
            small[i] = val % 2;
            val = val / 2;
        }
        for (int j = 0; j < 4; j++)
            d[(4 * no) + j] = small[3 - j];
    }

    for (int j = 0; j < 4 * 8; j++)
    {
        printf("%d", d[j]);
        if (j % 4 == 3)
            putchar('\n');
    }
}
0000
0001
0010
0011
0100
0101
0110
0111
#include <stdio.h>

int main(void)
{
    int d[32];

    for (int no = 0; no < 8; no++)
    {
        int val = no;
        for (int i = 4; i > 0; --i)
        {
            d[4 * no + i - 1] = val % 2;
            val /= 2;
        }
    }

    for (int j = 0; j < 4 * 8; j++)
    {
        printf("%d", d[j]);
        if (j % 4 == 3)
            putchar('\n');
    }
}
0000
0001
0010
0011
0100
0101
0110
0111