c вызов массива по ссылке [дубликат]

Вот некоторые подходы к работе с асинхронными запросами:
  1. Объект обезьяны браузера
  2. Q - A
  3. A + Promises.js
  4. jQuery отложен
  5. API XMLHttpRequest
  6. Использование концепции обратного вызова - как реализация в первом ответе

Пример: jQuery отложенная реализация для работы с несколькими запросами

var App = App || {};

App = {
    getDataFromServer: function(){

      var self = this,
                 deferred = $.Deferred(),
                 requests = [];

      requests.push($.getJSON('request/ajax/url/1'));
      requests.push($.getJSON('request/ajax/url/2'));

      $.when.apply(jQuery, requests).done(function(xhrResponse) {
        return deferred.resolve(xhrResponse.result);
      });
      return deferred;
    },

    init: function(){

        this.getDataFromServer().done(_.bind(function(resp1, resp2) {

           // Do the operations which you wanted to do when you
           // get a response from Ajax, for example, log response.
        }, this));
    }
};
App.init();
56
задан Jonathan Leffler 3 March 2015 в 08:48
поделиться

9 ответов

При передаче массива в качестве параметра этот

void arraytest(int a[])

означает то же самое, что и

void arraytest(int *a)

, поэтому вы равны , изменяя значения в основном.

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

80
ответ дан Bo Persson 1 September 2018 в 07:53
поделиться

Вы передаете значение ячейки памяти первого члена массива.

Поэтому, когда вы начинаете изменять массив внутри функции, вы изменяете исходный массив.

Помните, что a[1] - *(a+1).

4
ответ дан alex 1 September 2018 в 07:53
поделиться

Передача многомерного массива в качестве аргумента функции. Передача одного тусклого массива в качестве аргумента более или менее тривиальна. Давайте рассмотрим более интересный случай прохождения 2-мерного массива. В C вы не можете использовать указатель на конструкцию указателя (int **) вместо 2 dim-массива. Приведем пример:

void assignZeros(int(*arr)[5], const int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 5; j++) {
            *(*(arr + i) + j) = 0;
            // or equivalent assignment
            arr[i][j] = 0;
        }
    }

Здесь я указал функцию, которая принимает в качестве первого аргумента указатель на массив из 5 целых чисел. Я могу передать в качестве аргумента любой 2-мерный массив, который имеет 5 столбцов:

int arr1[1][5]
int arr1[2][5]
...
int arr1[20][5]
...

Вы можете прийти к идее определить более общую функцию, которая может принимать любые 2 dim-массива и изменять сигнатуру функции следующим образом :

void assignZeros(int ** arr, const int rows, const int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            *(*(arr + i) + j) = 0;
        }
    }
}

Этот код будет скомпилирован, но вы получите ошибку времени выполнения при попытке присвоить значения так же, как и в первой функции. Таким образом, в C многомерные массивы не совпадают с указателями на указатели ... указателями. Int (* arr) [5] является указателем на массив из 5 элементов, int (* arr) [6] является указателем на массив из 6 элементов, и они являются указателями на разные типы!

Ну, как определить аргументы функций для более высоких измерений? Просто, мы просто следуем шаблону! Hier ist та же функция, настроенная на выбор массива из трех измерений:

void assignZeros2(int(*arr)[4][5], const int dim1, const int dim2, const int dim3) {
    for (int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            for (int k = 0; k < dim3; k++) {
                *(*(*(arr + i) + j) + k) = 0;
                // or equivalent assignment
                arr[i][j][k] = 0;
            }
        }
    }
}

Как вы ожидали, в качестве аргумента может принимать любые 3-х мерные массивы, которые имеют во втором измерении 4 элемента и в третьем размерность 5 элементов. Любое подобное было бы в порядке:

arr[1][4][5]
arr[2][4][5]
...
arr[10][4][5]
...

Но мы должны указать все размеры размеров до первого.

2
ответ дан Andrushenko Alexander 1 September 2018 в 07:53
поделиться

Массивы в C в большинстве случаев преобразуются в указатель на первый элемент самого массива. И более подробно массивы, переданные в функции, всегда преобразуются в указатели.

Здесь цитата из K & amp; R2nd :

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

Написание:

void arraytest(int a[])

имеет то же значение, что и запись:

void arraytest(int *a)

Поэтому, несмотря на то, что вы не пишете его явно, это как вы передаете указатель, и поэтому вы изменяете значения в основном.

Для более я действительно предлагаю прочитать этот .

Кроме того, вы можете найти другие ответы на SO здесь

3
ответ дан Community 1 September 2018 в 07:53
поделиться

Вы не передаете массив как копию. Это только указатель, указывающий на адрес, где первый элемент находится в памяти.

6
ответ дан fyr 1 September 2018 в 07:53
поделиться

@Bo Persson правильно заявляет в своем замечательном ответе здесь :

====================== ====================================

При передаче массива в качестве параметра этот

void arraytest(int a[])

означает то же, что и

void arraytest(int *a)

================================ ==========================

Однако позвольте мне также добавить, что это:

означает то же самое, f3]

, что означает точно такое же, как

void arraytest(int a[1])

, что означает точно такое же, как

void arraytest(int a[2])

, что означает точно такое же, как

void arraytest(int a[1000])

и т. д.

На самом деле значение «размер» внутри параметра массива здесь, по-видимому, предназначено только для эстетической / самостоятельной документации и может быть любым целым положительным (size_t типом Я думаю) вы хотите!

На практике, однако, вы должны использовать его для указания минимального размера массива, который вы ожидаете от функции, чтобы при написании кода вам легко отслеживать и проверять. Стандарт MISRA-C-2012 ( купит / загрузит 236-страничный PDF-версия стандарта для £ 15,00 здесь ) до тех пор, пока не будет указано:

Правило 17.5. Аргумент функции, соответствующий параметру, объявленному для типа массива, должен иметь соответствующее количество элементов.

...

< blockquote>

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

...

Использование декларатора массива для параметра функции более четко определяет интерфейс функции, чем использование указателя. Минимальное количество элементов, ожидаемых функцией, явно указано, тогда как это невозможно с указателем. [emphasis added]

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

0
ответ дан Gabriel Staples 1 September 2018 в 07:53
поделиться

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

int func(int arr[], ...){
    .
    .
    .
}

int func(int arr[SIZE], ...){
    .
    .
    .
}

int func(int* arr, ...){
    .
    .
    .
}

Итак, вы изменяете исходные значения.

Спасибо !!!

3
ответ дан Monirul Islam Milon 1 September 2018 в 07:53
поделиться

Вы передаете адрес первого элемента массива

6
ответ дан obo 1 September 2018 в 07:53
поделиться

В C, за исключением нескольких особых случаев, ссылка на массив всегда «распадается» на указатель на первый элемент массива. Следовательно, невозможно передать массив «по значению». Массив в вызове функции будет передан функции как указатель, который аналогичен передаче массива по ссылке.

EDIT: Есть три таких особых случая, когда массив не распадается на указатель к его первому элементу:

  1. sizeof a не совпадает с sizeof (&a[0]).
  2. &a не совпадает с &(&a[0]) (и не совсем как &a[0]).
  3. char b[] = "foo" не совпадает с char b[] = &("foo").
6
ответ дан Thom Smith 1 September 2018 в 07:53
поделиться
Другие вопросы по тегам:

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