Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.07.2017, 22:20   #1
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию язык Си массивы

Возникла такая проблема: обычно при работе с массивами я не использую синтаксический сахар, а обращаюсь к элементам массива с помощью *(mas + n). Но это правильно работает только с одномерными массивами - если это многомерный (дву-) массив, то выдает ошибку, если ставить **(mas l * SIZE + n), то, хоть никакой ошибки не появляется, программа просто не работает как надо. Как правильно обращаться к элементу многомерного массива не используя синтаксический сахар?
tutejshy вне форума Ответить с цитированием
Старый 29.07.2017, 00:39   #2
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Для того, чтобы работать через конструкцию *(mas + i * SIZE + k), нужно иметь одномерный массив размера M*N (эмуляция двумерности)

Двумерный массмв нужно разыменовывать два раза вложенно, примерно так:
Код:
#include <stdio.h>
int main()
{
  int i, k;
  int arr[2][3] = {{1,2,3}, {4,5,6}};
  for (i = 0; i<2; i++)
  {
    for (k = 0; k<3; k++)
    {
      printf("%d ", *(*(arr+i)+k));
    }
    printf("\n");  
  }  
}
Но я не вижу ни одного разумного аргмента за такой способ записи..
Black Fregat вне форума Ответить с цитированием
Старый 29.07.2017, 07:07   #3
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

"двумерный массив" (тот, что пишится arr[i][j]) есть массив УКАЗАТЕЛЕЙ на УКАЗАТЕЛИ на ЗНАЧЕНИЯ. Поэтому у вас и не работает, как хотите. В общем случае, там не линейная память.
Для такой записи *(mas + i * SIZE + k) вам нужно делать синтаксичски 1 мерный массив с размером M*N значений.
Кстати удалять двумерные массивы нужно циклом - сначала каждую строку delete[], а потом весь массив так же (и распределять построчно).
alexzk вне форума Ответить с цитированием
Старый 29.07.2017, 08:28   #4
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Сообщение от tutejshy Посмотреть сообщение
обычно при работе с массивами я не использую синтаксический сахар
Изначально провальная затея.
Croessmah вне форума Ответить с цитированием
Старый 29.07.2017, 16:51   #5
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение
Изначально провальная затея.
Интересно почему?
tutejshy вне форума Ответить с цитированием
Старый 29.07.2017, 16:55   #6
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию

Цитата:
Сообщение от Black Fregat Посмотреть сообщение
#include <stdio.h>
Цитата:
Сообщение от Black Fregat Посмотреть сообщение
Код:


#include <stdio.h>
int main()
{
int i, k;
int arr[2][3] = {{1,2,3}, {4,5,6}};
for (i = 0; i<2; i++)
{
for (k = 0; k<3; k++)
{
printf("%d ", *(*(arr+i)+k));
}
printf("\n");
}
}
Спасибо

Последний раз редактировалось tutejshy; 29.07.2017 в 17:01.
tutejshy вне форума Ответить с цитированием
Старый 29.07.2017, 21:09   #7
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
В общем случае, там не линейная память.
нет никаких ни "общих случаев",
ни "частных случаев".

есть один единственный случай:
память в массивах всегда располагается линейно.
и это не зависит от его разрядности.

следующий код иллюстрирует,
как найти минимальный элемент в массивах любой разрядности:

http://rextester.com/DOR88516

Код:
#include <iostream>
#include <algorithm>

// =======================================================
// =======================================================
// =======================================================

//   вычисляет количество элементов многомерного массива

template<class T> struct elem__
{
    typedef T type;
    static const size_t value = 1;
};

template<class T, size_t N> struct elem__< T[N] >
{
    typedef typename elem__<T>::type
        type;
    static const size_t value = N * elem__<T>::value;
};

template<class T> 
const typename elem__<T>::type& min__(const T& arr)
{
    static_assert(
        std::is_array<T>::value,
        "ERROR: expected array"
    );
    typedef typename elem__<T>::type
        type;
    
    auto* b = reinterpret_cast<const type*>(arr);
    auto* e = b + elem__<T>::value;
    
    return *std::min_element(b,e);
}

// =======================================================
// =======================================================
// =======================================================

void example2d()
{
    int a[2][3] = {
        {3,4,5},
        {6,7,1},
    };
    std::cout << "[must be 1] min value = "<< min__(a) <<std::endl;
}

void example3d()
{
    int a[2][2][3] = {
        {
            {3,4,5},
            {6,7,2},
        },
        {
            {3,4,5},
            {6,7,8},
        },
    };
    std::cout << "[must be 2] min value = "<< min__(a) <<std::endl;
}


int main()
{
    std::cout << "Hello, world!\n";
    example2d();
    example3d();
}
_Bers вне форума Ответить с цитированием
Старый 29.07.2017, 22:07   #8
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Это если именно массивы, а не их эмуляция через массив указателей и т.д.
p51x вне форума Ответить с цитированием
Старый 29.07.2017, 22:11   #9
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
есть один единственный случай:
память в массивах всегда располагается линейно.
Например, в таком коде компилятор этого уже не знает:
Код:
void exampleBadBar(int a[2][3])
{
    std::cout << "[must be 1] min value = "<< min__(a) <<std::endl;
}

void exampleBadFoo()
{
    int a[2][3] = {
        {3,4,5},
        {6,7,1},
    };
    exampleBadBar(a);
}
Black Fregat вне форума Ответить с цитированием
Старый 29.07.2017, 22:27   #10
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Это если именно массивы, а не их эмуляция через массив указателей и т.д.
когда речь пойдёт о не массивах,
тогда будем говорить о не массивах.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Язык Си - массивы leonid_spartak Помощь студентам 1 12.05.2017 09:30
Массивы.Язык Си Caca0 Помощь студентам 26 05.02.2013 00:10
массивы. язык СИ. skauzer_blr Помощь студентам 8 10.04.2012 22:15
Массивы, язык - C. xcyber Помощь студентам 9 19.10.2009 21:38
Массивы (язык С++) Ноберт Помощь студентам 3 24.08.2009 23:10