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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> передача массива по ссылке, как передать массив в функцию по ссылке 
:(
    Опции темы
pepelaz
Дата 1.4.2007, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Код

 bool proverka(int a,int b[])
{   int i;
    bool flag;
    i=0;
 while (i<3)
 {if (a==b[i])
 {flag = 1;}  

 else {flag= 0;} 
 i++;
 }


все работает , но как массив b передать не по значению , а по ссылке.Подскажите пожалуйста недавно только c++ учу .никак не разберусь с этой ерундой
PM MAIL   Вверх
Daevaorn
Дата 1.4.2007, 15:30 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Ты передешь и так по указателю, поэтомы ссылка тут не нужна
PM MAIL WWW   Вверх
JAnty
  Дата 1.4.2007, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



 bool proverka(int a,int *b);
 bool proverka(int a,int b[8]);
 bool proverka(int a,int b[]);

Всё одно и тоже.


--------------------
Русский справочник по WinAPI

Возможно всё, что возможно вообразить! Это и значит быть гением как я!
PM MAIL   Вверх
vinter
Дата 1.4.2007, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


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

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



Цитата(JAnty @  1.4.2007,  15:40 Найти цитируемый пост)
Всё одно и тоже.

не совсем smile 


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


Новичок



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

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



Код

while  (i<3) /*есть елементы в послудовательности*/
   
   {
       if (  proverka(x[i],y)==0 ) /*if x[i] нет в y засовываем его туда*/
          {y[j]=x[i];
           j++;
           i++;
          
          }       
   else i++; /*есть в y не засовываем*/
       
       
    }

proverka выполняется для  одного и того же  массива который был считан вначале, а должена по идее выполнятся для массива с обновленными значениями
PM MAIL   Вверх
sisbkoshup
Дата 1.4.2007, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Имя массива и есть ссылка на первый элемент! Причем константная, поэтому нелбзя массивы присваивать друг другу в с++!!!
Т.ч. Любой массив передается по ссылке!

_________________

 smile 

Это сообщение отредактировал(а) sisbkoshup - 1.4.2007, 21:10
PM MAIL   Вверх
BreakPointMAN
Дата 1.4.2007, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(sisbkoshup @  1.4.2007,  22:09 Найти цитируемый пост)
Имя массива и есть ссылка на первый элемент!

Кто тебе сказал такую глупость?


--------------------
"Разруха не в клозетах, а в головах." © Ф.Ф. Преображенский (М.Булгаков, "Собачье сердце")
PM WWW ICQ   Вверх
Xenon
Дата 1.4.2007, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Константная ссылка - это некий новый элемент языка?


--------------------
user posted image  
PM MAIL   Вверх
sisbkoshup
Дата 1.4.2007, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(BreakPointMAN @ 1.4.2007,  21:16)
Цитата(sisbkoshup @  1.4.2007,  22:09 Найти цитируемый пост)
Имя массива и есть ссылка на первый элемент!

Кто тебе сказал такую глупость?

Набей код:

Код

int a[10]; 
for (i=0; i<10; ++i)
  a[i]=i;
cout<<2[a];



И посмотри что будет!

или если угодно: 

Код

  int *p;
  int a[10];
  p=&a[0];
  for (int i=0; i<10; ++i)
     *(p++)=i;
  cout<<a[2];



a[2]~*(a+2)~2[a]!!!!!!!!!!

И на конец попробуй присвоить массивы друг другу!!!
Это говорят на лекциях в РГУ!!!



_____________________


 smile 




Это сообщение отредактировал(а) sisbkoshup - 1.4.2007, 21:42
PM MAIL   Вверх
Xenon
Дата 1.4.2007, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



sisbkoshup, я тебе про то, что это не ссылка, а указатель константный.

Это сообщение отредактировал(а) Xenon - 1.4.2007, 21:30


--------------------
user posted image  
PM MAIL   Вверх
apook
Дата 1.4.2007, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Имя массива и есть ссылка на первый элемент!

Цитата

имя массива является синонимом расположения его начального элемента

Цитата

Можно производить следующие операции с указателями:
1. Присваивание значения указателя другому указателю того же типа
2. Сложение и вычитание указателя и целого
3. Вычитание и сравнение двух указателей, указывающих на элементы одн
   ого и того же массива,
4. Присваивание указателю нуля и сравнение указателя с нулем.

Других операций с указателями производить не допускается!

Нельзя складывать два указателя, перемножать их,  делить,  сдвигать,
выделять разряды;
указатель нельзя складывать со значением типа float или double;
указателю одного типа нельзя даже присвоить указатель другого  типа,
не выполнив предварительно операции приведения ( исключение составл
яют лишь указатели типа void * ). 




Это сообщение отредактировал(а) apook - 1.4.2007, 21:45


--------------------
Мои руки из дуба, голова из свинца ну и пусть ...
PM MAIL   Вверх
sisbkoshup
Дата 1.4.2007, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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


Эксперт
***


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

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



Хотя Страуструп пишет, что:
Код

int arr [] = {1,4,3};
int* pTr = arr; //Неявное преобразования int[] в int*

Получается не вполне корректно называть arr констатным указателем?


--------------------
user posted image  
PM MAIL   Вверх
sisbkoshup
Дата 1.4.2007, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вполне корректно! Почему нет?
PM MAIL   Вверх
Xenon
Дата 1.4.2007, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



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


--------------------
user posted image  
PM MAIL   Вверх
Fazil6
Дата 1.4.2007, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Xenon @  1.4.2007,  22:11 Найти цитируемый пост)
Получается не вполне корректно называть arr констатным указателем?

почему? 
PM MAIL   Вверх
sisbkoshup
Дата 1.4.2007, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(apook @ 1.4.2007,  21:43)
Можно производить следующие операции с указателями:
1. Присваивание значения указателя другому указателю того же типа
2. Сложение и вычитание указателя и целого
3. Вычитание и сравнение двух указателей, указывающих на элементы одн
   ого и того же массива,
4. Присваивание указателю нуля и сравнение указателя с нулем.

Других операций с указателями производить не допускается!

Нельзя складывать два указателя, перемножать их,  делить,  сдвигать,
выделять разряды;
указатель нельзя складывать со значением типа float или double;
указателю одного типа нельзя даже присвоить указатель другого  типа,
не выполнив предварительно операции приведения ( исключение составл
яют лишь указатели типа void * ). 

Два указателя одного типа можно, и нужно, складывать и вычитать, результатом будет целое!

______________

 smile

Добавлено через 4 минуты и 9 секунд
Цитата(Xenon @ 1.4.2007,  22:25)
sisbkoshup, просто такое неявное преобразование массива в указатель при вызове функции приводит к потере размера массива, значит не совсем одно и тоже ...

Размер передать вторым параметром! Как это все и делают!!!



____________


 smile 

Это сообщение отредактировал(а) sisbkoshup - 1.4.2007, 22:26
PM MAIL   Вверх
BreakPointMAN
Дата 1.4.2007, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(sisbkoshup @  1.4.2007,  23:25 Найти цитируемый пост)
Два указателя одного типа можно, и нужно, складывать и вычитать, результатом будет целое!

Вычитать можно (и то надо делать с умом), складывать - нет. Кури умные книжки.
PS: массив не есть указатель, имя массива может в ряде случаев рассматриваться как константный указатель на его первый элемент, но не более того. И физически это отнюдь не одно и то же. На RSDN этой теме даже несколько вопросов из FAQ посвящено: 


--------------------
"Разруха не в клозетах, а в головах." © Ф.Ф. Преображенский (М.Булгаков, "Собачье сердце")
PM WWW ICQ   Вверх
Xenon
Дата 1.4.2007, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



sisbkoshup, при чем тут это. Мы говорим что это не одно и тоже, а ты вообще о другом чем-то. BreakPointMAN уже привел достаточно ссылок убедительных + Страуструпа надо читать, хотя он там об этом как-то вскользь пишет, хотя даже из "неявное преобразование" можно понять, что это не одно и тоже.


--------------------
user posted image  
PM MAIL   Вверх
JAnty
  Дата 2.4.2007, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



А ссылка на объект чем отличается от указателя?


--------------------
Русский справочник по WinAPI

Возможно всё, что возможно вообразить! Это и значит быть гением как я!
PM MAIL   Вверх
apook
Дата 2.4.2007, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

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

 smile  smile  smile 


--------------------
Мои руки из дуба, голова из свинца ну и пусть ...
PM MAIL   Вверх
JAnty
  Дата 2.4.2007, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

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

 smile 
Значит:
Код

int x;
int &a = x; /* не равно */ int *b = &x;


Будем считать, что я понял. smile 


--------------------
Русский справочник по WinAPI

Возможно всё, что возможно вообразить! Это и значит быть гением как я!
PM MAIL   Вверх
zkv
Дата 11.6.2007, 06:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

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



всплыл этот вопрос.
Возможно ли создать полноценную ссылку на массив, чтобы и sizeof правильно работал, и в функцию ее можно было передать?
Код

int A = 1;
int &rA = A;

int ARR [2][2];
//ссылка на ARR возможна?

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


Опытный
**


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

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



Цитата

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

Я так понимаю что не возможно такое
а еще вот  то что в функции sizeof-ом не получается воспользоваться, он возвращает
размер указателя тож неприятность


--------------------
Мои руки из дуба, голова из свинца ну и пусть ...
PM MAIL   Вверх
Voldemar2004
Дата 11.6.2007, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(sisbkoshup @  1.4.2007,  22:09 Найти цитируемый пост)
Имя массива и есть ссылка на первый элемент!


Цитата(BreakPointMAN @  1.4.2007,  22:16 Найти цитируемый пост)
Кто тебе сказал такую глупость?


А как же это:
Цитата
Связь между указателями и массивами

В языке Си массивы и указатели тесно связаны. Имя каждого массива может рассматриваться как указатель на первый элемент массива.
  smile  Взято отсюда 

Я и вдругих книгах читал про это - у Крупника, например, "Язык Си".

Добавлено через 8 минут и 10 секунд
Наверно имелось в виду, что имя массива - это указатель на его первый элемент, а не ссылка ?


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
zkv
Дата 11.6.2007, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

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



Voldemar2004, только не надо снова подымать эту тему, целая война была, может вернемся к вопросу:
Цитата(zkv @  11.6.2007,  06:22 Найти цитируемый пост)
Возможно ли создать полноценную ссылку на массив, чтобы и sizeof правильно работал, и в функцию ее можно было передать?


попробую пояснить подробнее:
Код

//с простыми типами делается так:
int A = 1;
int B = 2;
int &rInt;
if( ... )
  rInt = A;
else
  rInt = B;

//а ка провернуть с массивом?
int ARR_A [2][2];
int ARR_B [2][2];
//как объявить rARR?
if( ... )
  rARR = ARR_A;
else
  rrARR = ARR_B ;


если такую ссылку создать невозможно, то почему?
PM MAIL   Вверх
Daevaorn
Дата 11.6.2007, 13:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(zkv @  11.6.2007,  13:51 Найти цитируемый пост)
//с простыми типами делается так:

так нельзя. ссылка должна быть инициализирована сразу.
Цитата(zkv @  11.6.2007,  13:51 Найти цитируемый пост)
//а ка провернуть с массивом?

никак. язык такие конструкции не поддерживает.
PM MAIL WWW   Вверх
zkv
Дата 11.6.2007, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

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



Цитата(Daevaorn @  11.6.2007,  13:02 Найти цитируемый пост)
так нельзя. ссылка должна быть инициализирована сразу.

да, наврал немного, ну не суть, пусть будет так:
Код

int A = 1;
int B = 2;
int &rInt = A;
if( ... )
  rInt = A;
else
  rInt = B;

Цитата(Daevaorn @  11.6.2007,  13:02 Найти цитируемый пост)
никак. язык такие конструкции не поддерживает. 

спасибо, верю на слово smile
PM MAIL   Вверх
Fazil6
Дата 11.6.2007, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(zkv @  11.6.2007,  12:51 Найти цитируемый пост)
если такую ссылку создать невозможно, то почему?


Код

#include <stdio.h>

template<typename T , typename A>
void farr(T &as, const A x)
{
    printf("\nSize = %d" , sizeof(as)/sizeof(A));
}


int main()
{

    int arr[123];
    farr(arr, arr[0]);
}




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


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

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



Да, что ни говори, шаблоны - сила. Никому за C++ templates не угнаться. Для тех, кто их не любит, предлагается куда менее изящный вариант:
Код
#include <cstdlib>
#include <cassert>

const size_t ROWS = 2;
const size_t COLS = 2;

int sizeOfGivenArr( int (& refArrParam)[ROWS][COLS] ) {
    return sizeof(refArrParam) / sizeof(*refArrParam);
}

int main() {
    int arr [ROWS][COLS] = { 1, 2, 3, 4 };
    int (& refArr) [ROWS][COLS] = arr;
    
    assert( refArr[1][1] == arr[1][1] );
    assert( sizeof(arr)/sizeof(*arr) == sizeof(refArr)/sizeof(*refArr) );
    assert( sizeof(arr)/sizeof(*arr) == sizeOfGivenArr(arr) );
}


Это сообщение отредактировал(а) Ulysses4j - 11.6.2007, 13:15


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
Fazil6
Дата 11.6.2007, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



в принципе даже так проканает
Код

#include <stdio.h>

struct AAA
{
    int x;
    int y;
    char t;
    double d;

};
    template<typename T >
void farr(T &as)
{
    printf("\nSize = %d" , sizeof(as)/sizeof(as[0]));
}


int main()
{

    int arr[123];
    farr(arr);

    char ca[12];
    farr(ca);

    AAA ds[12454];
    farr(ds);
}



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

Это сообщение отредактировал(а) Fazil6 - 11.6.2007, 13:19
PM MAIL   Вверх
_stranger_
Дата 11.6.2007, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 3.10.2006
Где: город-герой Киев

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



а если вот так
Код

int ARR[2][2];
typedef int Mass[2][2];
Mass& ttt = ARR;

void func(Mass &ref)
{
   std::cout << sizeof(ref) << std::endl;
}


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

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



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

Я не спорю, что шаблонный вариант куда более расширяемый и удобный smile

Это сообщение отредактировал(а) Ulysses4j - 11.6.2007, 13:27


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
Fazil6
Дата 11.6.2007, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Ulysses4j @  11.6.2007,  13:25 Найти цитируемый пост)
необходимо для обеих вариантов - шаблонного и нешаблонного.

