Привет! Я Ксавье Жувено, и вот первая часть длинной серии о Современный вызов 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”