Форум программистов, компьютерный форум CyberForum.ru

Функции, передача массива в качестве параметра - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 94, средняя оценка - 4.84
Опа!!
14 / 14 / 0
Регистрация: 30.09.2009
Сообщений: 89
30.09.2009, 16:59     Функции, передача массива в качестве параметра #1
Приветствую)
Собственно, есть простенькое задание с двумерными массивами, оно выполнено:

C++
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
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
 
void main(){
const int str=4,stb=5;
int mas[str][stb];
int i,j;
 
//Построчный ввод элементов массива;
for(i=0;i<str;i++)
 for(j=0;j<stb;j++)
  {cout<<"Vvedite ["<<i+1<<"]"<<"["<<j+1<<"]"<<" element massiva: ";
  cin>>mas[i][j];}
 
//Поиск строки с наиб. количеством нулевых элементов;
int istr=-1, MaxKol=0;
for (i = 0; i < str; i++) {
int Kol=0;
for (j = 0; j < stb; j++) if(mas[i][j]==0) Kol++;
if (Kol>MaxKol) {istr=i; MaxKol=Kol;}}
 
//Вывод исходного массива на экран;
cout<<"Ishodniy massiv: "<<endl;
for (i = 0; i < str; i++){
 for (j=0; j < stb; j++) cout<<mas[i][j]<<" ";
}
if (istr== -1) cout<<endl<<"Nulevix elementov net!";
else cout<<endl<<"Nomer stroki: "<<istr+1;
 
getch();
return;
}
Необходимо оформить каждый пункт в виде функции. Исп. глобальных переменных не допускается. Ниже что у меня получилось, но где-то ошибка и код не компилится
(cannot convert parameter 1 from 'int [4][5]' to 'const int *')
Помогите доделать, или подскажите, в каком направлении искать =)


C++
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
34
35
36
#include <stdafx.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;
 
int srch(const int* mas, const int a, const int b);
int const str=4,stb=5;
 
int main(){
int x, c;
int mas[str][stb];
 
//Построчный ввод элементов массива;
for(x=0;x<str;x++)
 for(c=0;c<stb;c++)
  {cout<<"Vvedite ["<<x+1<<"]"<<"["<<c+1<<"]"<<" element massiva: ";
  cin>>mas[x][c];}
 
srch(mas, str, stb);
return 0;
getch();
}
 
 
//---------------------------------------------------
//Функция поиска номера строки с наиб. кол-вом нулей;
int srch(const int *mas, const int a, const int b){
int istr=-1, MaxKol=0;
for (int i = 0; i < str; i++) {
 int Kol=0;
 for (int j = 0; j < stb; j++) if(mas[i][j]==0) Kol++;
  if (Kol>MaxKol) {istr=i; MaxKol=Kol;}
return istr;
}
//---------------------------------------------------
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.09.2009, 16:59     Функции, передача массива в качестве параметра
Посмотрите здесь:

C++ [C++, OpenGL, glut] передача метода класса в качестве параметра функции glutDisplayFunc()
C++ Передача двумерного массива в качестве аргумента функции
Передача двумерного массива указателей на char в качестве параметра функции C++
C++ Передача массива как параметра функции
Передача массива в функцию в качестве параметра C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Rififi
 Аватар для Rififi
2330 / 1045 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
30.09.2009, 17:01     Функции, передача массива в качестве параметра #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
это

int srch(const int* mas, const int a, const int b);


заменить на

int srch(const int (&mas)[str][stb], const int a, const int b);
Опа!!
14 / 14 / 0
Регистрация: 30.09.2009
Сообщений: 89
30.09.2009, 17:27  [ТС]     Функции, передача массива в качестве параметра #3
Спасибо, сейчас попробую =0
Опа!!
14 / 14 / 0
Регистрация: 30.09.2009
Сообщений: 89
30.09.2009, 20:31  [ТС]     Функции, передача массива в качестве параметра #4
Работает) еще раз благодарю

вот окончательная версия, работает (двумерные массивы, функции, передача массива в качестве параметра, поиск строк с наибольшим количеством нулей). Может, понадобится кому)
C++
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
34
35
36
37
38
39
#include <stdafx.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;
 
