C 从动态数组存储和调用值时出错:程序输出不符合预期
我已经编写了一个程序,将二进制数字1-8计算为四位,存储在一个数组中,然后打印生成的字符串。输出应该是:0000000 1001000110100…等等。但是我的程序正在打印:0000000 10000001,我似乎找不到问题,因此任何帮助都将不胜感激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
#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