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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача функциям и работа с динамическим массивом 
V
    Опции темы
Lorigin
Дата 8.11.2008, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Печатаю фото на холс



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

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



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

Код

#include "stdafx.h"
#include <iostream>
#include <locale>

using namespace std;

void VvodMas(int& M, int &Kolvo)  //очевидно здесь проблема
{
    for (int i=0; i<Kolvo; i++)
    {
        _tprintf(L"%d-ый: ",i);
        scanf_s("%d",M[i]); // как обратиться к нему?? тоесть записать в него
     }    
}

void VivodMas (int& M, int &Kolvo) // правильно ли??
{
    for (int i=0; i<Kolvo; i++)
    {
        _tprintf(L"%d   ",M[i]); // как обратиться к нему?
     }    
    getchar();getchar();
}

void Puzirek()
{
    
}

void Puzirek2()
{
    
}


int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL,".OCP");
    int key;
    int dlina = 0;
    
    Start:
    system("cls");
    if (dlina == 0) {
        _tprintf(L"Задайте размерность массива:  ");
        scanf_s("%d",&dlina);
        goto Start;
    }
    int *mas = new int[dlina];
    _tprintf(L"Меню: \n");
    _tprintf(L"1. Ввод элементов\n");
    _tprintf(L"2. Вывод элементов\n");
    _tprintf(L"3. Сортировать пузырьком \n");
    _tprintf(L"0. Выход \n\n\n");
    _tprintf(L":> ");
    scanf_s("%d",&key);
    switch (key) {
        case 
            1:VvodMas(*mas, dlina); goto Start;     //правильно передаю?
        case 
            2:VivodMas(*mas, dlina); goto Start;    //правильно передаю?
        case 
            3:Puzirek(); goto Start;
        case 
            4:Puzirek2(); goto Start;
        case 
            0:return 0;
        default: goto Start;
    }
    delete [] mas;
    return 0;
}


собственно застопорился как передать динамический массив в процедуру, чтобы его там заполнить... и как передать его чтобы прочитать 
(VvodMas,VivodMas), вся проблемма мне недоразобраться с * и & когда и что писать надо.... =\ читал уже 3 часа - в голове каша.. помогте пожалуйсто


Это сообщение отредактировал(а) Lorigin - 8.11.2008, 23:01
PM MAIL WWW   Вверх
mes
Дата 8.11.2008, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Код


void VvodMas(int * M, int Kolvo);
void VivodMas(int * M, int Kolvo);
VvodMas(mas, dlina);
VivodMas(mas, dlina);




--------------------
PM MAIL WWW   Вверх
mr.Anderson
Дата 8.11.2008, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


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

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



Lorigin, массив в Си - это указатель на некоторую область памяти, где начинаются элементы массива. Поэтому при передаче его в качестве параметра мы должны задать формальный параметр тоже как указатель. А количество - просто переменная, количество элементов, поэтому ссылка во втором параметре не нужна.


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Lorigin
Дата 8.11.2008, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Печатаю фото на холс



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

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



mes, 
вылетает ошибка при вводе первого элемента:
Unhandled exception at 0x102a5c53 (msvcr80d.dll) in Sortirovki.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd. =(
PM MAIL WWW   Вверх
mes
Дата 8.11.2008, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Lorigin @  8.11.2008,  22:59 Найти цитируемый пост)
вся проблемма мне недоразобраться с * и & когда и что писать надо..


void f (int ) // передача по значению .. т.е функция получает копию объекта
void f(int&) // передача по ссылке.. т.е  функция получает сам объект
void f(int *) //передача по указателю.. т.е функция получает копию переменой, храняшую адрес первого (одного) объекта 
void f(int *&) //передача указателя по ссылке.. т.е функция получает саму переменую, храняшую адрес первого (одного) объекта


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


Печатаю фото на холс



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

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



int *mas = new int[dlina];

тоесть этим мы выделяем память для определенного количества целых чисел?

так почему когда мы передаем VvodMas(mas, dlina); мы просто так пишем mas?

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

P.S. если у кого то есть подходящее чтиво где на элементарнейшим образом растолковано обращение с динамическими массивами при передаче между функциями.. буду крайне благодарен 

Это сообщение отредактировал(а) Lorigin - 8.11.2008, 23:51
PM MAIL WWW   Вверх
Lazin
Дата 8.11.2008, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



есть простые способы делать простые вещи
Код

//передача динамического массива по ссылке
void extend_vector( std::vector<int>& v )
{
    v.push_back(0);
}

//немного "магии", функция получает 2 итератора и выводит все что между ними в stdout
template<class I>
void out_data(I begin, I end)
{
    for (I i = begin; i != end; ++i)
        std::cout << *i << std::endl;
}

std::vector<int> my_array(100);//массив из 100 элементов

extend_vector(my_array);
std::cout << my_array.size() << std::endl;
out_data(my_array.begin(), my_array.end());


Это сообщение отредактировал(а) Lazin - 9.11.2008, 00:00
PM MAIL Skype GTalk   Вверх
Lorigin
Дата 9.11.2008, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Печатаю фото на холс



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

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



Lazin, 

про STL я слышал и знаю.. но цель разобраться именно в моей задаче =\
PM MAIL WWW   Вверх
SVN74
Дата 9.11.2008, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



PM MAIL WWW   Вверх
mes
Дата 9.11.2008, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Lorigin @  9.11.2008,  00:00 Найти цитируемый пост)
но цель разобраться именно в моей задаче =\ 


вот Вам примерчик , дальше надеюсь получится :
Код

#include <iostream>
#include <locale>
using namespace std;

void VvodMas(int* first, int* last)
{
  if (last<first) return;
  for (int *p=first; p!=last; ++p)
  {
   std::cout << p-first << "ый :  ";
   std::cin >> *p;
  }
  std::cout << std::endl << std::endl << std::endl;
}
void VivodMas(int* first, int* last)
{
  if (last<first) return;

  std::cout << *first; // вынесли из цикла , чтоб не путаться с запятой
  for (int *p=first+1; p!=last; ++p)
  std::cout << ", " << *p ;

  std::cout << std::endl << std::endl << std::endl;
}

void ShowMenu ()
{
    static const char *menu[]  = { "Меню: ","1. Ввод элементов", "2. Вывод элементов", "3. Сортировать пузырьком ", "0. Выход " };
    static const int   menu_size = sizeof(menu)/sizeof(char*);

    for (int i=0; i<menu_size; ++i)
    std::cout<<menu[i] << std::endl;
    std::cout << std::endl << std::endl << std::endl;
}

void MasAction(int dlina)
{
    int *mas = new int[dlina];
       int key=0;
    do
    {
        ShowMenu();
        cin >> key;

        switch (key)
        {
               case  1:VvodMas(mas, mas+dlina); break;
               case  2:VivodMas(mas, mas+dlina); break;
               default : break;
        }
    } while (key);

    delete[] mas;
}

int main ()
{
    int dlina =0;
    while (!dlina) { std::cout << "Задайте размерность массива:  "; cin >> dlina; }

    MasAction (dlina);

    system("pause");
  return 0;
}


P.S и старайтесь обходиться без goto.. Тем более так как Вы сделали.


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(Lorigin @  8.11.2008,  23:33 Найти цитируемый пост)
тоесть этим мы выделяем память для определенного количества целых чисел?

да

Цитата(Lorigin @  8.11.2008,  23:33 Найти цитируемый пост)
так почему когда мы передаем VvodMas(mas, dlina); мы просто так пишем mas?

mas это указатель, указатель это переменная, способная хранить адрес элемента определенного типа, в данном случае mas хранит адрес первого элемента массива, mas + 1 хранит адрес второго, mas + 2 третьего и тд... тоесть учитывается размер переменной, реально к адресу, для переменной типа int будет добавляться 4.
на пальцах:
если внутри указателя mas лежит значение 0x00100000, и мы прибавляем к нему 1, то указатель будет содержать 0x00100004(если размер типа int - 4 байта). При попытке разименовать это значение int tmp = *mas программа обратится к памяти по адресу 0x00100004, и прочитает оттуда 4 байта в переменную tmp.
если ты пишешь mas[N] то это эквивалентно *(mas + N), где * - операция разименования, тоесть полученя значения хранящегося по адресу, хранящемуся в указателе.
дальше, когда ты передаешь в функцию указатель, 
Код

void foo(int* addr, size_t data_size);

функция может, изменять значения в массиве, но, если функция изменит сам указатель, внешний код этого не увилит
Код

void allocate(int* addr, size_t size)
{
addr = new int[size];
}
int array = 0;
allocate(array, 1000);
array[0] = 1;//access violation

после вызова allocate переменная array все равно будет содержать 0, так как функция изменит только локальную копию указателя, что-бы этого избежать, нужно передать ссылку на указатель
Код

void allocate(int*& addr, size_t size)
{
addr = new int[size];
}
int array = 0;
allocate(array, 1000);
array[0] = 1;//ok

в этом случае, в функцию передается не значение указателя(0) а адрес переменной array и если функция его изменит, внешний код это увидит, так как переменная array изменится

ps 
то что я написал, написано в любой книге по с++, только понятно 
PM MAIL Skype GTalk   Вверх
mes
Дата 9.11.2008, 00:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Lazin @  9.11.2008,  00:23 Найти цитируемый пост)
ps 
то что я написал, написано в любой книге по с++, только понятно  

 smile классно сказал )



--------------------
PM MAIL WWW   Вверх
Lazin
Дата 9.11.2008, 00:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



зыы 
в твоем примере достаточно простых указателей
PM MAIL Skype GTalk   Вверх
Lorigin
Дата 9.11.2008, 01:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Печатаю фото на холс



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

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



Спасибо.. сейчас опять углублюсь и все проштудирую снова
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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