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

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

10.06.2013, 13:22. Показов 3834. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Я загрузил изображение. И есть указатель на его однобайтные пиксели: BYTE *pixels;
Пиксель [5,8] считываю так: pixels[5*Width+8];
А как сделать, чтоб pixels[5,8] ?

Пробую через другой указатель:
BYTE *array[Width][Height]=pixels;
Компилятор ругается.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.06.2013, 13:22
Ответы с готовыми решениями:

Как представить многомерный массив в одномерный?
Задана матрица размерностью h*w. Как представить многомерный массив в одномерный? Напишите...

Как представить пятимерный массив?
"Одномерный массив можно представлять себе как строку данных, двумерный массив — как таблицу...

Как представить массив в привате
При создание класса там есть паблик и приват. Мне нужно как-то обозначить что массив в привате...

Представить строку как массив чисел
string a = "123"; Console.WriteLine(Convert.ToInt32(a)); Программа показывает: 123...

23
13 / 13 / 1
Регистрация: 31.12.2010
Сообщений: 131
Записей в блоге: 14
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-Выход
0
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 39
11.06.2014, 08:13  [ТС] 3
Не то. Вот что бы не пришлось писать такой код как у вас я и задумался, может как нибудь можно извратиться с указателями, что бы не приходилось каждый раз при обращении к массиву указывать width (в вашем случае 80).
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
11.06.2014, 08:15 4
Можете выделить память под указатели и "настроить" каждый на свою "строку" пикселей
1
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
11.06.2014, 08:22 5
Цитата Сообщение от Pro_ha Посмотреть сообщение
Я загрузил изображение.
покажи как загрузил?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 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 ;
   }
}
0
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 39
11.06.2014, 08:41  [ТС] 7
Цитата Сообщение от Croessmah Посмотреть сообщение
Можете выделить память под указатели и "настроить" каждый на свою "строку" пикселей
О, точно.

Цитата Сообщение от ValeryS Посмотреть сообщение
покажи как загрузил?
Загружаю с помощью готовых функций: http://lodev.org/lodepng/ (работает только с png).
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
11.06.2014, 08:55 8
Цитата Сообщение от Croessmah Посмотреть сообщение
int operator()(int x, int y) {
* * * return p[y*w+x] ;
* *}
если уж на то пошло, то неплохо бы и проверку сделать, на предмет выхода за пределы
Цитата Сообщение от Pro_ha Посмотреть сообщение
Загружаю с помощью готовых функций:
очень информативно
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
11.06.2014, 09:01 9
Цитата Сообщение от ValeryS Посмотреть сообщение
если уж на то пошло, то неплохо бы и проверку сделать, на предмет выхода за пределы
зачем? Всё как в жизни - вышел за пределы - отвечай
0
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 39
11.06.2014, 09:16  [ТС] 10
Цитата Сообщение от Croessmah Посмотреть сообщение
struct helper
Через operator и структуру интересный вариант. Нечто похожее через макросы хотел делать. Но в обоих случаях идет лишнее умножение. Работая с большим объемом пикселей, не очень рационально. Хотя, может разницы и не будет.

Добавлено через 10 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
очень информативно
А что не ясно. По указанной ссылке скачиваешь и добавляешь в свой проект lodepng.cpp и lodepng.h.
И грузишь PNG рисунок с помощью функции lodepng::decode(...) Если надо более подробно - на той странице чуть ниже есть примеры использования.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
11.06.2014, 09:26 11
Цитата Сообщение от Pro_ha Посмотреть сообщение
А что не ясно.
А все неясно
Цитата Сообщение от Pro_ha Посмотреть сообщение
По указанной ссылке скачиваешь и добавляешь в свой проект lodepng.cpp и lodepng.h.
это я должен сделать?
или все же покажешь как ты используешь функции, как объявляешь переменные, выделяешь память
0
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 39
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);//освобождаем память вектора. Не обязательно, т.к. он в любом случае высвободится за границей видимости переменной.
}
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
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 то умножение могут заменится сдвигом
1
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 39
11.06.2014, 12:47  [ТС] 14
Там возвращается фиксированный формат 4 байта на пиксель. Но теперь знаю и про COLORREF. А нужно все для последюущего анализа пикселей.
Инлайновую функцию не хочу использовать т.к. где то читал, что это лишь пожелание компилятору. Он может и не зайинлайнить в некоторых случаях. Я пишу мелкие классы без CPP файлов. Сразу в H-ке расписываю тело функций. (меня парит по 2 раза писать название и параметры функции, и в случае их изменения следить чтоб они совпадали). А при таком "упрощенном" способе как раз и не работает инлайн. Хотя могу ошибаться. Давно дело было. Тему создал год назад. И только сейчас ответили.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
11.06.2014, 13:37 15
Цитата Сообщение от Pro_ha Посмотреть сообщение
Там возвращается фиксированный формат 4 байта на пиксель. Но теперь знаю и про COLORREF.
нук COLORREF такой и есть
структура из 4 байтов
RGB и четвертый резервный
Цитата Сообщение от Pro_ha Посмотреть сообщение
что это лишь пожелание компилятору. Он может и не зайинлайнить в некоторых случаях.
Современные как раз инлайнят по своему желанию, даже если не попросишь
Цитата Сообщение от Pro_ha Посмотреть сообщение
А при таком "упрощенном" способе как раз и не работает инлайн.
точнее как раз работает
функция реализованная в описании класса становится inline
Цитата Сообщение от Pro_ha Посмотреть сообщение
Тему создал год назад
а на первое то сообщение я не посмотрел
0
Заблокирован
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
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
11.06.2014, 14:54 17
Цитата Сообщение от ValeryS Посмотреть сообщение
есть тупой вариант создать двумерный массив и скопировать в него
Был предложен и существенно более умный вариант - завести массив указателей на начала строк и адресоваться через него. Если кто-то предложит что-то эффективнее - с интересом выслушаю .
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
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];
а работать как?
0
327 / 230 / 55
Регистрация: 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;
}
Адресуемся через массив строк как через двумерный.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
11.06.2014, 17:13 20
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Адресуемся через массив строк как через двумерный.
покаж
я пока увидел работу со всей строчкой
как например получить элемент 0,0 и сравнить его с 0,1?
0
11.06.2014, 17:13
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.06.2014, 17:13
Помогаю со студенческими работами здесь

Представить трехмерный массив как двумерный
Дан массив АЖ 3 размерности, каждый срез его это матрица, 2х мерный массив. Нужно его преобразовать...

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

Как представить массив состоящий из дробей ?
и потом нужно максимальную дробь найти в этом массиве

Дан одномерный массив А, состоящий из N целых чисел. Переписать из него в одномерный массив В все нечетные числа
У меня есть задание: Дан одномерный массив А, состоящий из N целых чисел. Переписать из него в...


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

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