Переменная int изменяется на 1 после цикла while - PullRequest
0 голосов
/ 05 июля 2019

Я пытался создать программу с десятичной запятой в двоичную.Он должен конвертировать только от 0 до 255, и это так.

У меня есть две переменные, 'n' и 'temp', когда пользователь впервые вводит число, которое я сохраняю, в 'n'.Затем я назначаю 'n' для 'temp' (таким образом, создавая копию, по крайней мере, я так думаю).

тогда я использую только 'temp' в своем коде.Я никогда не использую n, пока не решу напечатать число, введенное пользователем.И тут возникает проблема: если я введу число больше 255, переменная 'n' изменится на 1.

Я попытался запустить свой код через пару онлайн-компиляторов C, и все они вывели переменную 'n«Правильный путь, означающий, что несмотря на то, что двоичный файл не работает, когда числа больше 255 (как и предполагалось), они печатают введенное значение.

Я нашел один онлайн-компилятор, в котором он не печатает переменную 'n', если она больше 255.

https://www.tutorialspoint.com/compile_c_online.php

Если вы запустите мойкод этого компилятора, вы увидите, как переменная 'n' меняется на 1 без использования.

Я знаю, что "двоичная часть" не будет работать, если вы используете число больше 255. Iхочу знать, почему 'n' меняется из ниоткуда.

#include <stdio.h>

int main()
{
    int bin[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    int arrSize = 7;
    int n;
    int temp;

    scanf("%d", &n);

    temp = n;

    while(temp != 0)
    {
        bin[arrSize] = temp % 2;

        temp = temp / 2;
        arrSize = arrSize - 1;
    }

    printf(" Decimal: %d ----> binary: ", n);
    for(int i = 0; i <= 7; i++)
    {
        printf("%d", bin[i]);
    }
    printf("\n");


    return 0;
}

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Вы прошли через "переполнение буфера".Краткое определение для этого:

Переполнение буфера происходит, когда программа или процесс пытается записать больше данных в блок памяти или буфер фиксированной длины, чем выделен буфер для хранения.Поскольку буферы создаются для хранения определенного количества данных, дополнительные данные могут перезаписывать значения данных в адресах памяти, смежных с целевым буфером, если программа не включает проверку достаточных границ, чтобы помечать или отбрасывать данные, когда слишком много отправляется в буфер памяти.

Ошибка в вашем коде остается в этом цикле while:

while(temp != 0){
   //I added this line to make it clear
   printf("inside loop\tarrSize=%d\n",arrSize);
   bin[arrSize] = temp % 2;
   temp = temp / 2;
   arrSize = arrSize - 1;
}

Для входа, равного 300 (ошибка будет возникать для каждого входа> 255), вы получите этовывод:

inside loop arrSize=7
inside loop arrSize=6
inside loop arrSize=5
inside loop arrSize=4
inside loop arrSize=3
inside loop arrSize=2
inside loop arrSize=1
inside loop arrSize=0
inside loop arrSize=-1
inside loop arrSize=0

Проблема в том, что у нас индекс равен -1, Вы спросите, что будет?на самом деле массивы являются указателями на адрес первого элемента таблицы + смещение (индекс * размер типа таблицы), что означает, что для bin [-1] это фактически arrSize, а bin [-2] на самом деле п.Вы можете проверить это, проверив адреса следующим образом:

printf("@ of bin[-1]:\t%p\n",(void*)&bin[-1]);
printf("@ of arrSize:\t%p\n\n",(void*)&arrSize);
printf("@ of bin[-2]:\t%p\n",(void*)&bin[-2]);
printf("@ of n:\t\t\t%p\n",(void*)&n);

, который с моим компилятором дал мне:

@ of bin[-1]:   0x7ffe00e32f9c
@ of arrSize:   0x7ffe00e32f9c

@ of bin[-2]:   0x7ffe00e32f98
@ of n:         0x7ffe00e32f98

Таким образом, вы изменяете, не зная bin [-1] (или bin[-2] в соответствии со значением n), которое на самом деле является arrSize (или n) ..

Как вы можете это исправить?Я советую вам проверять индекс каждый раз, когда вы хотите зациклить массив (условие цикла должно быть в функции arrSize).Или вы можете, если хотите, чтобы этот конкретный пример игнорировал это и сосредоточился на логике: проверьте вход (в вашем случае вход n должен быть: 0 <= n <= 255)

0 голосов
/ 05 июля 2019
void *ieee2b(double value,char size,void *res){
  char
    *p0=res,
    *p=p0;

  vbreplacec(vbsprintf(p,"%*.*s",size,size," "),' ','0',p);
  if((long)value!=value)
    while(1){
      double
        tmp=value*2;

      *p++='0'+(long)tmp;
      if(tmp==1||tmp==0||p-p0>size)
        break;
      value=tmp-(long)tmp;
    }
  else{
    p=p0+size-1;

    while((long)value>1){
      *p--='0'+((long)value%2);
      value=(long)value/2;
    }
    *p--='0'+((long)value);
  }
  return res;
}
...