Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как передать массив в функцию по значению? 
V
    Опции темы
Dmitriy2k
Дата 30.3.2008, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 6.11.2005

Репутация: нет
Всего: нет



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

FuncArray(int arr[][20]){
...
}

main()
{
    int a[2][20];
    FuncArray(a);
}

мне же нужно чтобы передавалась в функцию копия массива, чтобы можно было в функции
изменять значения элементов, не повреждая исходный массив.
PM MAIL   Вверх
bsa
Дата 30.3.2008, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Код
typedef int Array[2][20];
FuncArray(Array arr)
{
 ....
}
main()
{
    Array a;
    FuncArray(a);
}


Это сообщение отредактировал(а) bsa - 30.3.2008, 11:40
PM   Вверх
Dennnis
Дата 30.3.2008, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 23.3.2008

Репутация: нет
Всего: 4



Код

struct Arr
{
    int arr[2][20];
};

FuncArray(Arr arr){
...
}
main()
{
    Arr a;
    FuncArray(a);
}


или

Код

FuncArray(const std::vector<std::vector<int> >& arr){
...
}

main()
{
    std::vector<std::vector<int> > arr;
    FuncArray(arr);
}


Это сообщение отредактировал(а) Dennnis - 30.3.2008, 11:39
--------------------
Get Rich or Die Tryin'
PM   Вверх
bsa
Дата 30.3.2008, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Dennnis, во втором случае передачи идет по ссылке, по сути, тоже самое, что по указателю.
PM   Вверх
Dennnis
Дата 30.3.2008, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 23.3.2008

Репутация: нет
Всего: 4




Цитата(bsa @  30.3.2008,  11:41 Найти цитируемый пост)
Dennnis, во втором случае передачи идет по ссылке, по сути, тоже самое, что по указателю. 

Ты имеешь ввиду надо так:
Код

FuncArray(std::vector<std::vector<int> > arr/*Теперь копирует*/){
...
}
main()
{
    std::vector<std::vector<int> > arr;
    FuncArray(arr);
}

--------------------
Get Rich or Die Tryin'
PM   Вверх
bsa
Дата 30.3.2008, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Dennnis, да. Теперь уже передача по значению.
PM   Вверх
Dmitriy2k
Дата 30.3.2008, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 6.11.2005

Репутация: нет
Всего: нет



Цитата

std::vector<std::vector<int> > arr;


Мне не очень понятно что означают угловые скобки. Я сколько писал на Си ни разу не встречал :(
[quote]

PM MAIL   Вверх
bsa
Дата 30.3.2008, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Dmitriy2k @ 30.3.2008,  14:50)
Цитата

std::vector<std::vector<int> > arr;


Мне не очень понятно что означают угловые скобки. Я сколько писал на Си ни разу не встречал :(

Это С++. std::vector - это шаблон динамического массива.
В этой строчке, в частности, создание массива массивов int.
PM   Вверх
Rififi
Дата 30.3.2008, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



Цитата
т.е. обычно мы передаем в функцию как бы указатель на первый элемент массива

массив не является указателем на первый элемент а неявно приводится к нему компилятором.
вот пример функцмии, в который передаётся сам массив, без потери информации о типе.

Код

template <size_t N>
void f(int (&a)[N])
{
    std::cout << "в массиве " << sizeof(a) / sizeof(a[0]) << " элементов." << std::endl;
}

int arr[10];
f(arr);

PM MAIL   Вверх
bsa
Дата 31.3.2008, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Rififi, читаем вопрос Dmitriy2k внимательно - речь идет о языке Си
PM   Вверх
Rififi
Дата 31.3.2008, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



bsa, 
а чего тогда ему советуют вектор?

Для Си кроме отсутствия ссылочного типа ничего не меняется
void f(int (*arr)[10])
{
    printf("%d элементов.\n", sizeof(*arr) / sizeof((*arr)[0]));
}

int arr[10];
FuncArray(&arr);

PM MAIL   Вверх
bsa
Дата 31.3.2008, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Rififi, ты ему предлагаешь передать по указателю, а ему нужно по значению
PM   Вверх
Rififi
Дата 31.3.2008, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



чтобы передать "массив по-значению", нужно чтобы он был lvalue и/или имел конструктор копирования.
а массив, как известно, не является lvalue, зато является POD-типом, следовательно, запрашиваемое в исходном вопросе невозможно.
PM MAIL   Вверх
UnrealMan
Дата 31.3.2008, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Rififi @  31.3.2008,  13:40 Найти цитируемый пост)
чтобы передать "массив по-значению", нужно чтобы он был lvalue и/или имел конструктор копирования.
а массив, как известно, не является lvalue

Это ты где такое вычитал?
PM MAIL   Вверх
Graf_h
Дата 31.3.2008, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 482
Регистрация: 18.10.2007
Где: г. Ровно, Украина

Репутация: 2
Всего: 5



Цитата(Dmitriy2k @  30.3.2008,  11:29 Найти цитируемый пост)
Подскажите, можно ли передать копию массива в функцию

Это честно говоря глупо smile ! лудше по сonst ссылке smile 


--------------------
Иногда переменная - это просто переменная
PM MAIL ICQ   Вверх
vinter
Дата 31.3.2008, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(Graf_h @  31.3.2008,  17:39 Найти цитируемый пост)
Это честно говоря глупо  ! лудше по сonst ссылке  

угу, это очень умно, особенно если учесть что
Цитата(Dmitriy2k @  30.3.2008,  12:29 Найти цитируемый пост)
 чтобы можно было в функцииизменять значения элементов, не повреждая исходный массив.


Цитата(Rififi @  31.3.2008,  00:43 Найти цитируемый пост)
массив не является указателем на первый элемент а неявно приводится к нему компилятором.

имя массива есть адрес первого элемента, т.е можно считать указателем.
Цитата(Rififi @  31.3.2008,  14:40 Найти цитируемый пост)
чтобы передать "массив по-значению", нужно чтобы он был lvalue и/или имел конструктор копирования.

чего?  smile 



--------------------
Мой блог
PM MAIL WWW   Вверх
Rififi
Дата 31.3.2008, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



vinter, процитированная фраза - это исключительно моё предположение, потому что я не знаю, что означает "передать массив по-значению".
PM MAIL   Вверх
bsa
Дата 31.3.2008, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Rififi @ 31.3.2008,  18:37)
vinter, процитированная фраза - это исключительно моё предположение, потому что я не знаю, что означает "передать массив по-значению".

Похоже, массив действительно нельзя передать по значению. Тогда придется либо через структуру извращаться, либо вручную создавать копию
PM   Вверх
JackFlamingo
Дата 31.3.2008, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 24.6.2007

Репутация: нет
Всего: нет



На мой взгляд, наиболее элегантное решение в отношении переносимости и понимаемости кода - это передать массив по ссылке с модификатором const, а затем ВРУЧНУЮ создать копию.
PM MAIL ICQ   Вверх
vinter
Дата 31.3.2008, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(JackFlamingo @  31.3.2008,  22:33 Найти цитируемый пост)
На мой взгляд, наиболее элегантное решение в отношении переносимости и понимаемости кода - это передать массив по ссылке с модификатором const

зачем? какой смысл тут от передачи по ссылке?


--------------------
Мой блог
PM MAIL WWW   Вверх
MAKCim
Дата 1.4.2008, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(bsa @  30.3.2008,  11:38 Найти цитируемый пост)

typedef int Array[2][20];
FuncArray(Array arr)
{
 ....
}
main()
{
    Array a;
    FuncArray(a);
}

а теперь посмотри ассемблерный листинг  smile 

как бы мы не старались передать массив по значению, не получится
единственный вариант - инкапсуляция
Код

typedef struct {
    int array[2][2];
} array_t;



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Dmitriy2k
Дата 1.4.2008, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 6.11.2005

Репутация: нет
Всего: нет



