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

Как одномерный массив представить двумерным? - C++

Восстановить пароль Регистрация
 
 
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
10.06.2013, 13:22     Как одномерный массив представить двумерным? #1
Я загрузил изображение. И есть указатель на его однобайтные пиксели: BYTE *pixels;
Пиксель [5,8] считываю так: pixels[5*Width+8];
А как сделать, чтоб pixels[5,8] ?

Пробую через другой указатель:
BYTE *array[Width][Height]=pixels;
Компилятор ругается.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.06.2013, 13:22     Как одномерный массив представить двумерным?
Посмотрите здесь:

C++ Можно ли представить структуру как элемент массива, т е массив состоящий из однотипных структур
Матрица и одномерный массив (Составить одномерный массив, содержащий количество буквенных символов в каждом из ее столбцов, подсчет символов) C++
C++ Задача по двумерным массивам :) ( нечетные строки двумерного массива заменить на одномерный массив)
C++ Как представить массив состоящий из дробей ?
C++ ассоциативный массив map c двумерным массивом
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fair7
8 / 8 / 0
Регистрация: 31.12.2010
Сообщений: 81
10.06.2014, 01:49     Как одномерный массив представить двумерным? #2
Я как-то писал программу, которая может помочь понять: как с одно мерным массивом, можно работать, как с двухмерным.
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
#include "c:/MyLib/nn_p.h"
#include "c:/MyLib/winconsole.h"
#define s 254
int main()
{
    char fieldYX[49*80];
    for (int i = 0; i < 49*80;fieldYX[i++]=' ');
    Blinking();
    int g,yx=24*41;
    do
    {
        _XY();p(fieldYX);
        g=_getch();
        switch(g)
        {
        case 'q':if((yx-80)>=0)fieldYX[yx-=80]=s;break;
        case 'a':if((yx+80)<=49*80)fieldYX[yx+=80]=s;break;
        case 'o':if((yx-1)>=0&&(yx)%80!=0)fieldYX[--yx]=s;break;
        case 'p':if((yx+1)<=49*80&&(yx+1)%80!=0)fieldYX[++yx]=s;break;
        }
    }
    while(g!=27);
    return 0;
}
q-верх
a-вниз
o-влево
p-вправо

Добавлено через 14 минут
Прошу прощения, предыдущий исходник, ссылался на мою библиотеку.
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#define s 254
HANDLE hCon =  GetStdHandle( STD_OUTPUT_HANDLE );
void Blinking(int off=99)// MEPYAHUE y5PATb
{   CONSOLE_CURSOR_INFO cci;
    cci.dwSize=off;
    cci.bVisible=false;
    SetConsoleCursorInfo(hCon,&cci);
}
void AltEnter()
{
    keybd_event(VK_MENU,
                0x38,
                0,
                0);
    keybd_event(VK_RETURN,
                0x1c,
                0,
                0);
    keybd_event(VK_RETURN,
                0x1c,
                KEYEVENTF_KEYUP,
                0);
    keybd_event(VK_MENU,
                0x38,
                KEYEVENTF_KEYUP,
                0);
}
void _XY(unsigned short X=0,unsigned short Y=0)// nO3UYUR KyPCOPA, D7R CUMBO7OB
{   COORD coord = { X, Y };
    SetConsoleCursorPosition(hCon, coord);
}
char fieldYX[49*80];// Обяъявил глобальной, чтобы в конце ноль не дописовать, чтобы мусор не выводить
int main()
{
    
    for (int i = 0; i < 49*80;fieldYX[i++]=' ');
    Blinking();
    AltEnter();
    int g,yx=24*41;
    do
    {
        _XY();printf(fieldYX);
        g=_getch();
        switch(g)
        {
        case 'q':if((yx-80)>=0)fieldYX[yx-=80]=s;break;
        case 'a':if((yx+80)<=49*80)fieldYX[yx+=80]=s;break;
        case 'o':if((yx-1)>=0&&(yx)%80!=0)fieldYX[--yx]=s;break;
        case 'p':if((yx+1)<=49*80&&(yx+1)%80!=0)fieldYX[++yx]=s;break;
        }
    }
    while(g!=27);
    delete hCon;
    return 0;
}
ESC-Выход
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 08:13  [ТС]     Как одномерный массив представить двумерным? #3
Не то. Вот что бы не пришлось писать такой код как у вас я и задумался, может как нибудь можно извратиться с указателями, что бы не приходилось каждый раз при обращении к массиву указывать width (в вашем случае 80).
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11818 / 6797 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
11.06.2014, 08:15     Как одномерный массив представить двумерным? #4
Можете выделить память под указатели и "настроить" каждый на свою "строку" пикселей
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
11.06.2014, 08:22     Как одномерный массив представить двумерным? #5
Цитата Сообщение от Pro_ha Посмотреть сообщение
Я загрузил изображение.
покажи как загрузил?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11818 / 6797 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
11.06.2014, 08:39     Как одномерный массив представить двумерным? #6
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
struct helper
{
   explicit helper ( int * p_ , int w_ , int h_ ) : p(p_) , w(w_) , h(h_) {
   }
   int operator()(int x, int y) {
      return p[y*w+x] ;
   }
private:
   int * p ;
   int w ;
   int h ;
} ;
 