//Глобальные переменные и объявление функции;
int const str=4,stb=5;
int srch(const int (&mas)[str][stb], const int a, const int b);
 
 
//Основная функция;
int main(){
int x, c;
int mas[str][stb];
 
//Построчный ввод элементов массива;
for(x=0;x<str;x++)
 for(c=0;c<stb;c++)
  {cout<<"Vvedite ["<<x+1<<"]"<<"["<<c+1<<"]"<<" element massiva: ";
  cin>>mas[x][c];}
 
if(srch(mas,str,stb) > 0) cout<<"Naiblo'shee kol-vo '0' soderzhitsya v "<<(srch(mas, str, stb)+1)<<"-oy stroke!";
else
 cout<<"Ni odna stroka ne soderzhit '0'!";
getch();
}
 
//---------------------------------------------------------------
//Определение функции поиска номера строки с наиб. кол-вом нулей;
int srch(const int (&mas)[str][stb], const int a, const int b){
int istr=-1, MaxKol=0;
for (int i = 0; i < str; i++) {
 int Kol=0;
 for (int j = 0; j < stb; j++) if(mas[i][j]==0) Kol++;
  if (Kol>MaxKol) {istr=i; MaxKol=Kol;}}
return istr;
}
//---------------------------------------------------------------
Rififi
 Аватар для Rififi
2330 / 1045 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
30.09.2009, 21:13     Функции, передача массива в качестве параметра #5
кстати, в таком случае дополнительные переменные a и b не нужны (если они используются для передачи количества строк/столбцов, чего из кода не видно)
получить их можно так:
const size_t H = sizeof(mas) / sizeof(mas[0]);
const size_t W = sizeof(mas[0]) / sizeof(mas[0][0]);
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
01.10.2009, 03:01     Функции, передача массива в качестве параметра #6
Rififi, а почему не работало? Ведь если у функции есть параметр-указатель,то можно передавать и массивы? Или ошибка потому,что параметр передаётся как const,и это связано с неявными преобразованиями указателя в массив?
TanT
эволюционирую потихоньку
 Аватар для TanT
464 / 462 / 43
Регистрация: 30.06.2009
Сообщений: 1,399
01.10.2009, 06:17     Функции, передача массива в качестве параметра #7
Цитата Сообщение от Rififi Посмотреть сообщение
кстати, в таком случае дополнительные переменные a и b не нужны (если они используются для передачи количества строк/столбцов, чего из кода не видно)
получить их можно так:
const size_t H = sizeof(mas) / sizeof(mas[0]);
const size_t W = sizeof(mas[0]) / sizeof(mas[0][0]);
может дело вкуса, но я отдаю предпочтение макросу
C++
1
#define ncell(m) (sizeof(m) / sizeof((m)[0]))
Rififi
 Аватар для Rififi
2330 / 1045 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
01.10.2009, 13:30     Функции, передача массива в качестве параметра #8
#pragma,

Rififi, а почему не работало?

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

Ведь если у функции есть параметр-указатель,то можно передавать и массивы?

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

Или ошибка потому,что параметр передаётся как const,и это связано с неявными преобразованиями указателя в массив?

нет, const влияет только на то, что данные, которые адресует такой указатель нельзя изменить, причем об этом следит сам компилятор а не программист.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.10.2009, 14:29     Функции, передача массива в качестве параметра #9
Цитата Сообщение от Rififi Посмотреть сообщение
В этом случае не работало потому, что функция ожидала указатель, а передавался двумерный массив. Одно в другое не приводится.
Двухмерный массив в приницпе не может передаваться. Просто ожидался параметр типа "указатель на int" или "указатель на одномерный массив int'ов" (оба термина эквивалентны), а передавался "указатель на двухмерный массив int'ов". В Си\Си++ подобные неявные преобразования между разными типами указателей запрещены

Однако я понимаю, чем вызван вопрос #pragm'ы, а потому просто отвечу конкретным исходником

C
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
#include <stdio.h>
 
void
func (int *arr, int n1, int n2)
{
  int i, j;
 
  for (i = 0; i < n1; i++)
    for (j = 0; j < n2; j++)
      printf ("%d\n", *(arr + i * n2 + j));
}
 
