Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
#1

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

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

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

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

Как представить многомерный массив в одномерный? - C++
Задана матрица размерностью h*w. Как представить многомерный массив в одномерный? Напишите пожалуйста программу для visual studio

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

Можно ли представить структуру как элемент массива, т е массив состоящий из однотипных структур - C++
Можно ли представить структуру как элемент массива, т е массив состоящий из однотипных структур

Двумерным массив - C++
Помогите разобраться, почему не работает? Вылетает с ошибкой: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFDFDFDFD.Указывает...

Как сложить массив чтоб получился одномерный массив? - C++
Например есть 3х мерный массив, как сложить его строки чтоб получился одномерный массив B (1 строка будет 1 элементом массива В). void...

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

23
fair7
9 / 9 / 0
Регистрация: 31.12.2010
Сообщений: 81
Записей в блоге: 1
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
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 08:13  [ТС] #3
Не то. Вот что бы не пришлось писать такой код как у вас я и задумался, может как нибудь можно извратиться с указателями, что бы не приходилось каждый раз при обращении к массиву указывать width (в вашем случае 80).
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
11.06.2014, 08:15 #4
Можете выделить память под указатели и "настроить" каждый на свою "строку" пикселей
1
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,231
11.06.2014, 08:22 #5
Цитата Сообщение от Pro_ha Посмотреть сообщение
Я загрузил изображение.
покажи как загрузил?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 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
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 08:41  [ТС] #7
Цитата Сообщение от Croessmah Посмотреть сообщение
Можете выделить память под указатели и "настроить" каждый на свою "строку" пикселей
О, точно.

Цитата Сообщение от ValeryS Посмотреть сообщение
покажи как загрузил?
Загружаю с помощью готовых функций: http://lodev.org/lodepng/ (работает только с png).
0
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,231
11.06.2014, 08:55 #8
Цитата Сообщение от Croessmah Посмотреть сообщение
int operator()(int x, int y) {
* * * return p[y*w+x] ;
* *}
если уж на то пошло, то неплохо бы и проверку сделать, на предмет выхода за пределы
Цитата Сообщение от Pro_ha Посмотреть сообщение
Загружаю с помощью готовых функций:
очень информативно
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
11.06.2014, 09:01 #9
Цитата Сообщение от ValeryS Посмотреть сообщение
если уж на то пошло, то неплохо бы и проверку сделать, на предмет выхода за пределы
зачем? Всё как в жизни - вышел за пределы - отвечай
0
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(...) Если надо более подробно - на той странице чуть ниже есть примеры использования.
0
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,231
11.06.2014, 09:26 #11
Цитата Сообщение от Pro_ha Посмотреть сообщение
А что не ясно.
А все неясно
Цитата Сообщение от Pro_ha Посмотреть сообщение
По указанной ссылке скачиваешь и добавляешь в свой проект lodepng.cpp и lodepng.h.
это я должен сделать?
или все же покажешь как ты используешь функции, как объявляешь переменные, выделяешь память
0
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);//освобождаем память вектора. Не обязательно, т.к. он в любом случае высвободится за границей видимости переменной.
}
0
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,231
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
Pro_ha
1 / 1 / 0
Регистрация: 07.06.2013
Сообщений: 32
11.06.2014, 12:47  [ТС] #14
Там возвращается фиксированный формат 4 байта на пиксель. Но теперь знаю и про COLORREF. А нужно все для последюущего анализа пикселей.
Инлайновую функцию не хочу использовать т.к. где то читал, что это лишь пожелание компилятору. Он может и не зайинлайнить в некоторых случаях. Я пишу мелкие классы без CPP файлов. Сразу в H-ке расписываю тело функций. (меня парит по 2 раза писать название и параметры функции, и в случае их изменения следить чтоб они совпадали). А при таком "упрощенном" способе как раз и не работает инлайн. Хотя могу ошибаться. Давно дело было. Тему создал год назад. И только сейчас ответили.
0
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,231
11.06.2014, 13:37 #15
Цитата Сообщение от Pro_ha Посмотреть сообщение
Там возвращается фиксированный формат 4 байта на пиксель. Но теперь знаю и про COLORREF.
нук COLORREF такой и есть
структура из 4 байтов
RGB и четвертый резервный
Цитата Сообщение от Pro_ha Посмотреть сообщение
что это лишь пожелание компилятору. Он может и не зайинлайнить в некоторых случаях.
Современные как раз инлайнят по своему желанию, даже если не попросишь
Цитата Сообщение от Pro_ha Посмотреть сообщение
А при таком "упрощенном" способе как раз и не работает инлайн.
точнее как раз работает
функция реализованная в описании класса становится inline
Цитата Сообщение от Pro_ha Посмотреть сообщение
Тему создал год назад
а на первое то сообщение я не посмотрел
0
11.06.2014, 13:37
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.06.2014, 13:37
Привет! Вот еще темы с ответами:

ассоциативный массив map c двумерным массивом - C++
Искал информацию в интернете но безрезультатно. Необходимо сделать ассоциативный массив с со строковым ключом и двумерным массивом 3х3 в...

Одномерный массив, подскажите как вывести, как просит в задании - C++
После ввода с клавиатуры произвольного одномерного массива целых чисел (в пределах знакового целого типа) вывести на экране нечетные из них...

Как возвратить одномерный массив - C++
Есть вопрос. Можно ли возвратить из одной функции в другую, ее вызвавшую, не просто одно значение, а массив значений через return? void...

Как перевернуть одномерный массив? - C++
#include &lt;iostream&gt;; using namespace std; int main() { const int n=3; int myArray={1,2,3}; for (int i=0; i&lt;n; i++){ ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.