我编写了以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * convertToBinary(int baseTenNumber)
{
int counter = 0;
char *result = NULL;
int remainder = baseTenNumber;
while(remainder)
{
result = (char *) realloc(result, sizeof(char) + 2);
printf("%d\n", baseTenNumber);
result[counter] = baseTenNumber%2;
remainder/=2;
counter++;
}
return result;
}
int main (void)
{
int input = -1;
while(input)
{
printf("Enter an integer: ");
scanf("%d", &input);
char * result = convertToBinary(input);
printf("The binary version of %d is %s\n", input, result);
memset(result, '0', sizeof(result));
free(result);
}
return 0;
}
是的,我知道二进制文件将被反向写入,稍后将进行介绍。 但是为什么该程序不保存我的值?
我正在尝试在循环的每次迭代中分配内存。我对一次性完成所有操作不感兴趣。
任何提示都会很棒,谢谢!
答案 0 :(得分:2)
有几种方法可以使内存完全适合C。
一种方法是准确地预先计算所需的内存量,您可以在此处执行此操作。但这并不总是可能的,它需要编写更多的代码,更多的错误以及更多的运行时。
另一种方法是使用var GerenciaBD GERENCIABD
var PontoExecucao int
GerenciaBD.F_GERENCIABD_ABRIR_CONEXAO_MYSQL()
GerenciaBD.DataBase.ExecContext(context.TODO(),"call PESSOA_TESTE", sql.Named("psaida", sql.Out{Dest:&PontoExecucao}))
println(PontoExecucao)
。重新分配会变得杂乱且昂贵,这是邀请错误的好方法。如果您要处理现有的大量内存,例如增加数组,那么有时这是必需的。
另一种方法是分配足够大的堆栈缓冲区以容纳任何可能的值,然后使用strdup
将其复制到恰好正确的堆内存量。当您需要一次处理所有事物并且不确定大小可能会很棒。例如,从文件读取。
realloc
我们可以为您的问题做同样的事情。
// Allocate a big, reusable buffer
char line[BUFSIZ];
while( fgets(line, sizeof(line), fp) ){
...now you can slice and dice line...
}
堆栈内存便宜并且可以快速分配和丢弃。这比一次又一次地重新分配堆内存快得多。使用#include <stdio.h>
#include <string.h>
// The largest possible string to hold a binary integer
#define BINARY_INT_SIZE ((sizeof(int)*8) + 1)
// A cheap way to convert from integer 0/1 to char 0/1
const char BINARY_TO_CHAR[] = {'0', '1'};
char * convertToBinary(int number) {
// Initialize the stack variable to hold the conversion
char result[BINARY_INT_SIZE] = {0};
for( int counter = 0; number; counter++ ) {
printf("%d %d %d\n", counter, number, number % 2);
result[counter] = BINARY_TO_CHAR[number % 2];
number/=2;
}
// Copy from the stack into exactly enough heap memory
return strdup(result);
}
可确保持久堆内存紧凑。
答案 1 :(得分:2)
仅添加到已经给出的精彩答案中,但是我想澄清一些事情,只是为了安全起见,没有人明确指出。
对于初学者来说,您的值会被保存(尽管数量不正确,不在正确的位置,也没有正确的值,我将在后面解释)。您的printf()
语句根本无法识别存储在所创建数组的每个索引中的值。在格式字符串中,您使用的是%s
格式说明符。如果您实际上正在打印人类可读的ASCII码,则可以。问题是您正在打印文字值0
和1
,它们分别映射到“ NULL”和“ heading of heading”。
其他答案对于如何将数字值映射到 ASCII值提出了很好的建议,但是从理论上讲,如果您想在自己的计算机上打印索引按原样排列数组,您将需要通过以下方式进行打印:
printf("The binary version of %d is ", input);
for(int i = numDigits - 1; i >= 0; --i)
printf("%d", result[i]);
在这种情况下,您要以数字而不是字符的形式打印数组中的每个项目。
接下来我要指出的是您在while循环中的逻辑。您对result[counter]
的分配始终为baseTenNum % 2
,因此根据数字是始终是偶数还是奇数,它将存储全0或全1。然后,最重要的是,realloc()
总是将大小调整为固定大小,而不是随每个新字符一起增长(在另一个答案中指出:-)。
希望这些帮助可以帮助您解决一些麻烦!
答案 2 :(得分:1)
Schwerm的答案是最好的。
如果要在每次迭代中分配内存,则realloc(result, counter + 2)
将随着counter
的增加而再分配一个字节。 +2
为当前字符提供一个字节,为终止符提供一个字节。
要将模运算中的1和0转换为可以打印的字符,请添加'0'
。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * convertToBinary(unsigned int baseTenNumber)
{
int counter = 0;
char *result = NULL;
char *temp = NULL;
int remainder = baseTenNumber;
while(remainder)
{
if ( NULL == ( temp = realloc(result, counter + 2))) {
fprintf ( stderr, "problem realloc\n");
exit ( 0);
}
result = temp;
printf("%d\n", remainder);
result[counter] = remainder%2 + '0';
remainder/=2;
counter++;
}
result[counter] = 0;//terminate
return result;
}
int main (void)
{
unsigned int input = 0;
do
{
printf("Enter an integer: ");
scanf("%u", &input);
if ( input) {
char * result = convertToBinary(input);
printf("The binary version of %d is %s\n", input, result);
free(result);
}
} while(input);
return 0;
}