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();
При передаче массива в качестве параметра этот
void arraytest(int a[])
означает то же самое, что и
void arraytest(int *a)
, поэтому вы равны , изменяя значения в основном.
По историческим причинам массивы не являются гражданами первого класса и не могут быть переданы по значению.
Вы передаете значение ячейки памяти первого члена массива.
Поэтому, когда вы начинаете изменять массив внутри функции, вы изменяете исходный массив.
Помните, что a[1]
- *(a+1)
.
Передача многомерного массива в качестве аргумента функции. Передача одного тусклого массива в качестве аргумента более или менее тривиальна. Давайте рассмотрим более интересный случай прохождения 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]
...
Но мы должны указать все размеры размеров до первого.
Массивы в C в большинстве случаев преобразуются в указатель на первый элемент самого массива. И более подробно массивы, переданные в функции, всегда преобразуются в указатели.
Здесь цитата из K & amp; R2nd :
Когда имя массива передается функции, то, что передается, является местоположение начальный элемент. Внутри вызываемой функции этот аргумент является локальной переменной, поэтому параметр имени массива является указателем, то есть переменной, содержащей адрес.
blockquote>Написание:
void arraytest(int a[])
имеет то же значение, что и запись:
void arraytest(int *a)
Поэтому, несмотря на то, что вы не пишете его явно, это как вы передаете указатель, и поэтому вы изменяете значения в основном.
Для более я действительно предлагаю прочитать этот .
Кроме того, вы можете найти другие ответы на SO здесь
Вы не передаете массив как копию. Это только указатель, указывающий на адрес, где первый элемент находится в памяти.
@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>...
< blockquote>Если параметр объявлен как массив с указанным размером, соответствующий аргумент в каждом вызове функции должен указывать на объект, у которого есть как минимум столько же элементов, сколько массив.
blockquote>...
Использование декларатора массива для параметра функции более четко определяет интерфейс функции, чем использование указателя. Минимальное количество элементов, ожидаемых функцией, явно указано, тогда как это невозможно с указателем. [emphasis added]
blockquote>Другими словами, они рекомендуют использовать формат явного размера, даже если стандарт C его технически не применяет - он по крайней мере помогает вам разъяснить как разработчик, так и другим, используя код, какой размер массива ожидает функция.
Если вы хотите передать одномерный массив в качестве аргумента в функции, вам нужно объявить формальный параметр одним из следующих трех способов, и все три метода объявления будут давать похожие результаты, поскольку каждый сообщает компилятору, что целое число указатель будет получен.
int func(int arr[], ...){
.
.
.
}
int func(int arr[SIZE], ...){
.
.
.
}
int func(int* arr, ...){
.
.
.
}
Итак, вы изменяете исходные значения.
Спасибо !!!
В C, за исключением нескольких особых случаев, ссылка на массив всегда «распадается» на указатель на первый элемент массива. Следовательно, невозможно передать массив «по значению». Массив в вызове функции будет передан функции как указатель, который аналогичен передаче массива по ссылке.
EDIT: Есть три таких особых случая, когда массив не распадается на указатель к его первому элементу:
sizeof a
не совпадает с sizeof (&a[0])
. &a
не совпадает с &(&a[0])
(и не совсем как &a[0]
). char b[] = "foo"
не совпадает с char b[] = &("foo")
.