int
main (void)
{
  int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6} };
  int b[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8}, { 9, 10, 11, 12 } };
 
  printf ("-----\n");
  func ((int*)a, 2, 3);
  printf ("-----\n");
  func ((int*)b, 3, 4);
  printf ("-----\n");
  return 0;
}
Т.е. можно передавать и так, но при таком способе доступ к элементам массива можно осуществлять только через адресную арифметику, но нельзя через квадратные скобки. При этом такой метод оказывается более универсальным, чем метод Rififi, т.к. в его случае можно передавать только массив с какими-то фиксированными количествами по обоим измерениям. В мой способ можно передавать вообще массив с произвольным количеством измерений, нужно только более аккуратно подавать описатели размерностей. Но в такие крайности без какой-то необходимости впадать не следует

В языке C99 (и в GNU C) есть понятие VLA - variable length array. Возможно, что на современных виндовых компиляторах это тоже поддерживается, а потому можнонаписатьболее элегантно. При этом надо понимать, что это не есть "станадртный Си" (условнообзову именно этим термином)

C
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
#include <stdio.h>
 
void
func (int n1, int n2, int arr[n1][n2])
{
  int i, j;
 
  for (i = 0; i < n1; i++)
    for (j = 0; j < n2; j++)
      printf ("%d\n", arr[i][j]);
}
 
int
main (void)
{
  int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6} };
  int b[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8}, { 9, 10, 11, 12 } };
 
  printf ("-----\n");
  func (2, 3, a);
  printf ("-----\n");
  func (3, 4, b);
  printf ("-----\n");
  return 0;
}
Rififi
 Аватар для Rififi
2330 / 1045 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
01.10.2009, 15:02     Функции, передача массива в качестве параметра #10
Evg,
Возможно, что на современных виндовых компиляторах это тоже поддерживается
Что касается MS, то они по каким-то неведомым причинам не слишком жалуют С99 и не торопятся добавлять его поддержку в свой компиль. Так, даже новейшая скоро-выходящая VS2010 не обладает такой поддержкой.

впрочем, имея C++ оно не особо-то и нужно.
C++-эквивалент этого будет:

template <typename T, const size_t n1, const size_t n2>
void func(T (&arr)[n1][n2]);

только, как видно, гораздо удобнее - не зависит от типа, и размерности массива считаюся автоматически компилятором
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.10.2009, 16:44     Функции, передача массива в качестве параметра #11
Цитата Сообщение от Rififi Посмотреть сообщение
template <typename T, const size_t n1, const size_t n2>
void func(T (&arr)[n1][n2]);
Где-то мы это уже обсуждали, но всё равно напиши сюда конкретный пример, чтобы люди не искали
Rififi
 Аватар для Rififi
2330 / 1045 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
01.10.2009, 19:05     Функции, передача массива в качестве параметра #12
Evg,
Где-то мы это уже обсуждали, но всё равно напиши сюда конкретный пример, чтобы люди не искали

Собстна, твой пример может быть переписан так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
template <typename T, const size_t n1, const size_t n2>
void func (T (&arr)[n1][n2])
{
  for (size_t i = 0; i < n1; i++)
    for (size_t j = 0; j < n2; j++)
      std::cout << arr[i][j] << std::endl;
}
 
int
main (void)
{
  int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6} };
  int b[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8}, { 9, 10, 11, 12 } };
 
  std::cout << "-----" << std::endl;
  func (a);
  std::cout << "-----" << std::endl;
  func (b);
  std::cout << "-----" << std::endl;
  return 0;
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,136
Записей в блоге: 26
01.10.2009, 19:10     Функции, передача массива в качестве параметра #13
Если дело дойдёт до написания FAQ'а, надо не забыть про эту тему
ByHbKa
0 / 0 / 0
Регистрация: 27.10.2009
Сообщений: 29
20.11.2009, 13:29     Функции, передача массива в качестве параметра #14
ага
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.02.2011, 01:49     Функции, передача массива в качестве параметра
Еще ссылки по теме:

Передача функции с двумерным массивов в качестве параметра C++
Передача указателя в качестве параметра функции динамически подключаемой библиотеки .so C++
C++ Глобальное задание массива в качестве параметра функции

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Мигрень
 Аватар для Мигрень
20 / 20 / 2
Регистрация: 09.11.2010
Сообщений: 102
05.02.2011, 01:49     Функции, передача массива в качестве параметра #15
а как передать строку массива в качестве параметра?
Yandex
Объявления
05.02.2011, 01:49     Функции, передача массива в качестве параметра
Ответ Создать тему
Опции темы

Текущее время: 04:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru