Помогите разобраться с передачей измененных данных в таблицу,плиз
Разработать функцию,которая формирует символьную строку,которая соответствует троичному коду заданного целого числа (не обращаться к соответствующим библиотечным функциям).В массив занести последовательность введенных с клавиатуры целых натуральных чисел -ввод должен заканчиваться нулем. На основе разработанной функции напечатать таблицу введенных чисел и их троичных кодов.
Много непонятного в коде. Например не ясно зачем все считываемые числа хранятся в массиве, хотя достаточно одной ячейки памяти - прочесть в неё число, сконвертить, вывести на экран, и затем эту ячейку памяти снова можно использовать для считывания следующего числа.
По поводу "передачи измененных данных в таблицу". Зачем туда их передавать, если у тебя и таблица (он же массив) и индекс текущего числа - всё объявлено в глобальной области видимости. Эти данные доступны их всех функций.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Дело в том,что в задании сказано заносить введенные данные в массив.
Я не понимаю,как вывести конвертированные данные в таблицу и вообще правильно ли они конвертируются. Когда я пишу следующее
printf("\t\n\v| %15.li |%10.i",numberToConvert,convertedNumber[digit]);
компилятор игнорирует convertedNubmer, поэтому скорее всего ошибка где-то в конвертитовании данных
Ошибок тут много, на самом деле. Возьмём функицю convertNumber. Она меняет ячейку данных из исходного массива (numberToConvert), что приводит к тому, что печать исходных данных (а она происходит после конвертации), выводит одни остатки от деления на 3, а не изначальные числа. Далее посмотрим куда алгоритм конвертации сохраняет остатки от делений. Сохранение производится в массив convertedNumber, при чём индекс текущего элемента не сбрасывается в ноль при конвертации каждого нового числа. Это быстро приведёт к переполнению и выходу за границы массива convertedNumber (достаточно ввести 64 числа меньше 3, или 32 чисел меньше от 3, но меньше 9, или 16 чисел от 9, но меньше 27 и т.д. - это всё допустимое количество чисел, ведь N=200). Даже если мы исправим функцию convertNumber так, чтобы индекс в начале функции обнулялся, мы лишь уйдём от одной проблемы к другой. У нас не будет переполнения, но у нас будет перетирание сконвертированного числа при каждом новом вызове convertNumber и сохранить ВСЕ сконвертированные данные у нас не выйдет (хотя задание требует именно этого). Дополнительная проблема состоит в том, что есть ошибка в алгоритме конвертации. При вычислении остаков от деления на M мы вычисляем цифры нашего числа в M-ричной системе счисления, но ЗАДОМ НАПЕРЁД. Последний факт не учтён в алгоритме.
Исходя из всего этого я предлагаю исправлять не только алгоритм, но и систему хранения данных. Хранить нам нужно как все исходные числа, так и все сконвертированные числа.
Для начала нужно сообразить сколько нам нужно трёхбитных ячеек, чтобы вместить число типа long int после конвертации. Если ты компилируешь программу на Windows, то long int - это 64 бита. Как узнать сколько нужно трёхразрядных знаков, чтобы вместить такое число?
2 ^ 64 = 3 ^ x
x = 64 * log3 (2) =(округляя до большего целого)= 41
То есть converterNumber достаточно иметь длинной 41 (а не 64, как это сделано у тебя). Теперь сообразим что мы будем хранить в ячейках этого массива? Цифры хранить не очень удобно, так как будут проблемы с выводом. Правильнее хранить сконвертированное число, как строку, тогда мы сможем распечатать это число обычным printf, указав в строке формата %s. Но если мы будем хранить сконвертированное число, как строку, то нам потребуется ещё один дополнительный символ под терминирующий ноль (в кратце, это специальный нулевой символ, который воспринимается всеми C-функциями, как конец строки).
Итого длина convertedNumber должна быть 41 + 1 = 42, а тип должен быть char. Такой массив символов (иными словами строка), должен быть у нас ДЛЯ КАЖДОГО входного числа.
#define N 200
// структура, хранящая информацию об одном числе
struct NumberInfo
{
lont int num; // само число
char conv[42]; // сконвертированное число
}
// массив структур, хранящий информацию о всех исходных и сконвертированных числах
NumberInfo numbers[N];
Далее нужно подправить функцию для чтения данных. Она должна читать не numberToConvert, а numbers.num, а заодно заполнять нулями строку numbers.conv (если не вызывать никаких стандартных функций, то сделать можно с помощью вложенного цикла по j от 0 до 41 и присваивания numbers.conv[j] нуля).
Следующий шаг - исправляем функцию конвертации. В цикле вычисляем остатки от деления и заносим их в numbers.conv, причём вносим не просто остаток, а остаток + '0' (символ ноль) для того, чтобы туда попало не просто число, а символ, соответствующий этому числу. После завершения заполнения numbers.conv, не забываем реверсировать строку (иными словами развернуть). Самый простой способ, это сначала вычислить её длину, а затем в цикле запустить два счётчика (левый и правый) друг на встречу другу - один от начала строки, другой от её конца (длина-1). На каждом шаге менять местами соответствующие счётчикам ячейки строки. Признак выхода из цикла: левый счётчки стал больше или равен, чем правый.
Третий шаг - поправить функцию вывода таблицы на экран. При новом способе хранения данных она станет проще и понятнее. Мы просто в цикле по i должны сделать printf("%ld | %s", numbers.num, numbers.conv).
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Иногда у меня создаётся впечатление, что такие подробные ответы в студенческих тема я пишу исключительно для себя . Уж больно высока вероятность прекращения в теме любой активности после такого подробного, но при этом не содержащего готового решения ответа.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Уж больно высока вероятность прекращения в теме любой активности после такого подробного, но при этом не содержащего готового решения ответа.
Да здесь так постоянно, распишешь все досконально, а ТС и след простыл. Для себя это в первую очередь полезно - мозг стимулирует, мысли в порядок приводит, +146% к пониманию задачи, ну и опыт конечно.
It's a long way to the top if you wanna rock'n'roll
В таком случае беру свои слова обратно и, в честь этого, даже расширяю описание, чтобы сделать всё ещё более понятным. С нетерпением жду результатов!
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Я решила скинуть начало, чтобы убедиться все ли я правильно поняла. Что-то я переживаю) Я не очень поняла: остаток +'0', каким образом нужно использовать это выражение?
#include "stdafx.h"
#include <stdio.h>
#define N 200
// структура, хранящая информацию об одном числе
struct NumberInfo
{
long int num; // само число
char conv[42]; // сконвертированное число
}
// массив структур, хранящий информацию о всех исходных и сконвертированных числах
numbers[N];
int i;
int k;
void convertNumber(void);
void reverse(void);
int main (void)
{
printf("Number to convert? '0'-end" );
for (i=0;i<N;i++)
{
scanf("%li",&numbers[i].num);
if(numbers[i].num =='\0')
break;
else
convertNumber();
reverse();
}
return 0;
}
void convertNumber(void)
{
int base=3;
do
{
numbers[i].conv=numbers[i].num%base;
numbers[i].num=numbers[i].num/base;
}
while(numbers[i].num!=0);
}
void reverse(void)
{
char *p=numbers[i].conv;
gets(numbers[i].conv);
while(*p)
p++;
}
Я вообще не пойму, зачем вам нужна структура NumberInfo?
Поле Conv получается из поля Num путем преобразования (работы функции convertNumber)
Задание изначально не критично ко времени выполнения, поэтому не вижу необходимости существования этой структуры.
It's a long way to the top if you wanna rock'n'roll