Возможно проблема с зависимостью от плагина. Удалите этот плагин cordova-plugin-firebase, затем используйте эту команду для CLI:
плагин ionic cordova rm cordova-plugin-firebase cordova clean ionic cordova подготовьте android ionic cordova run android Я надеюсь решить вашу проблему.
blockquote>https://forum.ionicframework.com/t/test-ionic-app-to-actual-device-or-emulator/153300/2
Говорят, что массивы «распадаются» на указатели. Массив C ++, объявленный как int numbers [5]
, не может быть перенаправлен, то есть вы не можете сказать numbers = 0x5a5aff23
. Что еще более важно, термин «распад» означает потерю типа и размера; числа
распадаются на int *
, теряя информацию о размерности (счет 5), и тип больше не int [5]
. Найдите здесь случаев, когда распада не происходит .
Если вы передаете массив по значению, то на самом деле вы копируете указатель - указатель на первый элемент массива копируется в параметр (тип которого также должен быть указателем на тип элемента массива). Это работает из-за разрушающейся природы массива; однажды распался, sizeof
больше не дает полный размер массива, потому что по сути становится указателем. Вот почему (среди прочего) предпочтительнее передавать по ссылке или указателю.
Три способа передать массив 1 :
void by_value(const T* array) // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])
Последние два дадут правильный размер
] информация, в то время как первая не будет, поскольку аргумент массива распался, чтобы быть назначенным параметру.
1 Константа U должна быть известна во время компиляции.
Я мог бы быть настолько полужирным, чтобы думать, что существует четыре (4) способа передать массив как аргумент функции. Также вот короткий, но рабочий код для Вашего прочтения.
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
using namespace std;
// test data
// notice native array init with no copy aka "="
// not possible in C
const char* specimen[]{ __TIME__, __DATE__, __TIMESTAMP__ };
// ONE
// simple, dangerous and useless
template<typename T>
void as_pointer(const T* array) {
// a pointer
assert(array != nullptr);
} ;
// TWO
// for above const T array[] means the same
// but and also , minimum array size indication might be given too
// this also does not stop the array decay into T *
// thus size information is lost
template<typename T>
void by_value_no_size(const T array[0xFF]) {
// decayed to a pointer
assert( array != nullptr );
}
// THREE
// size information is preserved
// but pointer is asked for
template<typename T, size_t N>
void pointer_to_array(const T (*array)[N])
{
// dealing with native pointer
assert( array != nullptr );
}
// FOUR
// no C equivalent
// array by reference
// size is preserved
template<typename T, size_t N>
void reference_to_array(const T (&array)[N])
{
// array is not a pointer here
// it is (almost) a container
// most of the std:: lib algorithms
// do work on array reference, for example
// range for requires std::begin() and std::end()
// on the type passed as range to iterate over
for (auto && elem : array )
{
cout << endl << elem ;
}
}
int main()
{
// ONE
as_pointer(specimen);
// TWO
by_value_no_size(specimen);
// THREE
pointer_to_array(&specimen);
// FOUR
reference_to_array( specimen ) ;
}
я мог бы также думать, что это показывает превосходство C++ по сравнению с C. По крайней мере, в ссылке (предназначенная игра слов) передачи массива ссылкой.
, Конечно, существуют чрезвычайно строгие проекты без выделения "кучи", никаких исключений и никакого станд.:: lib. Собственная обработка массива C++ является функцией языка в жестком реальном времени, можно было бы сказать.
Массивы в основном такие же, как указатели в C / C ++, но не совсем. После преобразования массива:
const int a[] = { 2, 3, 5, 7, 11 };
в указатель (который работает без приведения типов и поэтому в некоторых случаях может происходить неожиданно):
const int* p = a;
вы теряете способность оператора sizeof
подсчитывать элементы в array:
assert( sizeof(p) != sizeof(a) ); // sizes are not equal
Эта утраченная способность называется «распадом».
Для получения дополнительных сведений ознакомьтесь с этой статьей о распаде массива .
Это когда массив гниет и на него указывают; -)
На самом деле, это просто, если вы хотите передать куда-то массив, но вместо этого передается указатель (потому что кто, черт возьми, передаст за вас весь массив), люди говорят, что плохой массив распался на указатель.
Распад массива означает, что когда массив передается в качестве параметра функции, он обрабатывается так же, как («распадается на») указатель.
void do_something(int *array) {
// We don't know how big array is here, because it's decayed to a pointer.
printf("%i\n", sizeof(array)); // always prints 4 on a 32-bit machine
}
int main (int argc, char **argv) {
int a[10];
int b[20];
int *c;
printf("%zu\n", sizeof(a)); //prints 40 on a 32-bit machine
printf("%zu\n", sizeof(b)); //prints 80 on a 32-bit machine
printf("%zu\n", sizeof(c)); //prints 4 on a 32-bit machine
do_something(a);
do_something(b);
do_something(c);
}
Есть два осложнения или исключения для
Во-первых, при работе с многомерными массивами в C и C ++ теряется только первое измерение. Это связано с тем, что массивы расположены в памяти непрерывно, поэтому компилятор должен знать все измерения, кроме первого, чтобы иметь возможность вычислять смещения в этом блоке памяти.
void do_something(int array[][10])
{
// We don't know how big the first dimension is.
}
int main(int argc, char *argv[]) {
int a[5][10];
int b[20][10];
do_something(a);
do_something(b);
return 0;
}
Во-вторых, в C ++ вы можете использовать шаблоны для определения размера массивы. Microsoft использует это для версий C ++ функций Secure CRT, таких как strcpy_s , и вы можете использовать аналогичный прием, чтобы надежно получить количество элементов в массиве .
Массивы в C не имеют значения.
Везде, где ожидается значение объекта, но объект является массивом вместо этого используется адрес ее первого элемента с указателем типа на (тип элементов массива)
.
В функции все параметры передаются по значению (массивы не исключение). Когда вы передаете массив в функцию, он «превращается в указатель» (sic); когда вы сравниваете массив с чем-то другим, он снова «превращается в указатель» (sic); ...
void foo(int arr[]);
Функция foo ожидает значение массива. Но в C массивы не имеют значения! Таким образом, foo
получает вместо этого адрес первого элемента массива.
int arr[5];
int *ip = &(arr[1]);
if (arr == ip) { /* something; */ }
В приведенном выше сравнении arr
не имеет значения, поэтому он становится указателем. Он становится указателем на int.
Вот что говорит стандарт (C99 6.3.2.1/3 - Другие операнды - Lvalue, массивы и указатели функций):
За исключением случаев, когда это операнд оператора sizeof или унарный оператор &, или строковый литерал, используемый для инициализации массива, выражение, имеющее тип "массив типа", является преобразовано в выражение с типом "указатель на тип", которое указывает на начальный элемент объект массива и не является lvalue.
Это означает, что почти каждый раз, когда имя массива используется в выражении, оно автоматически преобразуется в указатель на 1-й элемент в массиве.
Обратите внимание, что имена функций действуют аналогичным образом, но указатели на функции используются гораздо реже и гораздо более специализированным образом, что не вызывает такой большой путаницы, как автоматическое преобразование имен массивов в указатели.
Стандарт C ++ (4.2 Array-to -поинтер-преобразование) ослабляет требования к преобразованию в (выделено мной):
lvalue или rvalue типа «массив NT» или «массив неизвестной границы T» может быть преобразован в rvalue of type “pointer to T.”
So the conversion doesn't have to happen like it pretty much always does in C (this lets functions overload or templates match on the array type).
This is also why in C you should avoid using array parameters in function prototypes/definitions (in my opinion - I'm not sure if there's any general agreement). They cause confusion and are a fiction anyway - use pointer parameters and the confusion might not go away entirely, but at least the parameter declaration isn't lying.
«Распад» относится к неявному преобразованию выражения из типа массива в тип указателя. В большинстве случаев, когда компилятор видит выражение массива, он преобразует тип выражения из «N-элементного массива T» в «указатель на T» и устанавливает значение выражения равным адресу первого элемента массива. . Исключениями из этого правила являются случаи, когда массив является операндом операторов sizeof
или &
, либо массив является строковым литералом, используемым в качестве инициализатора в объявлении.
Предположим, что следующий код:
char a[80];
strcpy(a, "This is a test");
Выражение a
имеет тип «80-элементный массив символов», а выражение «Это тест» имеет тип «16-элементный массив символов. "(в C; в C ++ строковые литералы - это массивы const char). Однако в вызове strcpy ()
ни одно выражение не является операндом sizeof
или &
, поэтому их типы неявно преобразуются в «указатель на char» , и их значения устанавливаются на адрес первого элемента в каждом. strcpy ()
получает не массивы, а указатели, как видно из его прототипа:
char *strcpy(char *dest, const char *src);
Это не то же самое, что указатель на массив. Например:
char a[80];
char *ptr_to_first_element = a;
char (*ptr_to_array)[80] = &a;
Оба ptr_to_first_element
и ptr_to_array
имеют одинаковое значение ; базовый адрес a. Однако они бывают разных типов и обрабатываются по-разному, как показано ниже:
a[i] == ptr_to_first_element[i] == (*ptr_to_array)[i] != *ptr_to_array[i] != ptr_to_array[i]
Помните, что выражение a [i]
интерпретируется как * (a + i)
(которое работает только в том случае, если тип массива преобразован в тип указателя), поэтому оба a [i]
и ptr_to_first_element [i]
работают одинаково. Выражение (* ptr_to_array) [i]
интерпретируется как * (* a + i)
. Выражения * ptr_to_array [i]
и ptr_to_array [i]
могут приводить к предупреждениям или ошибкам компилятора в зависимости от контекста; они определенно поступят неправильно, если вы ожидаете, что они оценят как a [i]
.
sizeof a == sizeof *ptr_to_array == 80
Опять же, когда массив является операндом sizeof
, это не преобразован в тип указателя.
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
- простой указатель на char.
a [i]
и ptr_to_first_element [i]
работают одинаково. Выражение (* ptr_to_array) [i]
интерпретируется как * (* a + i)
. Выражения * ptr_to_array [i]
и ptr_to_array [i]
могут приводить к предупреждениям или ошибкам компилятора в зависимости от контекста; они определенно поступят неправильно, если вы ожидаете, что они оценят как a [i]
.
sizeof a == sizeof *ptr_to_array == 80
Опять же, когда массив является операндом sizeof
, это не преобразован в тип указателя.
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
- простой указатель на char.
a [i]
и ptr_to_first_element [i]
работают одинаково. Выражение (* ptr_to_array) [i]
интерпретируется как * (* a + i)
. Выражения * ptr_to_array [i]
и ptr_to_array [i]
могут приводить к предупреждениям или ошибкам компилятора в зависимости от контекста; они определенно поступят неправильно, если вы ожидаете, что они оценят как a [i]
.
sizeof a == sizeof *ptr_to_array == 80
Опять же, когда массив является операндом sizeof
, это не преобразован в тип указателя.
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
- простой указатель на char.
* ptr_to_array [i]
и ptr_to_array [i]
могут приводить к предупреждениям или ошибкам компилятора в зависимости от контекста; они определенно поступят неправильно, если вы ожидаете, что они оценят как a [i]
.
sizeof a == sizeof *ptr_to_array == 80
Опять же, когда массив является операндом sizeof
, это не преобразован в тип указателя.
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
- простой указатель на char.
* ptr_to_array [i]
и ptr_to_array [i]
могут приводить к предупреждениям или ошибкам компилятора в зависимости от контекста; они определенно поступят неправильно, если вы ожидаете, что они оценят как a [i]
.
sizeof a == sizeof *ptr_to_array == 80
Опять же, когда массив является операндом sizeof
, это не преобразован в тип указателя.
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
- простой указатель на char.