Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/95: Рейтинг темы: голосов - 95, средняя оценка - 4.81
17 / 17 / 1
Регистрация: 30.09.2009
Сообщений: 89
1

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

30.09.2009, 16:59. Показов 17615. Ответов 14
Метки нет (Все метки)

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

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;
}
//---------------------------------------------------
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.09.2009, 16:59
Ответы с готовыми решениями:

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

Передача двумерного массива указателей на char в качестве параметра функции
Есть массив char *result2; Нужно передать его в функцию void defDouble(???) в качестве одного из...

Передача функции в качестве параметра
#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; double f(double x) { return...

Передача функции в качестве параметра
Как передать функцию с параметрами в transform? Т.е., например, мне надо из каждого числа вектора...

14
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
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);
3
17 / 17 / 1
Регистрация: 30.09.2009
Сообщений: 89
30.09.2009, 17:27  [ТС] 3
Спасибо, сейчас попробую =0
0
17 / 17 / 1
Регистрация: 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;
}
//---------------------------------------------------------------
0
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
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]);
2
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
01.10.2009, 03:01 6
Rififi, а почему не работало? Ведь если у функции есть параметр-указатель,то можно передавать и массивы? Или ошибка потому,что параметр передаётся как const,и это связано с неявными преобразованиями указателя в массив?
0
эволюционирую потихоньку
468 / 466 / 91
Регистрация: 30.06.2009
Сообщений: 1,401
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]))
0
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
01.10.2009, 13:30 8
#pragma,

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

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

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

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

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

нет, const влияет только на то, что данные, которые адресует такой указатель нельзя изменить, причем об этом следит сам компилятор а не программист.
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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;
}
3
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
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]);

только, как видно, гораздо удобнее - не зависит от типа, и размерности массива считаюся автоматически компилятором
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
01.10.2009, 16:44 11
Цитата Сообщение от Rififi Посмотреть сообщение
template <typename T, const size_t n1, const size_t n2>
void func(T (&arr)[n1][n2]);
Где-то мы это уже обсуждали, но всё равно напиши сюда конкретный пример, чтобы люди не искали
1
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
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;
}
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
01.10.2009, 19:10 13
Если дело дойдёт до написания FAQ'а, надо не забыть про эту тему
0
0 / 0 / 0
Регистрация: 27.10.2009
Сообщений: 29
20.11.2009, 13:29 14
ага
0
21 / 21 / 2
Регистрация: 09.11.2010
Сообщений: 102
05.02.2011, 01:49 15
а как передать строку массива в качестве параметра?
0
05.02.2011, 01:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.02.2011, 01:49
Помогаю со студенческими работами здесь

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

Передача CString в качестве параметра функции
Добрый всем вечер! Мучает один вопрос, на который не могу найти ответ. Как наилучшим образом...

Передача функции в качестве параметра в другую функцию
Задание стоит следующее: Написать программу, содержащую две функции. Первая функция, вычисляющая...

Передача функции с двумерным массивов в качестве параметра
Всем доброго времени суток. У меня проблема следующего плана. Есть некая функция void...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru