LINUX.ORG.RU

Ммм. А в С++ нету массивов. есть указатели. можно передать копию std::vecotra, можно создать через new новый, при помощи memcpy скопировать туда данные и это уже передать.

theos ★★★
()
Ответ на: комментарий от Davidov

> Видимо, речь идёт о старой байке, что якобы массив и указатель — одно и то же.

А в чем разница кроме синтаксиса?

SSZB
()
Ответ на: комментарий от SSZB

> А в чем разница кроме синтаксиса?
int a[10];
int *a;

есть разница? Задай себе вопрос, что ты можешь сделать с "a" в первом и во втором случае.

UVV ★★★★★
()

создай копию и передай :-\

hizel ★★★★★
()
Ответ на: комментарий от UVV

Если записать так:

int* a = alloca( sizeof( int ) * 10 );

то разницы вроде нет никакой

lester ★★★★
()
Ответ на: комментарий от SSZB

> А в чем разница кроме синтаксиса?

int *a1;
int a2[10];

sizeof a1; // 4
sizeof a2; // 40

a1 = 0; // ok
a2 = 0; // syntax error

zzf
()

>Как в функцию С++ передать копию масива, а не сам массив?

а как ты передаёшь в функцию массив, расскажи:) А как копию передавать будешь?

golodranez ★★★★
()
Ответ на: комментарий от UVV

>int a[10]; >int *a;

Не, не совсем так

int a[10]; int * const a;

Да, на уровне языка есть такой хак c sizeof(). можно даже считать число элементов sizeof(a)/sizeof(a[0]). а теперь расскажите мне, если массив - полноценный тип данных, как у него обстоят дела с передачей в функцию.

theos ★★★
()

Понятно, спасибо за разъяснение.

SSZB
()
Ответ на: комментарий от SSZB

>> Видимо, речь идёт о старой байке, что якобы массив и указатель — одно и то же.

>А в чем разница кроме синтаксиса?

Для линкера массив и указатель это разные вещи.

Absurd ★★★
()
Ответ на: комментарий от theos

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

можно массив константного размера обернуть в структуру и так передавать:)

dilmah ★★★★★
()
Ответ на: комментарий от theos

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

xydo ★★
()
Ответ на: комментарий от dilmah

>можно массив константного размера обернуть в структуру и так передавать:)

Костыли то всегда найдутся =) - это просто было доказательство в пользу утверждения что массивов в С нету.

theos ★★★
()
Ответ на: комментарий от theos

Да спор-то на самом деле не о том существуют или нет массивы в С, а о том как назвать то что есть :)

true_admin ★★★★★
()
Ответ на: комментарий от theos

>массивов в С нету

Ну бред же. Да, операции копирования нет; но массивы есть, даже многомерные. Более того, как выше показано по ссылке, массив не есть указатель (хотя в некоторых ситуациях поведение похоже).

Davidov ★★★★
()
Ответ на: комментарий от theos

>>можно массив константного размера обернуть в структуру и так передавать:)

>Костыли то всегда найдутся =) - это просто было доказательство в пользу утверждения что массивов в С нету.


Попробуй написать в .h файле

extern const char* str;

а в .c файле:

const char str[] = "some string";

Линкер не будет думать что это одно и тоже написанное по-разному.

Absurd ★★★
()
Ответ на: комментарий от Davidov

>даже многомерные

o_O когда повявились? Есть указатели на указатель ("массивы" "массивов").

>хотя в некоторых ситуациях поведение похоже

Наоборот, это одно и тоже, но поведение иногда разнится.

theos ★★★
()

Более того, если

int* a = alloca( sizeof( int ) * 10 );

и

int a[10];

еще ведут себя похоже, то вот уже

int **a;

и

int a[10][10];

Уже облом.

Waterlaz ★★★★★
()
Ответ на: комментарий от theos

> o_O когда повявились? Есть указатели на указатель ("массивы" "массивов").

-1

> Наоборот, это одно и тоже, но поведение иногда разнится.

+1

dilmah ★★★★★
()
Ответ на: комментарий от theos

>>даже многомерные

>o_O когда повявились? Есть указатели на указатель ("массивы" "массивов").

А вот это уже фигня. int a[2][2] - это совсем не int **a.

const86 ★★★★★
()
Ответ на: комментарий от theos

Насчет копирования: придется его производить достаточно большое кол-во раз(в цикле) поэтому не пойдет. Кроме того, массив двумерный. Поэтому копирование займет много времени. Что-то слышала насчет кастования в константный - может это поможет? Не подскажете, как это? Еще одно: насколько поняла, если кастовать с помощью стандартных операторов типа static_cast, то все равно значения элементов массива меняются.

>Как передаётся в функцию массив:

естессно, через указатель на нулевой элемент)что-то типа того:

void f(char **);

может еще что-то вроде const char** использовать? а внутри функции снимать константность - это возможно? Просто тогда косяки с вызовом выходят - нельзя будет передать в качестве аргумента неконстантый массив. А после выхода из функции в этом случае в основной программе не окажется ИЗМЕНЕННЫЙ массив?? А надо бы, чтоб был такой, как ДО передачи в функцию f.
ЗЫ спасибо всем, кто откликнулся=)

FloyDos
() автор топика
Ответ на: комментарий от theos

>o_O когда повявились?

Всё с вами ясно. Марш читать K&R.

>Наоборот, это одно и тоже, но поведение иногда разнится.

Ох уж это желание пустить реки вспять. Есть устоявшаяся терминология, то что она тебе не нравится мало кого волнует; массивы от этого массивами быть не перестанут.

Davidov ★★★★
()
Ответ на: комментарий от Davidov

гкхм... а на МОЙ ВОПРОС ответ в этом форуме найдется или будем беседовать на тему формальной логики - что такое массив?

FloyDos
() автор топика
Ответ на: комментарий от theos

>o_O когда повявились? Есть указатели на указатель ("массивы" "массивов").

int a[x][y] - это на самом деле одномерный массив и никакой не указатель на указатель. Просто элементы адресуются не так, как в "обычном" одномерном (при компиляции по x и y вычисляется реальное смещение; аналагочно с и N-мерными массивами).

staseg ★★★★★
()
Ответ на: комментарий от FloyDos

> Насчет копирования: придется его производить достаточно большое кол-во раз(в цикле) поэтому не пойдет.

Ну тогда придется функции ничего не передавать. Зачем ей этот массив? Пусть без него работает.

LamerOk ★★★★★
()
Ответ на: комментарий от FloyDos

>гкхм... а на МОЙ ВОПРОС ответ в этом форуме найдется или будем беседовать на тему формальной логики - что такое массив?

Да, делать memcpy перед вызовом функции. Или прямо в ней (если такое поведение нужно всегда). Или пользоваться c++-векторами (std, boost, etc., самописный).

staseg ★★★★★
()
Ответ на: комментарий от staseg

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

FloyDos
() автор топика
Ответ на: комментарий от FloyDos

если вам нужно создавать локальную копию для работы внутри функции для массивов небольшого размера то calloc + memcpy внутри функции. кстати, скажите "много" это сколько? 1E6?

theos ★★★
()
Ответ на: комментарий от staseg

>это на самом деле одномерный массив и никакой не указатель на указатель.

Я говорю не о том, как это в памяти, о синтаксисе языка. И с синтаксической точки зрения это именно указатель на указатель:

a[0] - указатель на первый массив, a[0][1] - указатель на второй элемент в первом массиве.

Вот в паскале - действительно многомерные массивы: a : array [1..10, 1..10] of integer

на строчку a[0] выдаст ошибку. ибо это не массив массиовов. Нужно a[0,1]

theos ★★★
()
Ответ на: комментарий от theos

>И с синтаксической точки зрения это именно указатель на указатель: 

Что значит с синтаксической точки зрения? Забей на синтаксис. То, что синтаксис совпадает еще ничего не значит. a[10][10] - это как-бы массив массивов, а не указатель на указатели-с. 

#include <stdio.h>
int f(int** a){
    return a[1][1];
}

int main(){
    int a[10][10];
    a[1][1] = 100;
    printf("%d", f(a));
}


Вот такой вот код работать не будет.

Waterlaz ★★★★★
()
Ответ на: комментарий от theos

>Я говорю не о том, как это в памяти, о синтаксисе языка. И с синтаксической точки зрения это именно указатель на указатель:

Да плевать на синтаксис как таковой. Важно же понимать, что за ним лежит. Ваше непонимаие привело к фэйлу:

>a[0] - указатель на первый массив

Фиг там. Это адрес всего массива. Если быть дотошным, то адрес первого элемент массива. А вот a[1] - адрес "второго", и "третьего", и ..., и "N" массивов.

>a[0][1] - указатель на второй элемент в первом массиве

А это вообще не указатель, а значение (которое *(a+1*sizeof(sometype))).

staseg ★★★★★
()
Ответ на: комментарий от theos

> если вам нужно создавать локальную копию для работы внутри функции для массивов небольшого размера то calloc + memcpy внутри функции. кстати, скажите "много" это сколько? 1E6?

Только вместо memcpy лучше использовать std::uninitialized_copy, и перед выходом из функции std::destroy.

А еще лучше использовать std::tr1::array или std::vector:
#include <tr1/array>
//#include <vector>

#include <cstdio>

template <typename T, size_t N>
void func(T (&arg)[N]) {
	typedef std::tr1::array<T, N> hack;
	hack copy = reinterpret_cast<hack&>(arg); // в теории может где-то не работать :) но по-идее должно
	// или std::vector<T> copy(arg, arg+N);
	copy[0] = 0xBAD;
}

int main() {
	int array[100];
	for (int i=0; i<100; ++i)
		array[0] = 0xC0073;
	func(array);
	std::printf("0x%x\n", array[0]);
}

nozh
()
Ответ на: комментарий от theos

>o_O когда повявились? Есть указатели на указатель ("массивы" "массивов").

товарищь, вы некомпетентны. Если это одно и тоже попробуйте сделать:

int a[2][2] = {{1, 2}, {3, 4}} int **b = (int**)a;

и обратитесь к елементу b[1][1]. Ну как, видите 4? ;-)

chicane
()
Ответ на: комментарий от chicane

int a[2][2] - это массив массивов

int **a - это указатель на указатель

массив массивов адресовать нужно скорее так: int *(b[2])

chicane
()
Ответ на: комментарий от UVV

> int a[10];
> int *a;
> есть разница? Задай себе вопрос, что ты можешь сделать с "a" в первом и во втором случае.

сделать? (SIC!) сделать с ними я могу ровно одинаково. разницы практически нет.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> сделать? (SIC!) сделать с ними я могу ровно одинаково. разницы практически нет.

Лолшто?

int a[10];
int *b;

b = NULL;
a = NULL;

LamerOk ★★★★★
()
Ответ на: комментарий от staseg

>Очевидно, имелось ввиду, что в роли массива оба примера ведут себя одинаково.

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

chicane
()
Ответ на: комментарий от chicane

>как вы себе представляете указатель в роли массива? он всегда будет оставаться указателем

int * const array=malloc(4*sizeof(int));
array[3]=999;//в роли массива, не?
free(array);

staseg ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.