Когда указатель должен выстроить полезный?

Я могу объявить:

int (*ap)[N];

Так ap указатель на международный массив размера N. Почему это когда-либо полезно? Если я передаю его для функционирования, какую полезную вещь это может сделать с ним, что это не могло сделать только с нормальным указателем на содержание массива?

C FAQ скажите:

2.12: Как я объявляю указатель на массив?

Обычно, Вы не хотите.

10
задан zaharpopov 10 January 2010 в 19:21
поделиться

8 ответов

Я думаю, что заключение от всего обсуждения никогда . Никто здесь не очень продемонстрировал использование для этой конструкции, где что-то еще не будет работать более понятным способом.

-3
ответ дан 3 December 2019 в 19:33
поделиться

Это бесполезно, на самом деле. Но иногда используются указатели на массивы, например, в Microsoft Windows API - я видел там много такого.

2
ответ дан 3 December 2019 в 19:33
поделиться

Как правило, единственное время, которое вы увидите указатель на массив ( t (* a) [n] ) - это как параметр функции, где A предназначен для Будьте 2D-массива:

void foo(int (*a)[N], size_t count)
{
  size_t i;
  for (i = 0; i < count; i++)
      a[i][j] = ...;
  ...
}

void bar(void)
{
  int arr[M][N];
  foo(arr, M);
}

Обратите внимание, что для объявления параметров функции int in [] [n] эквивалентен int (* a) [n] , но это True True для объявлений параметров функции:

void foo (int a[][N], size_t count) {...}

Указатели на массивы, как правило, не так полезны в качестве указателей на базовый тип, поскольку вам нужно знать размер массива, чтобы правильно объявить указатель на него (указатель на 10-элементный массив INT - это другой тип из указателя на 20-элементный массив INT). Лично я не нашел многое использовать для них в 20-х нечетных годах программирования.

Помните, что в большинстве контекстов выражение массива (например, Arr выше) будет иметь его тип, неявную преобразу от «N-элементного массива T» в «указатель на T» (за исключением случаев, когда массив Выражение является операндом Sizeof или , или , или массив - это строковый буквальный, который используется в качестве инициализатора в декларации). В этом случае тип ARM в вызове foo неявно преобразуется из «массива M-элемента N-элемента int» на «на» указатель на N-элементный массив INT ".

Учитывая Декларацию T A [M] [n] [n] , все следующие выражения будут оценивать в том же месте (адрес первого элемента в массиве), но типы будут разными Как показано ниже:

Expression            Type                Implicitly converted to
----------            ----                -----------------------
         a            T [M][N]            T (*)[N]
      a[0]            T [N]               T *
        &a            T (*)[M][N]        
     &a[0]            T (*)[N]
  &a[0][0]            T *
2
ответ дан 3 December 2019 в 19:33
поделиться

Вместо:

Pile.new("game_id" => id, "contents" => "c_type_#{num}")

try:

piles.create("contents" => "c_type_#{num}")

Он пытается сохранить созданную кучу сразу. Или, если вам действительно нужно, чтобы сохранение не происходило (как в случае с создать ), вы можете сделать:

new_pile = piles.build("contents" => "c_type_#{num}")

Аналогично для класса Pile и его карт.

Что касается _ один: обезьяна , вы можете сделать следующее (из метода игры):

create_monkey("some_attr" => "some_value")
-121--3119892-

Оригинальная бумага Пейджа и Брина (Google) 1998 описал обход 25 миллионов страниц на 4 машинах за 10 дней. Они имели открытые 300 соединений за раз на машину. Я думаю, это все еще довольно хорошо. В своих собственных экспериментах с готовыми машинами под управлением Linux я мог надежно открыть 100-200 одновременных соединений.

Во время обхода контента необходимо выполнить три основных действия: (1) выбрать, что делать дальше, (2) получить эти страницы, (3) сохранить эти страницы. Для (1) вы должны внедрить какой-то приоритет очереди (т.е. сделать ширину первый поиск или OPIC), вы также должны держать трек о том, где вы были. Это можно сделать с помощью фильтра Блума. Фильтры Bloom (посмотрите его в Википедии) также можно использовать для хранения, если страница имела файл robot.txt и если префикс данного URL-адреса исключен.

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