int main()
{
   const int w = 3 ;
   const int h = 2 ;
   int pixels[w*h] = { 1 , 2 , 3 , 4 , 5 , 6 } ;
   helper arr( pixels , w , h ) ;
   for ( int i = 0 ; i < h ; ++i ) {
      for ( int j = 0 ; j < w ; ++j ) {
         std::cout << arr(j,i) << ' ' ;
      }
      std::cout << std::endl ;
   }
}
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 08:41  [ТС]     Как одномерный массив представить двумерным? #7
Цитата Сообщение от Croessmah Посмотреть сообщение
Можете выделить память под указатели и "настроить" каждый на свою "строку" пикселей
О, точно.

Цитата Сообщение от ValeryS Посмотреть сообщение
покажи как загрузил?
Загружаю с помощью готовых функций: http://lodev.org/lodepng/ (работает только с png).
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
11.06.2014, 08:55     Как одномерный массив представить двумерным? #8
Цитата Сообщение от Croessmah Посмотреть сообщение
int operator()(int x, int y) {
* * * return p[y*w+x] ;
* *}
если уж на то пошло, то неплохо бы и проверку сделать, на предмет выхода за пределы
Цитата Сообщение от Pro_ha Посмотреть сообщение
Загружаю с помощью готовых функций:
очень информативно
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11818 / 6797 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
11.06.2014, 09:01     Как одномерный массив представить двумерным? #9
Цитата Сообщение от ValeryS Посмотреть сообщение
если уж на то пошло, то неплохо бы и проверку сделать, на предмет выхода за пределы
зачем? Всё как в жизни - вышел за пределы - отвечай
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 09:16  [ТС]     Как одномерный массив представить двумерным? #10
Цитата Сообщение от Croessmah Посмотреть сообщение
struct helper
Через operator и структуру интересный вариант. Нечто похожее через макросы хотел делать. Но в обоих случаях идет лишнее умножение. Работая с большим объемом пикселей, не очень рационально. Хотя, может разницы и не будет.

Добавлено через 10 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
очень информативно
А что не ясно. По указанной ссылке скачиваешь и добавляешь в свой проект lodepng.cpp и lodepng.h.
И грузишь PNG рисунок с помощью функции lodepng::decode(...) Если надо более подробно - на той странице чуть ниже есть примеры использования.
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
11.06.2014, 09:26     Как одномерный массив представить двумерным? #11
Цитата Сообщение от Pro_ha Посмотреть сообщение
А что не ясно.
А все неясно
Цитата Сообщение от Pro_ha Посмотреть сообщение
По указанной ссылке скачиваешь и добавляешь в свой проект lodepng.cpp и lodepng.h.
это я должен сделать?
или все же покажешь как ты используешь функции, как объявляешь переменные, выделяешь память
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 10:52  [ТС]     Как одномерный массив представить двумерным? #12
Цитата Сообщение от ValeryS Посмотреть сообщение
это я должен сделать?
А, я думал ты интересуешься для себя, как загружать картинки. Но сейчас увидел твой рейтинг и понял, что хочешь помочь.

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

C++ (Qt)
1
2
3
4
5
6
7
std::vector<unsigned char> img;//сюда раскодируется картинка. (RGBA RGBA ...)
unsigned int img_w, img_h;//через эти переменные вернутся ширина и высота картинки.
if(!lodepng::decode(img, img_w, img_h, (unsigned char*)mem_image, mem_image_size)){//гружу из памяти.(но там  есть и перегруженная функция с вариантом загрузки из файла)
  DWORD *pixels= &img[0];
  DWORD color=pixels[5*img_w+2]; //pixels[2][5]
  std::vector<unsigned char>().swap(img);//освобождаем память вектора. Не обязательно, т.к. он в любом случае высвободится за границей видимости переменной.
}
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
11.06.2014, 11:54     Как одномерный массив представить двумерным? #13
Цитата Сообщение от Pro_ha Посмотреть сообщение
DWORD *pixels= &img[0];
почему DWORD???
если работаешь с виндой то есть COLORREF
что ты дальше делаешь с картинкой?
есть тупой вариант создать двумерный массив и скопировать в него
есть вариант по типу Croessmah, но без структуры
типа
C++
1
2
3
4
inline COLORREF getPixel(COLORREF * arr,int x,int y)
  {
    return arr[x+y*w];
  }
можно и со структурой(классом)но заинлайнить функцию

если боишься умножения то зря
в любом случае оно будет присутствовать
если объявишь массив так
C++
1
int  a[10][10];
то в памяти он будет лежать одномерным и обращения типа
C++
1
b=a[5][5];
на уровне ассемблера будут выглядеть так
b=*(a+(5+5*10));
единственно что если ширина кратна степени 2 то умножение могут заменится сдвигом
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 12:47  [ТС]     Как одномерный массив представить двумерным? #14
Там возвращается фиксированный формат 4 байта на пиксель. Но теперь знаю и про COLORREF. А нужно все для последюущего анализа пикселей.
Инлайновую функцию не хочу использовать т.к. где то читал, что это лишь пожелание компилятору. Он может и не зайинлайнить в некоторых случаях. Я пишу мелкие классы без CPP файлов. Сразу в H-ке расписываю тело функций. (меня парит по 2 раза писать название и параметры функции, и в случае их изменения следить чтоб они совпадали). А при таком "упрощенном" способе как раз и не работает инлайн. Хотя могу ошибаться. Давно дело было. Тему создал год назад. И только сейчас ответили.
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
11.06.2014, 13:37     Как одномерный массив представить двумерным? #15
Цитата Сообщение от Pro_ha Посмотреть сообщение
Там возвращается фиксированный формат 4 байта на пиксель. Но теперь знаю и про COLORREF.
нук COLORREF такой и есть
структура из 4 байтов
RGB и четвертый резервный
Цитата Сообщение от Pro_ha Посмотреть сообщение
что это лишь пожелание компилятору. Он может и не зайинлайнить в некоторых случаях.
Современные как раз инлайнят по своему желанию, даже если не попросишь
Цитата Сообщение от Pro_ha Посмотреть сообщение
А при таком "упрощенном" способе как раз и не работает инлайн.
точнее как раз работает
функция реализованная в описании класса становится inline
Цитата Сообщение от Pro_ha Посмотреть сообщение
Тему создал год назад
а на первое то сообщение я не посмотрел
Trwsdf
Заблокирован
11.06.2014, 14:05     Как одномерный массив представить двумерным? #16
Цитата Сообщение от Pro_ha Посмотреть сообщение
Как одномерный массив представить двумерным? / С++ для начинающих
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  const int COUNT = 9;
    int init[COUNT] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    //or matrix
    //    {1,2,3}    
    //    {4,5,6}
    //    {7,8,9}
    std::valarray<int> val(init, COUNT);
    //get sub matrix 
    //    {4,5}
    //    {7,8} 
    auto slice = gslice(3, std::valarray<size_t>(2, 2), std::valarray<size_t>({3, 1}));
    // set 0
    val[slice] = 0;
    //result
    for (int i = 0; i < COUNT; i++)cout << noskipws << val[i] << " ";
    //1 2 3 0 0 6 0 0 9
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
11.06.2014, 14:54     Как одномерный массив представить двумерным? #17
Цитата Сообщение от ValeryS Посмотреть сообщение
есть тупой вариант создать двумерный массив и скопировать в него
Был предложен и существенно более умный вариант - завести массив указателей на начала строк и адресоваться через него. Если кто-то предложит что-то эффективнее - с интересом выслушаю .
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
11.06.2014, 16:12     Как одномерный массив представить двумерным? #18
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
завести массив указателей на начала строк и адресоваться через него.
можно
но я никак не могу представить как это сделать
типа ?
C++
1
2
3
4
int arr[100];// исходный массив
int * pi[10];
for(int i=0;i<100;i+=10)
  pi=&arr[i];
а работать как?
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
11.06.2014, 17:00     Как одномерный массив представить двумерным? #19
Цитата Сообщение от ValeryS Посмотреть сообщение
а работать как?
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
#include <stdio.h>
#include <stdlib.h>
int main()
{
    unsigned char *img_data;
    unsigned char **img_data_rows;
    int row_n,rows,cols;
    FILE* out;
    rows = 32;
    cols =16;
    
    img_data = (unsigned char*)malloc(rows*cols);
    img_data_rows = (unsigned char **)malloc(rows*sizeof(unsigned char *));
    for(row_n=0;row_n<rows;row_n++)
    {
       img_data_rows[row_n] = img_data+row_n*cols;
    }
    
    for(row_n=0;row_n<rows;row_n++)
    {
       memset(img_data_rows[row_n],row_n,cols);
    }
    out = fopen("test.dat","wb");
    fwrite(img_data,rows*cols,1,out);
    fclose(out);
    return 0;
}
Адресуемся через массив строк как через двумерный.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.06.2014, 17:13     Как одномерный массив представить двумерным?
Еще ссылки по теме:

Как сложить массив чтоб получился одномерный массив? C++
C++ Одномерный массив, подскажите как вывести, как просит в задании
C++ Как представить многомерный массив в одномерный?

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

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
11.06.2014, 17:13     Как одномерный массив представить двумерным? #20
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Адресуемся через массив строк как через двумерный.
покаж
я пока увидел работу со всей строчкой
как например получить элемент 0,0 и сравнить его с 0,1?
Yandex
Объявления
11.06.2014, 17:13     Как одномерный массив представить двумерным?
Ответ Создать тему
Опции темы

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