powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Передача массивов в функции
25 сообщений из 73, страница 2 из 3
Передача массивов в функции
    #38540198
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

SashaMercury,
Солтер Н.А. и Клепер С.Дж. (С++ для профессионалов) написали, как корректно выделить память для двумерного массива:
int x,y;

int** myArray = new int*[x]; //Выделяем для первой размерности массива

for (int i=0; i<x; i++)
myArray[i]=new int[x]; //Выделяем для i-го подмассива.

Это код, мне кажется самый корректный!


это не многомерный массив, это массив указателей на массивы.
это разные вещи. в памяти элементы располагаются совсем по другому.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540227
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
столько бреда понаписали в топике...
вечером буду наводить порядок...

1 отличайте массивы указателей от многомерных массивов.
2 отличайте указатели от массивов, массив выделяет память под все элементы, N*sizeof(elementtype), указатель - только sizeof(void*).

в с++ имеет смысл использовать ссылки на массивы, они могут сохранять размерность, или вектор верторов.
в последнем случае вообще все автоматом делается.

если же ты используешь функцию, надо использовать указатель на первый элемент массива и смещения в массиве вычислять самому.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540645
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

Код: plaintext
1.
2.
3.
4.
5.
int** a = new int*[2]; // это массив массивов
for(int i = 0; i < 2; ++i)
    a[i] = new int[2];

int b[2][2]; // это двухмерный массив 



так вот a и b совсем по разному лежат в памяти, хотя для тебя это оба двухмерных массива. b линейно располагает свои элементы

Код: plaintext
b[0][0] | b[0][1] | b[1][0] | b[1][1]  

тогда как a

Код: plaintext
1.
2.
a[0] -> a[0][0] | a[0][1]
a[1] -> a[1][0] | a[1][1]

по сути a - это набор из разрозненных участком динамической памяти - один под a, и два под a[0], a[1]

SashaMercury

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

например,

Код: plaintext
1.
2.
int a[10];
int* b = a;



нука сдвиньте мне a на второй элемент? нет, не выйдет, поскольку a это не указатель. тогда как с b все достаточно тривиально

Код: plaintext
1.
b += 1;
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540664
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё интересно:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int** a = new int*[2]; // это массив массивов
for(int i = 0; i < 2; ++i)
{
  if( !i )
    a[i] = new int[2];
  else
    a[i] = new int[200];
}

// и матрица стала непонятно каким ежём ...
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540672
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и я бы не называл это "массив массивов", на мой взгляд, массив массивов -- это многомерный массив.

Я бы называл это лучше "массив указателей", можно уточнить (но это не всегда так) "на динамически выделенные массивы".
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540910
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прочитал книги и сделал такой вывод:
В языке С/С++ предусмотрены многомерные массивы. Простейшим из них является двухмерный. По существу, двухмерный массив – это массив одномерных массивов.
В языке С/С++ указатели и массивы тесно связаны друг с другом. Имя массива без индекса – это указатель на его первый элемент.
Код: plaintext
1.
2.
3.
4.
5.
6.
int a[10];
//Следующие два выражения абсолютно идентичны.
a
&a[0]
//Это выражение является истинным (true)
а==&a[0]


Значит, адрес первого элемента массива совпадает с адресом всего массива.
Этого можно применять и к многомерным массивам.
Следующие два оператора будут эквивалентными:
Код: plaintext
1.
2.
a
&a[0][0]


Двухмерный массив можно представить с помощью указателя на массив одномерных массивов.
Опираясь на эти и на Ваши мнения, написал вот такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
int main()
{
    int array_i; //Количество строк
    int array_j; //Количество columns
	
    cout << "Enter array count:" << endl; 
	 
    cout << "i:"; cin >> array_i; //Ввод Количество строк
    cout << "j:" ; cin >> array_j; //Ввод Количество столбцов
    cout << endl;
        
	//Инициализация массива
	int *myArray[array_i]; //Выделяем для первой размерности массива
		
	for (int i=0; i<array_i; i++)
	   myArray[i]=new int[array_j]; //Выделяем для i-го подмассива.
	   
        // Присваивание значение     
	for (int i=0; i<array_i; i++) 
	  for (int j=0; j<array_j; j++) 
		myArray[i][j] = (i+1)*(j+1);       // Присваивание значения для каждого ячейки массива  
		
    //Вывод на экран
   cout << "Array:" << endl;
    for (int i=0; i<array_i; i++)
	{
	  for (int j=0; j<array_j; j++)
	      cout << *(int*) &myArray[i][j] << "    "; //Это операция выполняется быстрее, чем индексация.
	  cout << endl;
	}
   return 0;
   //Конец main
}



