ссылка на адрес массива совпадает с адресом [duplicate]

Вы можете использовать Handler для удаления View, не нарушая основной поток пользовательского интерфейса. Вот пример кода

new Handler(Looper.getMainLooper()).post(new Runnable() {
                                                        @Override
                                                        public void run() {
                                                           //do stuff like remove view etc
                                                            adapter.remove(selecteditem);
                                                        }
                                                    });
157
задан phant0m 7 January 2013 в 16:25
поделиться

7 ответов

Имя массива обычно оценивает адрес первого элемента массива, поэтому array и &array имеют одинаковое значение (но разные типы, поэтому array+1 и &array+1 будут not равно, если массив имеет длину более 1 элемента).

Есть два исключения: если имя массива является операндом sizeof или унарным & (адрес -of), имя относится к самому массиву. Таким образом, sizeof array дает размер в байтах всего массива, а не размер указателя.

Для массива, определенного как T array[size], он будет иметь тип T *. Когда / если вы увеличиваете его, вы переходите к следующему элементу массива.

&array оценивает один адрес, но с учетом того же определения создает указатель типа T(*)[size] - - т. е. это указатель на массив, а не на один элемент. Если вы увеличите этот указатель, он добавит размер всего массива, а не размер одного элемента. Например, с таким кодом:

char array[16];
printf("%p\t%p", (void*)&array, (void*)(&array+1));

Мы можем ожидать, что второй указатель будет 16 больше первого (потому что это массив из 16 символов). Поскольку% p обычно преобразует указатели в шестнадцатеричном виде, он может выглядеть примерно так:

0x12341000    0x12341010
172
ответ дан Keith Thompson 24 August 2018 в 00:35
поделиться

В C, когда вы использовали имя массива в выражении (включая передачу его функции), если он не является операндом оператора адреса (&) или оператора sizeof, он распаковывает на указатель на его первый элемент.

То есть, в большинстве контекстов array эквивалентно &array[0] как для типа, так и для значения.

] В вашем примере my_array имеет тип char[100], который распадается на char*, когда вы передаете его в printf.

&my_array имеет тип char (*)[100] (указатель на массив из 100 char ]). Поскольку это операнд &, это один из случаев, когда my_array не сразу разлагается на указатель на его первый элемент.

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

pointer_to_array имеет тип char * - инициализируется для указания на первый элемент массива, поскольку это то, что my_array распадается на в выражении инициализатора - и &pointer_to_array имеет тип char ** (указатель на указатель на char).

Из них: my_array (после распада на char*), &my_array и pointer_to_array все указывают непосредственно на массив или первый элемент массива и поэтому имеют одинаковое значение адреса.

22
ответ дан CB Bailey 24 August 2018 в 00:35
поделиться

Это потому, что имя массива (my_array) отличается от указателя на массив. Это псевдоним адреса массива, и его адрес определяется как адрес самого массива.

Однако указатель является обычной переменной C в стеке. Таким образом, вы можете взять свой адрес и получить другое значение от адреса, который он хранит внутри.

Я написал об этой теме здесь - пожалуйста, взгляните.

27
ответ дан Eli Bendersky 24 August 2018 в 00:35
поделиться

Фактически &myarray и myarray оба являются базовым адресом.

Если вы хотите увидеть разницу вместо использования

printf("my_array = %p\n", my_array);
printf("my_array = %p\n", &my_array);

, используйте

printf("my_array = %s\n", my_array);
printf("my_array = %p\n", my_array);
1
ответ дан glglgl 24 August 2018 в 00:35
поделиться

Причина, по которой my_array и &my_array приводит к тому же адресу, может быть легко понята, когда вы смотрите на макет памяти массива.

Допустим, у вас есть массив из 10 символов ( вместо этого 100 в вашем коде).

char my_array[10];

Память для my_array выглядит примерно так:

+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
^
|
Address of my_array.

В C / C ++ массив распадается на указатель на первый элемент в выражении, таком как

printf("my_array = %p\n", my_array);

. Если вы посмотрите, где находится первый элемент массива, вы увидите, что его адрес совпадает с адресом массива:

my_array[0]
|
v
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
^
|
Address of my_array[0].
2
ответ дан R Sahu 24 August 2018 в 00:35
поделиться

На языке программирования B, который был непосредственным предшественником C, указатели и целые числа были свободно взаимозаменяемыми. Система будет вести себя так, как если бы вся память была гигантским массивом. Каждое имя переменной имело связанный с ней глобальный или стековый относительный адрес, для каждого имени переменной единственными вещами, которые должен был отслеживать компилятор, была то, была ли она глобальной или локальной переменной и ее адресом относительно первого глобального или локального переменная.

Учитывая глобальное объявление, подобное i; [не нужно было указывать тип, поскольку все было целым числом / указателем], обрабатывался компилятором как: address_of_i = next_global++; memory[address_of_i] = 0; и оператор вроде i++ будет обрабатываться как: memory[address_of_i] = memory[address_of_i]+1;.

Объявление типа arr[10]; будет обрабатываться как address_of_arr = next_global; memory[next_global] = next_global; next_global += 10;. Обратите внимание, что как только эта декларация была обработана, компилятор мог сразу забыть о arr, являющемся массивом . Операция типа arr[i]=6; будет обрабатываться как memory[memory[address_of_a] + memory[address_of_i]] = 6;. Компилятору все равно, будет ли arr представлять массив и i целым числом, или наоборот. В самом деле, было бы все равно, являются ли они как массивами, так и целыми числами; он отлично сгенерировал бы код, как описано, невзирая на то, будет ли полученное поведение, вероятно, полезным.

Одна из целей языка программирования C была в значительной степени совместима с B. В B имя массива [называемого «вектором» в терминологии B] идентифицировало переменную, содержащую указатель, который изначально был назначен, чтобы указать на первый элемент распределения заданного размера, поэтому, если это имя появилось в списке аргументов для функции функция получит указатель на вектор. Несмотря на то, что C добавил «реальные» типы массивов, имя которых было жестко связано с адресом распределения, а не с переменной указателя, которая первоначально указывала бы на распределение, имея массивы, разлагающиеся на код, созданный указателями, который объявлял массив C-типа одинаковым к B-коду, который объявил вектор, а затем никогда не изменял переменную, содержащую ее адрес.

2
ответ дан supercat 24 August 2018 в 00:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: