Может кто-нибудь дать мне несколько советов по использованию массивов для распечатки обильных, совершенных и недостающих чисел в C ++?

Вот часть моего кода:
У меня проблемы с выяснением, как передать массив через perfectTest int. У меня есть варианты, что если n равно -1, то это выдает, что это недостающее число, если n равно 0, то это выдает, что это идеальное число, а если n равно 1, то это выдает, что это обильное число. номер, но мне нужно включить массивы в этом. Мне нужны советы.

//prototype
int perfectTest(int n);//function
int perfectTest(int n)

{   bool perfect;
int answer;
int perfectSum = 0;
perfect = false;

for(int i=1; i<=n/2; i++)
{
if(n % i==0)
perfectSum = i;
}

if(perfectSum == n)
perfect = true;
answer = perfectSum;
}//main function

int main()
{
char option;
int  n, m;
bool InService = true;
char perfectTestingOption;
int  perfectNum;
bool perfect = true;
int factor;while (InService == true)
{
cout << "\t\t\nWelcome! Choose an option below\n" << endl;
cout << "A = Perfect number testing" << endl;
cout << "B = Greatest common divisors and least common multiples" << endl;
cout << "C = Factorization of natural numbers" << endl;
cout << "Q = Quit the program\n" << endl;
cout << "Enter your choice:" << endl;
cin >> option;

if (option == 'A' || 'a')
{
cout << "\t\t\nWhich option would you like?\n" << endl;
cout << "1" << endl;
cout << "2" << endl;
cout << "3" << endl;
cout << "4" << endl;
cin >> perfectTestingOption;

if (perfectTestingOption == '1')
{
cout << "Enter a positive integer to check if it is a perfect number." << endl;
cin >> perfectNum;perfectTest(0);

for( );
if (n == -1)
{
cout << "That number is a deficient number" << endl;
}

else if (n == 0)
{
cout << "That number is a perfect number" << endl;
}

else if (n == 1)
{
cout << "That number is a abundant number" << endl;
}

else
{
cout << "Number is invalid" << endl;
}
}

-1

Решение

Массив — это не что иное, как блок данных, адресуемый смещением от некоторого базового адреса в памяти. Если у вас есть базовый адрес, количество элементов и тип данных элементов, у вас будет достаточно информации для обработки данных как массива.

Вы можете объявить массивы напрямую —

int array[SIZE];

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

Вместо этого вы можете выделить указатели и затем инициализировать их, чтобы они указывали на некоторое пространство кучи —

int * array = new int[SIZE];

Это выделяет некоторую память для блока целых динамично и дает вам адрес первого «слота». Оказывается, этого достаточно, поскольку синтаксис скобок в следующем бите функционирует как оператор смещения.

Чтобы получить доступ к отдельным элементам, после объявления переменной массива:

int foo = array[idx]

где idx это какой-то инт. Например, если idx были бы равны 1 (либо заменяя его литералом 1, либо переменной или выражением, оцениваемым до целого числа 1), мы получили бы целое число в слоте 1 слота справа от первого элемента. Напомним, что первый элемент в массиве в C (++) имеет индекс 0, потому что программисты сумасшедшие и любят индексировать вещи по 0 (и потому, что оператор скобки обозначает смещение с адреса первого элемента).

Как мы передаем массивы в функции? Достаточно передать их адреса памяти, если мы знаем тип данных каждого элемента массива, а также длину массива. Очень важно передать и проверить длину массива! Невыполнение этого может привести к ужасным последствиям, поскольку вы выходите за границы вашего массива и начинаете перезаписывать другие значения в вашей программе. (Более сложные структуры данных и другие языки программирования могут выполнять проверку границ автоматически. Поскольку мы используем пустые массивы, проверка границ наш обязанность.)

Давайте вернемся к исходной проблеме сейчас. Предположим, у нас есть функция int f(int i) это делает что-то классное с тем, что приходит. Мы хотим «массивизировать» эту функцию, чтобы она также брала массивы и возвращала массивы.

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

Мы делаем что-то вроде этого:

int * __f(int * __i, int ilen)
{
int * output = new int[ilen];
for(int offset = 0; offset < ilen; offset++)
{
output[offset] = f(__i[offset]);
}
return output;
}

Эта функция принимает целочисленный массив, содержащий ilen целые, и выводит результат применения f каждому. Обратите внимание, что эта функция выделяет новую память, что вам придется delete[] потом. С некоторой простой модификацией вы можете изменить эту функцию, чтобы модифицировать массив на месте.

Давайте разберем это построчно:

int * __f(int * __i, int ilen)

Функция подписи. Это говорит мне, что я беру адрес в массив ilen и возвращает адрес другого такого массива.

    int * output = new int[ilen];

Выделение новой памяти для нашего выхода. Если вы закончили с блоком памяти foo, вам следует delete[] foo когда вы закончите; в противном случае память остается выделенной и занимает место, пока ваша программа не завершится. Читайте о динамическом распределении памяти, если вы хотите узнать больше.

    for(int offset = 0; offset < ilen; offset++)
{
output[offset] = f(__i[offset]);
}

Для каждого элемента в нашем массиве (индексируется offset счетчик), выполняем f на соответствующем элементе входного массива __iи установите правильный элемент output массив к результату.

    return output;

Наконец, мы возвращаем массив, который мы создали. Технически мы возвращаем int *, но это просто причудливый способ сказать «адрес памяти одного или нескольких целых».

Я использовал синтаксис указателя (*) на протяжении всей этой рецензии. Глубокое понимание указателей требует времени для развития многих людей (включая меня; я не получал указатели в течение нескольких лет!). Вкратце, хотя:

  • Переменная вида int * foo содержит адрес памяти Этот адрес памяти, семантически, предназначен для указания на int, В действительности же адрес — это просто адрес. (Адрес памяти — это число, которое соответствует определенной ячейке в памяти. Вы можете рассматривать ячейки памяти как непрерывные адреса; то есть, с нашей точки зрения, ячейка 100 является «смежной» с ячейкой 101. Когда мы нумеруем память, мы используйте размер ячейки 1 байт. Адрес большей конструкции, такой как 4-байтовый int или массив ints, это адрес первого элемента.)
  • Как только мы объявили foo, затем foo само по себе относится к адрес хранится в. Если мы хотим значение, к которому foo очки, мы говорим *foo, *в этом контексте является разыменовать оператор: он берет адрес памяти и возвращает то, что там живет.
  • Если мы хотим адрес переменной bar, мы говорим &bar, & в этом контексте является адрес- оператор: он принимает переменную и говорит вам, где он живет.
  • Вы можете добавлять и вычитать из указателей: foo + 3 является совершенно действительным адресом памяти. БУДЬТЕ ОСТОРОЖНЫ! Каждая «1», которую вы добавляете и вычитаете, — это не одна ячейка памяти, а число ячеек памяти, равное размеру типа, инкапсулируемого массивом. В нашем случае, так как int 4 байт на большинстве современных платформ, foo + 3 добавляет 3 * 4 = 12 ячеек памяти к адресу fooне 3.
  • Указатели и массивы свободно взаимозаменяемы. Особенно, foo[n] работает для любого значения n, как и следовало ожидать.
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]