так, но я имел в виду. что нельзя написать
Код

int sizeOfGivenArr( int (& refArrParam)[])
{
   и т.д. .....

и поэтому для каждого отдельного массива разной размерности придется писать свою функцию, что вобщем-то несовсем входит в условие задачи. Какой смысл определять размер массива внутри функции если он и так жестко задан в объявлении параметра этой функции?
PM MAIL   Вверх
Ulysses4j
Дата 11.6.2007, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

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



Цитата(Fazil6 @ 11.6.2007,  14:32)
Какой смысл определять размер массива внутри функции если он и так жестко задан в объявлении параметра этой функции?

Мне кажется, именно жесткость здесь и желанна: внутри функции хочется быть уверенным, что мы имеем массив определенного размера. В отличие от распространенного подхода:
Код
void f( int a[3][4] ) {/*...*/}

 - где нам могут подсунуть что-угодно, в случае с ссылками цифры не врут. 

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



Это сообщение отредактировал(а) Ulysses4j - 11.6.2007, 13:49


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
Fazil6
Дата 11.6.2007, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Ulysses4j @  11.6.2007,  13:46 Найти цитируемый пост)
Еще неизвестно, что удобней.


Цитата(Ulysses4j @  11.6.2007,  13:46 Найти цитируемый пост)
в случае с ссылками цифры не врут.

так причем здесь определение размера? Он ведь известен... В твоем варианте проблема как таковая не стоит.
Код

int sizeOfGivenArr( int (& refArrParam)[ROWS][COLS] ) {
    return sizeof(refArrParam) / sizeof(*refArrParam);
}

это ведь тоже самое что и
Код

int sizeOfGivenArr( int (& refArrParam)[ROWS][COLS] ) {
    return ROWS;
}



PM MAIL   Вверх
Ln78
Дата 11.6.2007, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(zkv @  11.6.2007,  12:51 Найти цитируемый пост)

//а ка провернуть с массивом?
int ARR_A [2][2];

Если размеры известны, то можно писать так:
Код

typedef int Ar2_2[2][2] ;
int ARR_A [2][2];
Ar2_2& rA=ARR_A;

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



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

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



Всем спасибо, за столь развернутые примеры!

Но полное понимание сего вопроса еще не пришло, посмотрите плиз примерчик:
Код

typedef int Ar2_2[2][2];

int main()
{
    int a = 1, b = 2;
    int &c = (a > b) ? a : b;  //нет проблем

    Ar2_2 ARR_A = {0}, ARR_B = {0};
    
    Ar2_2& rArr1 = ARR_A;//нет проблем
    Ar2_2& rArr2 = (a > b) ? ARR_A : ARR_B; //не катит, почему?
}