Результат:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Enter array count:
i:5
j:5

Array:
1    2    3    4    5
2    4    6    8    10
3    6    9    12   15
4    8    12   16   20
5    10   15   20   25

--------------------------------
Process exited with return value 0
Press any key to continue . . .
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540920
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Далее буду разбираться передачи массивов на функции!
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540943
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,
В целом выглядит ок, но есть замечания.
1)
Код: plaintext
1.
int *myArray[array_i]; //Выделяем для первой размерности массива


А почему не
Код: plaintext
1.
int *myArray = new int*[array_i]


?
Вообще выделение локальных массивов заранее неизвестным размером, это нестандартная фича вашего компилятора. В С++ такого нет. Не гоовря уже о том что выделять массивы в стеке опасно, т.к. размер стека ограничен.

2)
Код: plaintext
1.
cout << *(int*) &myArray[i][j] << "    "; //Это операция выполняется быстрее, чем индексация.


Комментарий - бред.
Не только не быстрее, но еще и код становится нечитаемым - не делайте так никогда

3) Каждому выделению памяти чере new должно соответствовать удаление через оператор delete.
В этой простой программе которая сразу завершается это может и не имеет смысла, а вот в реальных программах будет утечка памяти.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38540980
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
Спасибо! Да Вы совершенно правы!
Anatoly Moskovsky2)
cout << *(int*) &myArray[i][j] << " "; //Это операция выполняется быстрее, чем индексация.

Комментарий - бред.
Не только не быстрее, но еще и код становится нечитаемым - не делайте так никогда

А как можно осуществлять доступ к элементам массива указателя?
Anatoly Moskovsky3) Каждому выделению памяти чере new должно соответствовать удаление через оператор delete.

Я с Вами согласен!
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541031
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovА как можно осуществлять доступ к элементам массива указателя?

Ну вот вы написали
Код: plaintext
1.
cout << *(int*) &myArray[i][j] 


а надо было
Код: plaintext
1.
cout << myArray[i][j] 



А разыменование, *, применяется если у вас уже есть указатель и вы хотите по нему прочесть или записать.
А специально получать адрес через & чтобы потом его тут же разыменовать - не надо.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541047
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovВ языке С/С++ указатели и массивы тесно связаны друг с другом. Имя массива без индекса – это указатель на его первый элемент.


Массивы и указатели никак не связаны друг с другом, кроме двух вещей:

и то, и другое подразумевает использование адресной арифметики.

имя массива неявно приводится компилятором к типу "указатель на первый элемент массива", если это нужно.

Более указатели и массивы никак не связаны вроде бы.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541068
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Код: plaintext
1.
int *myArray[array_i]; //Выделяем для первой размерности массива


А почему не
Код: plaintext
1.
int *myArray = new int*[array_i]


?
Вообще выделение локальных массивов заранее неизвестным размером, это нестандартная фича вашего компилятора. В С++ такого нет. Не гоовря уже о том что выделять массивы в стеке опасно, т.к. размер стека ограничен.



Такое есть в С99, который, очевидно, поддерживается его компилятором (MINGW).
Но если включить strict ansi режим (ключ -ansi, если я правильно помню), то ...
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541073
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
3) Каждому выделению памяти чере new должно соответствовать удаление через оператор delete.
В этой простой программе которая сразу завершается это может и не имеет смысла, а вот в реальных программах будет утечка памяти.

Анатолий, здеть ТОЖЕ ЕСТЬ утечка памяти, только тут на неё можно наплевать. Потому что код неценен.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541179
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТакое есть в С99
В режиме С да.
А в С++ нет.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541281
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

И все же, в реальных задачах, особенно связанных с вычислениями и частыми обращениями к матрице, лучше когда матрица лежит в памяти в непрерывном пространстве, а не рабросана кусками по хипу. Поэтому линейная развертка рулит по сравнению с массивом массивов. Ты наверняка слышал такое понятие как "фрагментация" применительно к дискам. Так вот оно в равной степени относится и куче. Чем больше у тебя фрагментов, тем больше происходит перезагрузок кэша процессора, что сказывается на производительности.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541340
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков,
Я буду имеет ввиду Вашего мнений. Но пока моя цель - постепенно освоит все тонкости языка С++.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541346
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovАнатолий Широков,
Я буду имеет ввиду Вашего мнений. Но пока моя цель - постепенно освоит все тонкости языка С++.
Я буду учитывать Вашего мнения. Но пока моя цель - постепенно освоит все тонкости языка С++
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541378
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий ШироковAlimkulov,

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

Толя, еще и NUMA радости в этом отношении добавляет.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541381
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovAlimkulovАнатолий Широков,
Я буду имеет ввиду Вашего мнений. Но пока моя цель - постепенно освоит все тонкости языка С++.
Я буду учитывать Вашего мнения. Но пока моя цель - постепенно освоит все тонкости языка С++

так в смысле тонкости самому адресацию в многомерном массиве сложнее написать.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541396
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovА как можно осуществлять доступ к элементам массива указателя?
Ты так пишешь "указатель", будто считаешь его чем-то большим, чем порядковым номером
ячейки памяти, почти мистической сущностью...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541401
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivSashaMercury,

Если я не ошибаюсь, то K&R пишут что указатели в частности предназначены для возврата нескольких значений из функции.


ты ошибаешься.


Старница 98. Строчки 1-2.
K&RУказатели в качестве аргументов обычно используются в функциях, которые должны возвращать более одного значения.
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541407
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivВообще, насколько я понял, объявление массива, например:

int a[10]

значит, что вы объявили int* a

че за бред? int* 4 байта, int [10] - 40.
есть разница?



не вырывайте из контекста, пожалуйста. я написал:
SВообще, насколько я понял, объявление массива, например:
int a[10]

значит, что вы объявили int* a(K&R пишут что имя массива является указательным выражением-страница 100), и это указательное выражение, хранит в себе адрес начала массива, и далее мы говорим, что одно значение будет занимать 4 байта(в зависимости от архитектуры), и гарантировано таких значений будет 10(впрочем с этим я не уверен, может он их все будет индексировать и считывать значения с 4 байт).


Про гарантированных 40 байт я написал.

MasterZivSПотому, как мне кажется, массив это такое вымышленное понятие, несколько искусственное, вообще ошибка, если кто-то говорит о них,
это только кажется. а когда кажется, надо креститься, тогда нечисть сгинет...

А разве не вымышленное ? Абстракция, накрученная. В K&R до 102 страницы я не встретил чёткого определения массива, и возможно это неопределяемое понятие в C, как и понятие множества в математике. Не буду приводить ссылки на функан, википедии вам хватит link_for_MasterZiv

и, ВЫ снова вырываете из контекста.Вы разорвали мою фразу я написал,

SПотому, как мне кажется, массив это такое вымышленное понятие, несколько искусственное, вообще ошибка, если кто-то говорит о них, без указателей, нужно начинать объяснение с указателей, и как частный случай их использования рассказывать про массивы



MasterZivS
без указателей, нужно начинать объяснение с указателей, и как частный случай их использования рассказывать про массивы. И вообще, может быть не стоит в качестве принимаемых параметров использовать массивы, если есть указатели.


вот это единственное нормальное замечание в посте. только есть одно но: в параметрах функции массив и указатель это одно и то же.



Одно из трёх утверждений вам понравилось ?Уже неплохо.
не одно и то же. Указатель понятие фундаментальное в фон-неймановской архитектуре, а массив абстракция
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541418
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryMasterZivSashaMercury,

Если я не ошибаюсь, то K&R пишут что указатели в частности предназначены для возврата нескольких значений из функции.


ты ошибаешься.


Старница 98. Строчки 1-2.
K&RУказатели в качестве аргументов обычно используются в функциях, которые должны возвращать более одного значения.

У вас какой K&R. Тут у меня на странице №98 речь идет о функции а не массивах. Может я читаю не тот изданию?
Можете написать конкретно, у вас какое издание и ссылки. У меня 3-е издание (2003г.)
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541424
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

k&_txt

5.2. Указатели и аргументы функций
...
Рейтинг: 0 / 0
Передача массивов в функции
    #38541442
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryMasterZivSashaMercury,

Если я не ошибаюсь, то K&R пишут что указатели в частности предназначены для возврата нескольких значений из функции.


ты ошибаешься.


Старница 98. Строчки 1-2.
K&RУказатели в качестве аргументов обычно используются в функциях, которые должны возвращать более одного значения.


Видимо должен быть какой-то контекст, который бы придал этим словам суть.
Я полагаю, что речь идет как раз о модификации в функции внешнего массива, как бы "возврата из функции массива". "Как бы" -потому что естественно вернуть массив из функции невозможно в С.
...
Рейтинг: 0 / 0
25 сообщений из 73, страница 2 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / Передача массивов в функции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]