(3) хранение страниц обычно выполняется в файле веб-архива, как и в архиве Интернета. При сжатии, вероятно, можно хранить миллиард страниц в 7 терабайтах, так что с точки зрения хранения будет доступно иметь миллиард страниц. Как оценка того, что может сделать одна машина, предположите, что вы получаете машину дешевки за 200$ с 1 ГБ или поршень и 160 ГБ harddrive. На 20KB странице (используйте запросы Range, чтобы не глотать большие страницы целиком) 10 миллионов страниц занимали бы 200 ГБ, но сжатые - около 70 ГБ.

Если вы храните архив, в котором работает поисковая система (по которому вы уже рассчитали, скажем, ранг страницы и bm25), и активный архив ползания контента, то вы израсходовали 140 ГБ. Это оставляет вам около 20 ГБ для других случайных вещей, которые вам нужно обработать. Если вы отрабатываете память, вам нужно постараться сохранить как можно больше своей приоритетной очереди и цветущих фильтров в ОЗУ, вы также находитесь прямо на краю того, что возможно. При обходе 300 000 страниц в день потребуется немного больше месяца/10 миллионов страниц

-121--2739648-

Существуют ситуации, когда требуется передать расположение памяти между программами. например, API Windows может ожидать, что вы передадите указатель на структуру данных или массив, где при программировании на каком-либо другом языке, скажем, c #. Windows API не волнует, как целевой язык обрабатывает массив, для Windows API это просто поток байтов в памяти, и он заполнит его, отправит обратно вам.во избежание несоответствия между языковыми типами в некоторых случаях мы используем указатель на массив, а не неявное имя массива в качестве указателя. Более того, не гарантируется, что неявное имя массива является длинным указателем, некоторые компиляторы могут оптимизировать его, чтобы оно было относительным значением в сегменте. указатель на массив гарантирует, что он имеет размер машинного регистра и вы можете указать на местоположение в любом месте доступной оперативной памяти.

2
ответ дан 3 December 2019 в 19:33
поделиться

Кажется, что мне кажется довольно бесполезным сделать указатель на массив. В C массив уже является указателем на блок этого типа данных.

int (*ap)[N];
int **ipp;

являются одними же типами данных (указатель на указатель на целое число). Единственное отличие Существует то, что есть пространство для N целых чисел, отведенных для AP.

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

-1
ответ дан 3 December 2019 в 19:33
поделиться

Указатель на массив может быть использован для динамического выделения многомерного массива N, в котором известны размеры N-1. Ниже создается массив Nx3.

int (*ap)[3];
ap = malloc(N * sizeof(*ap));
/* can now access ap[0][0] - ap[N-1][2] */

@Adam E/Cruachan, Это не то же самое, что указатель на указатель. ap - это один указатель на блок памяти, содержащий три последовательных целых числа. ap++ будет перемещать адрес указателя на следующий блок из трех целых чисел. for int **pp;, pp указывает на целое число, каждое из которых может указывать на целое число в любой точке памяти.

         +-----+                +------+    +-----+
 ap ---> | int |   vs.  pp ---> | int* | -> | int |
         | int |                +------+    +-----+
         | int |        pp+1 -> | int* | -\
         +-----+                +------+   \   +-----+
 ap+1 -> | int |                  :  :      -> | int |
         | int |                               +-----+
         | int |
         +-----+
           : :  
13
ответ дан 3 December 2019 в 19:33
поделиться

Если вы увеличиваете указатель, он будет указывать на начало следующей группы N элементов n.

Это не имеет большого значения, и это использование зависит от разработчика.

6
ответ дан 3 December 2019 в 19:33
поделиться

Это, вероятно, окуривет в субъективном / аргументе, но ...

На мой взгляд, указатели на массивы находятся на языке, потому что они упали на язык. Есть указатели на все остальные заявляемые тип данных, поэтому это тоже здесь. Я никогда не видел, чтобы кто-то получил действительно полезную работу из них. Гипотетически они позволяют прототипу, который требует массива, а не указателя на элемент, но ...

0
ответ дан 3 December 2019 в 19:33
поделиться
Другие вопросы по тегам:

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