Понятно. Спасибо за ответы. Ну чтож единственным вариантом является передача элемента структуры, содержащей массив, в функцию
PM MAIL   Вверх
UnrealMan
Дата 1.4.2008, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(vinter @ 31.3.2008,  18:26)
Цитата(Graf_h @  31.3.2008,  17:39 Найти цитируемый пост)
Это честно говоря глупо  ! лудше по сonst ссылке  

угу, это очень умно, особенно если учесть что
Цитата(Dmitriy2k @  30.3.2008,  12:29 Найти цитируемый пост)
 чтобы можно было в функцииизменять значения элементов, не повреждая исходный массив.

А создать копию массива внутри функции религия не позволяет?

Цитата(vinter @  31.3.2008,  18:26 Найти цитируемый пост)
имя массива есть адрес первого элемента, т.е можно считать указателем.

Имя массива - это не указатель.

Цитата(vinter @  31.3.2008,  22:34 Найти цитируемый пост)
Цитата(JackFlamingo @  31.3.2008,  21:33 Найти цитируемый пост)
На мой взгляд, наиболее элегантное решение в отношении переносимости и понимаемости кода - это передать массив по ссылке с модификатором const, а затем ВРУЧНУЮ создать копию. 

зачем? какой смысл тут от передачи по ссылке?

Затем, что такая передача позволяет контролировать размерность (если она должна быть жёстко задана). Вместо ссылки на массив можно использовать указатель на массив (не путать с указателем на первый элемент).

Цитата(MAKCim @  1.4.2008,  09:22 Найти цитируемый пост)
а теперь посмотри ассемблерный листинг  

А может, лучше всё-таки в стандарт посмотреть?

Цитата(8.3.5 Functions)
After determining the type of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively.

Невозможно сделать параметр функции массивом. Всякий параметр, объявление которого выглядит, как объявление массива, на самом деле будет объявленным как указатель. Для массивов не существует copy-initialization, а именно copy-initialization выполняется при передаче параметра:

Цитата(8.5 Initializers)
The initialization that occurs in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and brace-enclosed initializer lists (8.5.1) is called copy-initialization and is equivalent to the form
T x = a;

При отсутствии у массивов copy-initialization функция, параметром которой был бы массив, попросту никогда бы не могла быть вызвана.

Это сообщение отредактировал(а) UnrealMan - 1.4.2008, 14:38
PM MAIL   Вверх
Rififi
Дата 1.4.2008, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



MAKCim, 
 
Цитата
а теперь посмотри ассемблерный листинг

листинг доказывает только то, что массив и его первый элемент начинаются с одного адреса, "и чё дальше"?

Цитата
как бы мы не старались передать массив по значению, не получится

во-первых, обьясни, что это значит, "массив по значению"?
во-вторых, выше была приведена функция, которая получает массив на вход (да-да, именно сам массив, а ни какой не указатель)

Это сообщение отредактировал(а) Rififi - 1.4.2008, 15:43
PM MAIL   Вверх
vinter
Дата 1.4.2008, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(UnrealMan @  1.4.2008,  15:36 Найти цитируемый пост)
А создать копию массива внутри функции религия не позволяет?

причем тут это? причем тут константные ссылки? читай название топика smile  никто не спрашивал "как лучше передать, чтобы потом скопировать"

Добавлено через 4 минуты и 42 секунды
Цитата(UnrealMan @  1.4.2008,  15:36 Найти цитируемый пост)
Имя массива - это не указатель.

не будем играть терминами, это практически одно тоже, в случае одномерного. И не надо меня сейчас тыкать стандартом, и с пеной на губах доказывать что я не прав. На практике это работает точно так же, а значит это эквивалент ;)


--------------------
Мой блог
PM MAIL WWW   Вверх
UnrealMan
Дата 1.4.2008, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(vinter @  1.4.2008,  19:15 Найти цитируемый пост)
никто не спрашивал "как лучше передать, чтобы потом скопировать"

Ответ на поставленный в топике вопрос - никак. Всё, что тут можно предложить, - это обходное решение.

Цитата(vinter @  1.4.2008,  19:15 Найти цитируемый пост)
не будем играть терминами, это практически одно тоже, в случае одномерного.

ну да, здесь

Код

void f(char (&)[100])
{
    std::cout << "array" << std::endl;
}

void f(void *)
{
    std::cout << "pointer" << std::endl;
}

int main()
{
    char arr[100];
    std::cout << sizeof(arr) << std::endl;
    f(arr);
}

и здесь

Код

void f(char (&)[100])
{
    std::cout << "array" << std::endl;
}

void f(void *)
{
    std::cout << "pointer" << std::endl;
}

int main()
{
    char arr[100];
    char *p = arr;
    std::cout << sizeof(p) << std::endl;
    f(p);
}

вывод будет практически один и тот же smile

Это сообщение отредактировал(а) UnrealMan - 1.4.2008, 20:46
PM MAIL   Вверх
vinter
Дата 1.4.2008, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



UnrealMan, я не говорил что массивы ничем от указателей не отличаются, я сказал что имя массива можно считать указателем(константным). Специфика использования  одинакова, и разница между ними не существенна..


--------------------
Мой блог
PM MAIL WWW   Вверх
MAKCim
Дата 1.4.2008, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(UnrealMan @  1.4.2008,  14:36 Найти цитируемый пост)
А может, лучше всё-таки в стандарт посмотреть?

мне достаточно ассемблерного листинга

Цитата(Rififi @  1.4.2008,  15:40 Найти цитируемый пост)
листинг доказывает только то, что массив и его первый элемент начинаются с одного адреса, "и чё дальше"?

Код

typedef int array[2][2];

void f2(array a) {
}

void f1(array a) {
    f2(a);
}

int main() {
    array a;
    f1(a);
    return 0;
}

Код

f1:
    push   rbp
    mov    rbp, rsp
    sub    rsp, 8
    mov    qword [rbp - 8], rdi
    mov    rdi, qword [rbp - 8]
    call    f2
    leave
    ret

main:
    push  rbp
    mov   rbp, rsp
    sub   rsp, 16
    lea    rdi, qword [rbp - 16]
    call    f1
    mov    eax, 0
    leave
    ret

теперь понятно?
если нет, объясню



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Rififi
Дата 1.4.2008, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



vinter, 
Цитата
имя массива можно считать указателем(константным)


int arr[10];

в этой записи имя 'arr' имеет тип 'массив из 10 элементов типа int'. всё. где тут уазатель, покажите мне его? а нету. никакой указатель, константный или нет ни имеет к данной записи ни малейшего отношения. если внутри, в машинном представлении какой-то конкретный компилятор реализует массивы через указатели, как очевидно пытается доказать MAKCim, то я рад за них обоих. только причём здесь C/C++? меня вообще не волнует, что там сидит в машинном коде, да и раздел этот про C/C++.
мифические "указатели" появляются, как только имя arr будет использовано в выражениях. а именно, компилятор приводит имя arr к типу int*. так почему же arr - не указатель? да потому, что такое приведение типов не срабатывает всегда:
1. оператор sizeof(arr) вернет размер, равный 10*sizeof(int), а не sizeof(int*) как это было бы в случае указателя
2. унарный оператор & для выражения &arr имеет тип int(*)[10] а не int**

а результат унарного оператора нужен например затем, чтобы итерироваться по подмассивам:
int arr[10][10];
int (*p)[10] = &a[0];

(*p)[0] = 10; // работаем с первым подмассивом
++p; переходим на следующий подмассив.
(*p)[0] = 20; // продолжаем инициализацию




Это сообщение отредактировал(а) Rififi - 1.4.2008, 22:58
PM MAIL   Вверх
baldina
Дата 1.4.2008, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата

Подскажите, можно ли передать копию массива в функцию?

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

void f (const int* array, size_t count)
{
  size_t size = count * sizeof(int);
  int *temp = (int*)_alloca (size);
  memcpy (temp, array, size);
  // работаем с temp
}

PM MAIL   Вверх
vinter
Дата 2.4.2008, 06:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Rififi, блин, указатель это переменная содержащая адрес, имя массива является адресом. Связи не улавливаешь?
Цитата(Rififi @  1.4.2008,  23:57 Найти цитируемый пост)
в этой записи имя 'arr' имеет тип 'массив из 10 элементов типа int'. всё. где тут уазатель, покажите мне его?

реализация разная, а вот использование одинаково.


--------------------
Мой блог
PM MAIL WWW   Вверх
Dmitriy2k
Дата 2.4.2008, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 6.11.2005

Репутация: нет
Всего: нет



Цитата(UnrealMan @  1.4.2008,  14:36 Найти цитируемый пост)
Имя массива - это не указатель.


а как тогда объяснишь это?

Код

#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>


int main()
{
   int **ptr=(int**)malloc(100);
   ptr[4][4]=5;
   
   return 0;
}

PM MAIL   Вверх
vinter
Дата 2.4.2008, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Dmitriy2k, тут ты объявляешь двойной указатель, а не массив


--------------------
Мой блог
PM MAIL WWW   Вверх
Dmitriy2k
Дата 2.4.2008, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 6.11.2005

Репутация: нет
Всего: нет



правильней конечно будет так:
Код


#include <stdio.h>
#include <malloc.h>


int main()
{
   int arr[]={4,4,4,4,4,4,4};
   int *ptr=arr;  

   ptr[4]=5;

   printf("ptr[4]=%d\n",ptr[4]);
   
   return 0;
}




Цитата(vinter @  2.4.2008,  12:23 Найти цитируемый пост)
Dmitriy2k, тут ты объявляешь двойной указатель, а не массив 

а какая разница то компилятор все равно имя массива приводит к указателю(адресу первого элемента массива)

смоти ассемблерный код:
Код

8:       int arr[]={4,4,4,4,4,4,4};
0040B4D8   mov         dword ptr [ebp-1Ch],4      //первый элемент массива
0040B4DF   mov         dword ptr [ebp-18h],4
0040B4E6   mov         dword ptr [ebp-14h],4
0040B4ED   mov         dword ptr [ebp-10h],4
0040B4F4   mov         dword ptr [ebp-0Ch],4
0040B4FB   mov         dword ptr [ebp-8],4
0040B502   mov         dword ptr [ebp-4],4
9:       int *ptr=arr;
0040B509   lea         eax,[ebp-1Ch]                         //помещаем адрес массива
0040B50C   mov         dword ptr [ebp-20h],eax
10:
11:      ptr[4]=5;
0040B50F   mov         ecx,dword ptr [ebp-20h]
0040B512   mov         dword ptr [ecx+10h],5

PM MAIL   Вверх
Rififi
Дата 2.4.2008, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



vinter, 
Цитата
реализация разная, а вот использование одинаково.

внимательно перечитай мое предыдущее сообшение, особенно про операторы sizeof и &

Добавлено через 2 минуты и 27 секунд
Цитата(Dmitriy2k @  2.4.2008,  12:18 Найти цитируемый пост)
а как тогда объяснишь это?

а что тут обьяснять? завалить программу можно разными способами, например так:

void f(int**);

int arr[10][10];
f((int**) arr);

или даже так:

int* p = NULL;
p[0] = 1;

PM MAIL   Вверх
vinter
Дата 2.4.2008, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



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


--------------------
Мой блог
PM MAIL WWW   Вверх
MAKCim
Дата 2.4.2008, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Rififi @  1.4.2008,  22:57 Найти цитируемый пост)
если внутри, в машинном представлении какой-то конкретный компилятор реализует массивы через указатели, как очевидно пытается доказать MAKCim

я пытаюсь доказать, что в С/С++ массив нельзя передать в функцию по значению
ассемблерный код тому подтверждение
точка


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0964 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.