Привет! Я Ксавье Жувено, и вот первая часть длинной серии о Современный вызов C++ .В этой статье я собираюсь объяснить, как я решил первую проблему на C++ и как я интегрировал решение в проект Android.
Цель этой первой задачи проста. Мы должны вычислить сумму всех натуральных чисел, делящихся либо на 3, либо на 5, с точностью до некоторого предела, заданного пользователем, и мы должны распечатать ее. Решение будет вычислено на C++, а интерфейс для получения пользовательского ввода и отображения результата будет обрабатываться с помощью Android Studio Framework.
Решение на C++
Как вы, возможно, видели в моем предыдущем сообщении в блоге об установке Android Studio с C++ . Мы можем использовать C ++ 17 в Android Studio, так что это то, что я собираюсь использовать. 😉
Когда я начинаю свой путь в разработке Android, я интегрировал свое решение непосредственно в файл native-lib.cpp
создается по умолчанию Android Studio. А вот как выглядит эта функция:
[[nodiscard]] constexpr auto sumOf3and5MultipleUpTo(const unsigned int limit) { size_t sum = 0; for(auto number = limit; number >= 3; --number) { if(number % 3 == 0 || number % 5 == 0) { sum += number; } } return sum; }
Давайте подробнее рассмотрим эту функцию, чтобы убедиться, что мы все понимаем, как она работает и почему это так. Во-первых, давайте посмотрим на прототип и на то, что он дает нам в качестве информации:
[[nodiscard]] constexpr auto sumOf3and5MultipleUpTo(const unsigned int limit)
Эта функция constexpr , поскольку вычисление может быть выполнено во время компиляции, если мы захотим. Возвращаемый тип автоматически вычитается с помощью ключевого слова auto . Это также как атрибут [[nodiscard]] что означает, что результат этой функции должен быть использован программой. И, наконец, у нас есть один входной сигнал, который является положительным натуральным числом, поскольку он имеет тип unsigned int
.
Одним из ограничений, определяемых этой функцией, является то, что ввод никогда не должен заканчиваться 4294967295
который является пределом типа unsigned int
. .Это ограничение можно преодолеть, используя
size_t
После прототипа эта функция объявляет и инициализирует переменную для результата вычисления:
size_t sum = 0;
Это переменная size_t
, чтобы быть уверенным, что мы можем сохранить максимально возможное число, вплоть до 18446744073709551615
.Если мы хотели иметь возможность получать еще большие числа, нам пришлось бы использовать реализацию biginteger.
Затем у нас есть вычисление результата:
for(auto number = limit; number >= 3; --number) { if(number % 3 == 0 || number % 5 == 0) { sum += number; } }
Цикл идет вниз от предела, заданного пользователем, до 3
.Нет необходимости проверять, чтобы 0
, потому что ни 1
ни 2
или делится на 3
или 5
, и даже если 0
делится на них, добавляя 0
к сумме не изменит результат.
С помощью number % 3
мы проверяем , делится ли число на 3
, и с помощью number % 5
мы проверяем , делится ли число на 5
. И если одна из этих проверок верна, мы добавляем номер к текущему компьютеру сумма
.
И, наконец, мы возвращаем результат:
return sum;
Итак, вот мое решение этой проблемы, давайте посмотрим, как интерфейс выполнен в Android Studio.
Пользовательский интерфейс в Android Studio
Поскольку на данный момент это единственная проблема, которую решает это приложение, у нас есть только один экран в вашем приложении, поэтому я указал элементы пользовательского интерфейса непосредственно в файле activity_main.xml
создается по умолчанию Android Studio.
Отказ от ответственности: поскольку я только начинаю свое путешествие в Android Studio и мобильную разработку, то, что я узнаю здесь и в будущем посте, может быть для вас тривиальным. Возможно, даже есть несколько лучших способов, чем мое личное решение, достичь того же самого. Если у вас есть какой-либо из этих способов на примете, пожалуйста, сообщите мне в комментариях, чтобы я мог улучшить себя. Заранее благодарю вас 🙂
Чтобы создать наш пользовательский интерфейс, нам понадобятся два вида элементов: Текстовое представление и EditText .The EditText
позволит пользователю предоставить нам входные данные, а TextView
позволит нам отобразить результат пользователю. Вот как выглядит xml этих элементов:
Давайте копнем немного глубже в этих элементах.
Во-первых, Редактировать текст
.У него есть атрибут android: id
, который указывает идентификатор, который будет полезен, когда нам нужно будет получить входные данные, введенные пользователем в Редактировать текст
.Атрибут android:inputType
имеет значение number
, что заставляет пользователя вводить числа в EditText
.И, наконец, последний атрибут, о котором я хочу с вами поговорить, атрибут android:hint
, который отображает текст для отправки инструкции или сообщения пользователю, когда EditText
пуст
Теперь давайте посмотрим на TextEdit
.Как и EditText
, он имеет атрибут android:id
, который указывает идентификатор, который будет полезен, когда потребуется отобразить результат, найденный алгоритмом cpp. И у нас также есть атрибут android:text
, который представляет собой текст TextView
, отображаемый пользователю. Это атрибут, который мы изменим с помощью результата вычисления, выполненного на C++. На данный момент он отображает только “Результат:”.
Мы не будем рассматривать другие элементы, поскольку они не имеют отношения к цели этого сообщения в блоге, поскольку они в основном определяют размер и положение элементов.
Использование собственного кода C++
Чтобы связать и использовать функцию C++, которую мы создали ранее, нам нужно сделать несколько вещей. Во-первых, нам нужно объявить в файле C++ то, что мы хотим сделать доступным для остальной части программы. Это выглядит как следующий код:
extern "C" JNIEXPORT jstring JNICALL Java_com_example_themoderncppchallenge_MainActivity_Sum3And5Multiples( JNIEnv* env, jobject /* this */, const jint i) { auto sum = sumOf3and5MultipleUpTo(i); return env->NewStringUTF(std::to_string(sum).c_str()); }
Этот пример кода определяет функцию Сумма 3 и 5 кратных
, которая будет использоваться в Java. Эта функция принимает параметр joint
in, который будет вводиться пользователем, передает параметр функции out C++ и получает вычисленный результат, прежде чем возвращать его в виде строки. Вот как в коде Java выглядит прототип этой функции:
public native String Sum3And5Multiples(int i);
Теперь давайте посмотрим, как эта функция используется для отображения результата в TextView
после получения ввода пользователя с помощью |/Edit Text .Поскольку наше приложение пока решает только одну проблему, этот код написан непосредственно в методе
MainActivity::onCreate внутри
MainActivity.java файл. Вот как это выглядит:
EditText et = findViewById(R.id.plain_text_input); et.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { int limit = 0; if(count != 0) { limit = Integer.parseInt(s.toString()); } TextView tv = findViewById(R.id.result); tv.setText("Result: " + Sum3And5Multiples(limit)); } @Override public void afterTextChanged(Editable s) { } });
В этом коде мы получаем EditText
, используя его идентификатор, и прикрепляем прослушиватель к его тексту.
EditText et = findViewById(R.id.plain_text_input); et.addTextChangedListener(new TextWatcher() {
Затем мы указываем, что мы хотим сделать, когда текст внутри EditText
изменение, когда пользователь изменяет входные данные. Мы начинаем с проверки, есть ли какие-либо входные данные для получения, если нет, мы вычисляем сумму для 0
в качестве входных данных.
int limit = 0; if(count != 0) { limit = Integer.parseInt(s.toString()); }
Как только у нас есть ввод пользователя, мы получаем TextView
.И, наконец, мы вызываем метод C++ и выводим его результат.
TextView tv = findViewById(R.id.result); tv.setText("Result: " + Sum3And5Multiples(limit));
И вуаля, мы связали все в программу, которая решает первую проблему Современный вызов C++ .Лично , я добавил некоторые TextView
для предоставления дополнительной информации пользователю. Вот как это выглядит:
Вывод
Эта первая проблема и первая реальная программа в Android Studio стали для меня отличным опытом обучения. Я действительно много узнаю об Android Studio и о том, как работают различные части программы на родном C++.
Я знаю, что мне есть чему поучиться, и я рад этому так же сильно, как мне понравилось изучать то, что я изложил в этой статье 🙂 Пожалуйста, скажите мне, есть ли у вас какие-либо предложения или комментарии по поводу некоторых элементов или по поводу предложенного мной решения.
Спасибо вам всем за то, что прочитали эту статью, И до моей следующей статьи желаю вам отличного дня 😉
Интересные ссылки
Оригинал: “https://dev.to/10xlearner/the-modern-c-challenge-on-mobile-the-first-problem-3no9”