на отмеченной проблемной строке компилятор VC7.1 выдает ошибку:
Цитата

main.cpp(12) : error C2440: 'initializing' : cannot convert from 'int (*)[2]' to 'Ar2_2 (&)'
        A reference that is not to 'const' cannot be bound to a non-lvalue

Это особенность компилятора, или это и не должно работать?
PM MAIL   Вверх
Ulysses4j
Дата 11.6.2007, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

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



zkv, MinGW скомпилировал. VC++ (я восьмеркой пробовал - та же история) выделывается: ссылка - это хоть и константа, но константы бывают времени компиляции и времени выполнения. И если у компилятора не получается на этапе компиляции определить, то надо оставлять на потом. Возможно, правила более хитрые, и я чего-то не понимаю.


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
Fazil6
Дата 12.6.2007, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(zkv @  11.6.2007,  23:25 Найти цитируемый пост)
Это особенность компилятора, или это и не должно работать?


Цитата(zkv @  11.6.2007,  23:25 Найти цитируемый пост)
на отмеченной проблемной строке компилятор VC7.1 выдает ошибку:

у меня VC 80 проглотил нормально. Насчет VC71. 
Здесь всетаки оператор и видимо какая-то шняга получается с преобразованием массива к указателю (как в параметрах функции) 
Дальше имя массива не lvalue , а чтобы инициализировать ссылку сущностью, которая не является lvalue, эта ссылка должна быть константной (блин задвинул... короче только const ссылки позволяется инициализировать себя не lvalue). Так что понять его можно, хотя повторяю, что 80 схавал нормально
PM MAIL   Вверх
Ulysses4j
Дата 12.6.2007, 07:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

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



Цитата(Fazil6 @ 12.6.2007,  01:15)
у меня VC 80 проглотил нормально.

Ух-ты, тогда я уточню, что у меня не захотел компилировать этот код с такой же ошибкой компилятор MS Visual C++ 8.0 из состава VS Express Edition. Хотя я все время думал, что сам компилятор EE ничем от оного из "большой" VS не отличается.

Это сообщение отредактировал(а) Ulysses4j - 12.6.2007, 07:28


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
Ln78
Дата 12.6.2007, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Я пробовал тоже на восьмёрке, профессиональной, выдалась та же ошибка, что и у zkv. Пробовал менять настройки в проекте, что-то не получилось. Пробовал обмануть компилятор в 2 этапа:
Код

typedef int ArD2_3_2[3][2]; //Размерности разные, чтобы было проще отличать их между собой

void FalseReferens()
{
   ArD2_3_2 A={0},B={0};
   int a = 1, b =2;
   int * pI = a < b ? &A[0][0] : &B[0][0];
   ArD2_3_2& rAr = (ArD2_3_2&) pI;

   rAr[1][1]=123; //Здесь изменяется совсем другое значение
}

был наказан тем, что, хотя и не получил ни одного ворнинга, получил неправильно работающую функцию.
Ничего лучше, чем
Код

struct Sar
{
   Sar(ArD2_3_2 Ar) : pA(Ar) {}
   inline int* operator[](int i){return  pA[i];}
private:
   int (*pA)[2];
};
void Referens()
{
   ArD2_3_2 A={0},B={0};
   int a = 1, b =2;
   Sar rS = a < b ? A : B;

   rS[1][1]=12;
}

придумать не сумел. Вряд ли это то, что нужно zkv, но, возможно, кому-нибудь и пригодиться.

Это сообщение отредактировал(а) Ln78 - 12.6.2007, 08:09
PM MAIL   Вверх
JackYF
Дата 12.6.2007, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(zkv @  11.6.2007,  13:08 Найти цитируемый пост)
да, наврал немного, ну не суть, пусть будет так:

не будет. Это же совсем не то, что ты хочешь, насколько я понимаю.

Обычно данные проблемы решаются с помощью указателей:
Код


int ARR_A [2][2];
int ARR_B [2][2];


typedef int ARR[2][2];
ARR* rArr;
if( ... )
  rARR = &ARR_A;
else
  rrARR = &ARR_B ;


Неужели так необходимы ссылки?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
zkv
Дата 12.6.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

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



Цитата(JackYF @  12.6.2007,  14:17 Найти цитируемый пост)
не будет. Это же совсем не то, что ты хочешь, насколько я понимаю.

да я наврал много, сразу намека Daevaorn'a не понял smile по привычке делал по аналогии с указателями, потом понял что сморозил чушь.

Цитата(JackYF @  12.6.2007,  14:17 Найти цитируемый пост)
Обычно данные проблемы решаются с помощью указателей:

обычно так и делал, но вот вспомнил слова Страуструпа, что указатели в С++ всегда можно заменить ссылками (где-то он такое говорил...), и решил раскопать, как это делается в таком случае smile
PM MAIL   Вверх
JackYF
Дата 12.6.2007, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(zkv @  12.6.2007,  14:37 Найти цитируемый пост)
что указатели в С++ всегда можно заменить ссылками (где-то он такое говорил...),

ах вот откуда ноги растут... тогда ясно.

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



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Mag
Дата 15.6.2007, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(vinter @ 1.4.2007,  15:41)
Цитата(JAnty @  1.4.2007,  15:40 Найти цитируемый пост)
Всё одно и тоже.

не совсем smile

почему это? Правильно выше расписали! 
--------------------
В  каждой черной комнате есть выход - всегда есть выход с любой ситуации!
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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