реклама на сайте
подробности

 
 
> Двумерный массив и указатель на него, Как объявить чтобы можно было обращаться massiv[x][y]?
mempfis_
сообщение Jun 9 2009, 12:23
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Добрый день.

Чтото не могу понять как правильно объявить указатель на двумерный массив чтобы компилятор не ругался.

Есть такой массив:
Код
[b]unsigned int [/b] [i]__flash[/i] Program1[5][4] =
{
  {0,0,0,0},
  {1,1,1,1},
  {2,2,2,2},
  {3,3,3,3},
  {4,4,4,4}
}


И есть некая структура управления в которой хочу создать указатель на этот двумерный массив:
Код
typedef struct
{
unsigned int __flash **program;//указатель на текущую исполняемую программу
} stProgram;

stProgram Program; //экземпляр структуры


Стоит задача сделать так чтобы используя указатель Program.program обращаться к двумерному массиву
наиболее понятным образом Program.program[0][1] (без использования * и всяких смещений)

Определил функцию инициализации масива
Код
void SetProgram(unsigned int __flash **program_addr)
{
   Program.program = program_addr;
}



Компилятор ругается на вызов этой функции:
Код
SetProgram(&Program1[0][0]);


Цитата
Error[Pe167]: argument of type "unsigned int __flash (*)[4]" is incompatible with parameter of type "unsigned int __flash **"
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 55)
777777
сообщение Jun 9 2009, 12:33
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(mempfis_ @ Jun 9 2009, 16:23) *
unsigned int __flash **program;//указатель на текущую исполняемую программу

**program - это указатель ня ячейку памяти, в которой хранится другой указатель. Двумерные массивы так не передают.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 9 2009, 12:43
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(mempfis_ @ Jun 9 2009, 15:23) *
Чтото не могу понять как правильно объявить указатель на двумерный массив....

Многомерный массив ничем не отличается от 'простого', а указателю все едино на что указывать....


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 9 2009, 12:56
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Хорошо предположим я объявлю функцию с указателем на нулевой элемент массива

Код
typedef struct
{
unsigned int __flash *program;//указатель на текущую исполняемую программу
} stProgram;

stProgram Program; //экземпляр структуры
void SetProgram(unsigned int __flash *program_addr)
{
   Program.program = program_addr;
}


Как наиболее просто обращаться к элементам массива через Program.program[0][1] а не *(Program.program*0+1) ?
Для наглядности и простоты понимания программы хочу сделать обращение именно таким образом.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 9 2009, 13:03
Сообщение #5


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(mempfis_ @ Jun 9 2009, 16:56) *
Как наиболее просто обращаться к элементам массива через Program.program[0][1] а не *(Program.program*0+1) ?

Так прямо так и обращаться.
Program.program[0][1] = ...


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 9 2009, 13:23
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата
Так прямо так и обращаться.
Program.program[0][1] = ...


Так не хочет. На строчку
Код
Program.size = Program.program[Program.step_index][size_id]
компилятор выдаёт ошибку:

Цитата
Error[Pe142]: expression must have pointer-to-object type



А строчку
Код
Program.size = *(Program.program+4*Program.step_index+size_id)
воспринимает нормально.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 9 2009, 13:27
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(mempfis_ @ Jun 9 2009, 16:23) *
компилятор выдаёт ошибку:

Естественно. Вы-же УКАЗАТЕЛЬ передали. Вот он Вам черным по белому и пишет.
Program->program[][]


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Jun 9 2009, 13:35
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581



А чего бы в таком виде не сделать:
Код
value_from_array=array_access(Program.program,x,y);

Все довольно прозрачно...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 9 2009, 13:46
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(Goodefine @ Jun 9 2009, 16:35) *
А чего бы в таком виде не сделать:
Код
value_from_array=array_access(Program.program,x,y);

Все довольно прозрачно...


Это отдельная фукция которую не хотелось-бы вводить (да и нет смысла её вводить если можно достучаться через *(......)).
К сожалению через -> тоже не работает.
Приду домой почитаю в книге как это можно сделать (жаль на работе её нет, так хотелось до конца рабочего дня разобраться с этим вопросом).
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Jun 9 2009, 13:50
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581



Цитата(mempfis_ @ Jun 9 2009, 16:46) *
да и нет смысла её вводить если можно достучаться через *(......)).
К сожалению через -> тоже не работает.

У меня подозрение, что достучаться как
Код
Program->program[x][y]

Вы сможете на плюсах. В обычном Си компиляторе это не проходит...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 9 2009, 13:58
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Код
Вы сможете на плюсах. В обычном Си компиляторе это не проходит...

Всегда в настройках проекта ставлю Embedded C++.
Компилятор IAR 5.10
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 9 2009, 14:23
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(mempfis_ @ Jun 9 2009, 16:46) *
К сожалению через -> тоже не работает.

Глупости. Вы пишите, что попало и получаете какие попало ошибки.
Код
typedef struct {
int dm[8][8];
} dm_t;

dm_t  mm;

int test( dm_t *dm_ptr )
{
   return( dm_ptr->dm[3][3] );
}


void xmain(void)
{
     test( &mm );
}

И не рассказывайте о том, что компилятор чего-то не понял.


Цитата(Goodefine @ Jun 9 2009, 16:50) *
У меня подозрение, что достучаться как
Код
Program->program[x][y]

Вы сможете на плюсах. В обычном Си компиляторе это не проходит...

Ой! Рассажите об этом Ритчи....


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 9 2009, 14:29
Сообщение #13


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(mempfis_ @ Jun 9 2009, 16:23) *
Так не хочет. На строчку
Код
Program.size = Program.program[Program.step_index][size_id]
компилятор выдаёт ошибку:
Может для такого пользования (где есть некий size_id, и думаю еще какие-то другие id)
выгоднее применить массив структур вместо многомерного массива?
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Jun 9 2009, 14:34
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581



Цитата(zltigo @ Jun 9 2009, 17:23) *
Глупости. Вы пишите, что попало и получаете какие попало ошибки.
Код
typedef struct {
int dm[8][8];
} dm_t;

Ой! Рассажите об этом Ритчи....

А теперь добавьте волшебное слово __flash
Код
typedef struct {
int  __flash dm[8][8];
} dm_t;

и Ритчи расскажет Вам:
Цитата
Error: ... storage modifier not allowed in this context


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 9 2009, 14:39
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Goodefine @ Jun 9 2009, 17:34) *
и Ричи скажет вам:

Ну-ка двайте сюда место, где про __flash у Ритчи говорится smile.gif. А заодно расскажите как там Страутструп разруливает эту проблему smile.gif smile.gif. Ну а лучше почитайте документацию на компилятор, как и для чего __flash пользоваться.
Код
typedef __flash struct {
int dm[8][8];
} dm_t;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Jun 9 2009, 14:42
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581



Я к тому, что решение проблемы автора при обращении к флешевой памяти Вы не показали...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 9 2009, 14:58
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Goodefine @ Jun 9 2009, 17:42) *
Я к тому, что решение проблемы автора при обращении к флешевой памяти Вы не показали...

Проблемы Автора я не вижу, ну если не считаить проблемой попытку беспорядочного нагромождения всяких выражений. Если Вам удалось понять, в чем проблема - сформулируйте. То, что Автор назвал проблемой
Цитата
Двумерный массив и указатель на него, Как объявить чтобы можно было обращаться massiv[x][y]

Передача указателя на двухмерный массив и работа с ним определяется исключительно возможностями языка не зависит от использования дополнительных атрибутов памяти. Как работать с указателем в таком случае - пример приведен. Дополнительные атрибуты - по вкусу и в соответствии хотя-бы со здравым смыслом.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 9 2009, 15:59
Сообщение #18


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Вопрошающему: посторайтесь понять это и Вы найдёте ответ на свой вопрос...
Код
int *pointers[10]    - это массив указателей
int (*pointer)[10] - это переменная типа указатель на массив из десяти интов
double (*sum(double,double))[3] - функция sum возвращает указатель на массив из 3 даблов


to defunct: первые два совершенно разные типы. Вот пример их использования:
Код
pointers[0] = NULL;
*pointer[0] = 10;


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 9 2009, 16:19
Сообщение #19


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Уважаемый коллега zltigo привел пример не совсем того, про что спрашивал автор топика. Он ведь хотел иметь внутри структуры указатель на двумерный массив.

Посему, привожу изменненный вариант:

Код
typedef struct {
int (*pdm)[8];
} dm_t;

int dm[8][8];

int test(dm_t *dm_ptr)
{
   printf("size pdm = %d\n", sizeof(dm_ptr->pdm));
   return(dm_ptr->pdm[3][3] );
}

dm_t  mm;
int main(int argc, char *argv[])
{
     int i = 8;
     dm[3][3] = 5;
     mm.pdm = &dm[8];
     i = test(&mm);
     printf("i = %d\n", i);
     return 1;
}
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 9 2009, 16:31
Сообщение #20


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Простите, но зачем городить структуру? Автор спрашивал как объявить указатель на массив, если он конечно именно этого хочет...
Тогда путь только один:
объявите свой тип - указатель на двумерный массив из[5][4] элементов
Код
typedef int (*pointer_to_array_5_4_t)[5][4];

И используйте его по прямому назначению! И даже делайте его членом структуры.
Код
int array[5][4] = {{0}};
pointer_to_array_5_4_t ptr = &array;
*ptr[0][0] = 33;
Когда что-либо трудно понять/написать всегда на помощь приходит typedef...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 9 2009, 16:58
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(demiurg_spb @ Jun 9 2009, 19:31) *
Автор спрашивал как объявить указатель на массив, если он конечно именно этого хочет...

да-да... если...
Автор еще с flash тыкался, а указатель во флэшевой структуре на флэшевый массив ... мне как-то непонятно, зачем нужен.
Пора уже не автору народ экзаменовать, а нам его. Пусть скажет словами, чего хочет biggrin.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 9 2009, 17:26
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Jun 9 2009, 19:31) *
Простите, но зачем городить структуру?

Если это вопрос ко мне, то, потому, что Автор городил структуру, я полагал, что посеченная до вырожденого варианта структура приведена Автором для примера. Тем паче, что в обрывках приведенных текстов встречается поминание и других элементов некой структуры.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 9 2009, 18:09
Сообщение #23


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Dog Pawlowa @ Jun 9 2009, 20:58) *
... указатель во флэшевой структуре на флэшевый массив ... мне как-то непонятно, зачем нужен.
Очень даже нужен. Например структуры для меню. Массивы из указателей на структуры тоже логично держать в ПЗУ. У меня так реализовано, так что задачки могут быть очень и очень разными и интереснымиsmile.gif
To zltigo: да вопрос был к Вам. Я понял что Вы имели ввиду...

Цитата(Dog Pawlowa @ Jun 9 2009, 20:58) *
Пусть скажет словами, чего хочет biggrin.gif
Да этого точно не хватает.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 9 2009, 18:32
Сообщение #24


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(demiurg_spb @ Jun 9 2009, 18:59) *
to defunct: первые два совершенно разные типы. Вот пример их использования:
Код
pointers[0] = NULL;
*pointer[0] = 10;

Да как говорится что-то в глаз попало написал фигню, которую сразу же и удалил. (у Вас быстрая реакция smile.gif )
Конечно же это абсолютно два разных типа.

Пример использования правда не очень очевиден, т.к. нам ничто не мешает сделать:
*pointers[ 0 ] = 10;
*pointer[ 0 ] = 10;

Вот так будет более наглядно -

sizeof ( pointers ) != sizeof( pointer )
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 9 2009, 19:31
Сообщение #25


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(defunct @ Jun 9 2009, 22:32) *
нам ничто не мешает сделать:
*pointers[ 0 ] = 10;
*pointer[ 0 ] = 10;
Да, но смысл уже будет другой. Я привёл пример доступа к элементу массива с индексом 0 в обоих случаях.
А пример с sizeof тоже весьма показателен.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 9 2009, 21:23
Сообщение #26


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(demiurg_spb @ Jun 9 2009, 22:31) *
Да, но смысл уже будет другой. Я привёл пример доступа к элементу массива с индексом 0 в обоих случаях.

вот потому пример и неочевиден.
К элементу массива я например привык обращаться как arr[x]; а не как *arr[ x];

Цитата
А пример с sizeof тоже весьма показателен.

угу, сразу видно что
sizeof( pointer ) == sizeof( PVOID)
sizeof(pointers ) == 10 * sizeof( PVOID)
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 10 2009, 08:36
Сообщение #27


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



name=' date='Jun 9 2009, 19:19' post='604857'

Спасибо sergeeff, ваш вариант именно то что я хотел получить.
Переделал его на свой лад. Получилось то что написано ниже.

Код
#define max_size 5
unsigned int __flash Program1[max_size][4]=
{
   {1,1,1,1},
   {2,2,2,2},
   {3,3,3,3}
};

//массив второй программы из 5ти действий
unsigned int __flash Program2[max_size][4]=
{
   {7,7,7,7},
   {8,8,8,8},
   {9,9,9,9},
   {11,11,11,11},
   {44,44,44,44}
};

//структура управления программой
typedef struct {
unsigned int __flash (*program)[max_size];
} stProgram;

stProgram Program;

//процедура инициализации структуры управления
void SetProgram(unsigned int __flash (*addr)[])
{
  Program.program = addr;
}


void main(void)
{
//настройка программы
SetProgram(&Program1[0]);

//основной цикл программы
for(;;);
}


Теперь можно обращаться к элементам программы через указатель Program.program просто переберая индексы
Program.program[1][0], Program.program[2][1] и т.д.

Но есть ньюансы.
Во-первых размер возможных программ всегда должен быть максимальный (max_size).
Во-вторых код компилируется только в режиме С.
В режиме Embedded C++ выскакивает ошибка на процедуру инициализации программы
Код
void SetProgram(unsigned int __flash (*addr)[])
Error[Pe615]: parameter type involves pointer to array of unknown bound
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 10 2009, 09:16
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(mempfis_ @ Jun 10 2009, 11:36) *
Переделал его на свой лад.

Еще раз пройтись и поубирать, например, круглые скобки неведомо зачем напиханные и почитать, как в С++ (а не C ) осуществляется передача параметров по ссылке и значению.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 10 2009, 09:19
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(mempfis_ @ Jun 10 2009, 11:36) *
Но есть ньюансы.
Во-первых размер возможных программ всегда должен быть максимальный (max_size).

А о ньюансах говорилось? smile.gif

1) Если программа - это набор переменного количества наборов данных, то и организовывать данные целесообразно в соответствии с иерархией.
То есть array[4] - это один набор данных, а программа будет содержать массив указателей на эти наборы. Тогда эти наборы и повторяться могут, т.е. экономия места.

2) Можно кодировать последний набор данных в программе. Тогда все наборы расположить в линейный массив, а программа будет описываться указателем на первого набора данных этой программы в полном массиве наборов(или индексом в массиве). Тут экономия сложности smile.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
XVR
сообщение Jun 10 2009, 09:34
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Открою великую тайну rolleyes.gif - как сделать из массива (любого) тип, который можно будет написать в параметрах функции (например).
Берем исходное определение переменной -
Код
unsigned int __flash Program1[5][4] = {...}

Меняем имя переменной на тип, удаляем = и всё после него и пишем typedef вначале, все
Код
typedef unsigned int __flash ProgramType[5][4];

Используем
Код
void func(ProgramType my_var) {...}
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 10 2009, 10:23
Сообщение #31


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(mempfis_ @ Jun 10 2009, 11:36) *
Во-первых размер возможных программ всегда должен быть максимальный (max_size).
Во-вторых код компилируется только в режиме С.

И первое и второе неверно.
Код
#include <iostream>

unsigned int Program1[][4]=
{
   {1,1,1,1},
   {2,2,2,2},
   {3,3,3,3}
};

unsigned int Program2[][4]=
{
   {7,7,7,7},
   {8,8,8,8},
   {9,9,9,9},
   {11,11,11,11},
   {44,44,44,44}
};


void foo( const char *header, unsigned int pgm[][4], int size)
{
    std::cout << "======== " << header << "[" << size << "]" << std::endl;
    for( int i=0; i < size; ++i)
        std::cout << pgm[i][0] << ", " << pgm[i][1] << ", " << pgm[i][2] << ", " << pgm[i][3] << std::endl;
    std::cout << std::endl;
}

#define CALL_FOO(array) foo( #array, array, sizeof(array) / sizeof(array[0]) )

int main()
{
    CALL_FOO(Program1);
    CALL_FOO(Program2);
}

Код
gcc -Os -s foo.cpp -o foo.exe
foo.exe >foo.txt

Код
======== Program1[3]
1, 1, 1, 1
2, 2, 2, 2
3, 3, 3, 3

======== Program2[5]
7, 7, 7, 7
8, 8, 8, 8
9, 9, 9, 9
11, 11, 11, 11
44, 44, 44, 44


В смысле размер может быть переменным, но его надо или отдельно передать, или ограничить признаком, скажем, в реальной программе не бывает отрицательных чисел, тогда так
Код
unsigned int Program2[][4]=
{
   {7,7,7,7},
   {8,8,8,8},
   {9,9,9,9},
   {11,11,11,11},
   {44,44,44,44},
   {-1,-1,-1,-1}  // ограничитель и в цикле идти до него, а не по счётчику
};


Кстати, прототип функции С/С++ воспринимают как
Код
void foo(const char*, unsigned int (*)[4], int)

т.е. как функцию, принимающую указатель на 4-интовые массивы.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Wano
сообщение Jun 13 2009, 21:13
Сообщение #32


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



ЫЫЫЫЫ чего-то не катит

typedef char TypeD[5][5];

char array[5][5];

void func(TypeD * temp){
*temp[1][0]=5;//лезет не в &array+5 ,а в &array+25
}

int main (void)
{
func(&array);
return 0;
}

В disassembly видно что забит сдвиг от начала массива не на пять байт ,а на 25. Всё щастье пашет только на диапазоне *temp[0][0]....*temp[0][4] sad.gif
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 13 2009, 21:21
Сообщение #33


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Wano @ Jun 14 2009, 03:13) *
ЫЫЫЫЫ чего-то не катит

typedef char TypeD[5][5];


Потому что надо вот так:
typedef char[5][5] TypeD;


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 13 2009, 23:07
Сообщение #34


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Wano @ Jun 14 2009, 00:13) *
ЫЫЫЫЫ чего-то не катит

typedef char TypeD[5][5];

char array[5][5];

void func(TypeD * temp){
...
В disassembly видно что забит сдвиг от начала массива не на пять байт ,а на 25. Всё щастье пашет только на диапазоне *temp[0][0]....*temp[0][4] sad.gif
Естественно.
temp объявлен как указатель на массив char[5][5]
Соответственно temp[1] - это следующий такой массив (temp[1] есть массив char[5][5]), temp[1][0] - первый его подмассив, *temp[1][0], рассматриваемый как *(temp[1][0]) (приоритеты операций в С желательно выучить до начала программирования) - это нулевой элемент данного подмассива.
То, чего Вы хотите, можно достичь двумя способами
Код
typedef char TypeD[5][5];

void func_1(TypeD *temp){
    (*temp)[1][0]=5;
}

void func_2(TypeD temp){
    temp[1][0]=5;
}

Код
    .text
.global    func_1
    .type    func_1, @function
func_1:
/* prologue: frame size=0 */
/* prologue end (size=0) */
    ldi r18,lo8(5)
    movw r30,r24
    std Z+5,r18
/* epilogue: frame size=0 */
    ret
/* epilogue end (size=1) */
/* function func_1 size 4 (3) */
    .size    func_1, .-func_1

.global    func_2
    .type    func_2, @function
func_2:
/* prologue: frame size=0 */
/* prologue end (size=0) */
    ldi r18,lo8(5)
    movw r30,r24
    std Z+5,r18
/* epilogue: frame size=0 */
    ret
/* epilogue end (size=1) */
/* function func_2 size 4 (3) */
причём в первом я не вижу никакого смысла.

Ну а как бы я делал это (точнее, как я уже это делал) - я изобразил в предыдущем своём сообщении.

Кстати, С99 позволяет вообще так:
Код
void func( unsigned size_y, unsigned size_x, char array[size_y][size_x] )
{
    array[2][1] = 'a';
}

Код
    .text
.global    func
    .type    func, @function
func:
/* prologue: frame size=0 */
/* prologue end (size=0) */
    movw r30,r22
    lsl r30
    rol r31
    add r30,r20
    adc r31,r21
    ldi r24,lo8(97)
    std Z+1,r24
/* epilogue: frame size=0 */
    ret
/* epilogue end (size=1) */
/* function func size 8 (7) */
    .size    func, .-func

Только, хоть и прошло уже десять лет, не все компиляторы поддерживают все возможности С99.


И ещё вдогонку.

Массивов в языке С... Ну не так, чтобы нету совсем, но и что есть сказать тяжело.

Есть указатели и развитая арифметика с ними. Есть некий "макрос" из квадратных скобок, который облегчает запись этой арифметики. Именно поэтому функции в "можно достичь двумя способами" выше имеют тождественный код и хоть и должны вызывться по разному на уровне исходника
Код
void func_3()
{
    func_1( &array);
    func_2( array);
}
но код вызова тоже тождественный
Код
.global    func_3
    .type    func_3, @function
func_3:
/* prologue: frame size=0 */
    push r16
    push r17
/* prologue end (size=2) */
    ldi r16,lo8(array)
    ldi r17,hi8(array)
    movw r24,r16
    rcall func_1
    movw r24,r16
    rcall func_2
/* epilogue: frame size=0 */
    pop r17
    pop r16
    ret
/* epilogue end (size=3) */
/* function func_3 size 11 (6) */
    .size    func_3, .-func_3


Более того (специально сделал элемент массива двухбайтовым, чтобі біло чётко видно, что множится на два всегда "истинный" индекс, даже если он стоит перед скобками):
Код
unsigned a[5];

unsigned func_1(unsigned char i)
{
    return a[i];
}

unsigned func_2(unsigned char i)
{
    return i[a];
}

Код
.global    func_1
    .type    func_1, @function
func_1:
    mov r30,r24
    ldi r31,lo8(0)
    lsl r30
    rol r31
    subi r30,lo8(-(a))
    sbci r31,hi8(-(a))
    ld r24,Z
    ldd r25,Z+1
    ret

.global    func_2
    .type    func_2, @function
func_2:
    mov r30,r24
    ldi r31,lo8(0)
    lsl r30
    rol r31
    subi r30,lo8(-(a))
    sbci r31,hi8(-(a))
    ld r24,Z
    ldd r25,Z+1
    ret

в полном соответствии со стандартом (цитата из C89, в C99 аналогично)
Обратите внимание - "одно из выражений ... другое ..." а не "первое выражение ... второе ...".
Цитата
3.3.2.1 Array subscripting
Constraints

One of the expressions shall have type ``pointer to object type ,'' the other expression shall have integral type, and the result has type `` type .''

Semantics

A postfix expression followed by an expression in square brackets [] is a subscripted designation of a member of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*(E1+(E2))) . Because of the conversion rules that apply to the
binary + operator, if E1 is an array object (equivalently, a pointer to the initial member of an array object) and E2 is an integer, E1[E2] designates the E2 -th member of E1 (counting from zero).
Ну а если E1 - интегральный тип а E2 массив (или, что эквивалентно, указатель на его первый элемент), то тогда это будет E1-тый элемент массива E2.

Так что берите на вооружение это и не ограничивайте себя тем, что все массивы должны иметь одинаковую длину. Всё равно в функцию реально передаётся указатель на первый элемент массива - даже когда Вы думаете, что передаёте массив.

А вот ещё из стандарта С++, чтобы окончательно запутать развеять сомнения.
Цитата
When several ”array of” specifications are adjacent, a multidimensional array is created; the constant expressions that specify the bounds of the arrays can be omitted only for the first member of the sequence. [Note: this elision is useful for function parameters of array types, and when the array is external and the definition, which allocates storage, is given elsewhere. ] The first constant-expression can also be omitted when the declarator is followed by an initializer (8.5). In this case the bound is calculated from the number of initial elements (say, N) supplied (8.5.1), and the type of the identifier of D is ”array of N T.”

Except where it has been declared for a class (13.5.5), the subscript operator [] is interpreted in such a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th member of E1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation.


p.s. выделения везде мои


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Wano
сообщение Jun 13 2009, 23:44
Сообщение #35


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Код
void func( unsigned size_y, unsigned size_x, char array[size_y][size_x] )
{
    array[2][1] = 'a';
}


в RealView как то не очень прошло,если только size_y не забить статично.

вообще не трогая указатели и typedef пашет и

Код
char array[5][5];

void func(char temp[5][5]){
    temp[1][0]=5;
}

int main (void)
{        
    func(array);
  return 0;
}

Просто массив может быть разной размерности как и способ расчёт их определителя(матрицы), а раз верхний пример не катит, дабы не зацикливаться как на размерности массив так и на размере элементов в функцию кидаю адрес первого элемента :

Код
char array[5][5];

void func(char *temp,char x,char y){
    temp[1*x+1]=5;//[1][1]
}

int main (void)
{        
    func(&array[0][0],5,5);
  return 0;
}

Но никак не получается красивая конструкция типа temp[1][1] . Собственно если отбросить красоту,как помимо (начало+1*x+1) может произойти обращение с помощью скобок к элементам двумерного массива? Конструкция [][] скрывает тот же расчёт, и вроде даже сложнее.Смотрел на:

Код
char array[5][5];
char i=2,j=1;//позиция

void func(char *temp,char x,char y){//x,y размерность    
    temp[i*x+j]=5;
}

int main (void)
{            
    func(&array[0][0],5,5);
    array[i][j]=15;
  return 0;
}
Причина редактирования: Оформление цитат исходников.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 00:16
Сообщение #36


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Да, блин! Все рассказали, объяснили, примеры привели. Ан нет. По новой дискуссия разворачивается. Чего вы хотите добиться, никак в толк не возьму? Не очень изящно на С получается, перейдите на С++, сделайте себе объект - n-мерный массив (примеров - полно), и передавайте в вашу функцию хоть указатель, хоть ссылку. Причем есть очень хорошие примеры, когда обращение к конкретным элементам массива можно выполнить даже без операции умножения.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 03:07
Сообщение #37


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(XVR @ Jun 10 2009, 12:34) *
Открою великую тайну rolleyes.gif - как сделать из массива (любого) тип, который можно будет написать в параметрах функции (например).

еще проще - написать по вкусу PVOID или PCHAR


Цитата(sergeeff @ Jun 14 2009, 03:16) *
Не очень изящно на С получается, перейдите на С++, сделайте себе объект - n-мерный массив (примеров - полно),

Не будет изящной реализации на любом языке, когда выбран КРИВОЙ алгоритм решения задачи изначально.

описать действия можно и в одномерном массиве, причем прекрасно читаемо:

Код
int Program_1[] =
{
    /* step1 */  1, 1, 1, 1, 1, 1, 1, 0,
    /* step2 */  2, 2, 2, 0,
    /* step3 */  3, 3, 3, 3, 3, 0,
    /* step4 */  4, 4, 4, 4, 4, 0,
    /* step5 */  5, 5, 0,
    /* end */ 0
};

int Program_2[] =
{
    /* step1 */  11, 11, 11, 0,
    /* step2 */  44, 44, 44, 44, 0,
    /* end */ 0
};


int *Programs[] =
{
   Program_1,
   Program_2
   ...
};
;

где каждый "step" может быть любой длины и отделен от остальных 0-терминатором. конец программы - step начинающийся с терминатора.
далее пишем функцию для поиска очередного "step'a":

Код
int *FindStep( int *program, int StepId )
{
     if (!*program)
        return NULL;

     while (StepId)
     {
         if (!*program++)
            if (!*program)
               return NULL;
            else
               StepId--;
     }
    return program;
}


Ну а потом уже и DoProgram c DoStep'ом

Код
DoStep( int *step)
{
    while( *step )
    {
        ... // делаем что надо
        step++
    }
}

DoProgram( int *program)
{
     do
     {
           DoStep( program )
     } while ( program = FindStep( program, 1 ) );
}


работаем с этим как:

DoProgram( Programs[ x ] );
Go to the top of the page
 
+Quote Post
Wano
сообщение Jun 14 2009, 09:16
Сообщение #38


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



не рычите люди. С тем, что через void* можно бросить указатель в функцию хоть слона это ясно, искать маркер конца строк массива тоже ясно(один чёрт оно и так всё в ряд). Дайте ответ на вопрос:
Можно ли элементарно преобразовать указатель чего угодно, переданный в функцию, к виду [][] , а не работать со сдвигами? Зная размерность. И не трогать при это с++.
С чего угодно малость загнул, хотябы разобраться с char.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 09:39
Сообщение #39


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Wano @ Jun 14 2009, 12:16) *
...Дайте ответ на вопрос:
Можно ли элементарно преобразовать указатель чего угодно, переданный в функцию, к виду [][] , а не работать со сдвигами? Зная размерность. И не трогать при это с++. ...

Сдвиги то откуда взялись?
И вообще - Вам шашечки (двумерный массив) или ехать (управление по программе).
Если все-таки ехать, то defunct все подробно описал, когда я поленился.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Wano
сообщение Jun 14 2009, 10:04
Сообщение #40


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Конкретней : получаем в функции указатель:
void func(void *temp)
создаём указатель на нужный объект, char :
char * c_Uk;
связываем:
c_Uk= (char *)temp;
Вопрос: почему, если :
*(c_Uk+2)=5;
и
c_Uk[2]=5;
синонимы, то не проходят коснтрукции типа
c_Uk[1][1]=5;
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 10:08
Сообщение #41


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Не хочет народ читать книги отцов-основателей.
Для двумерных массивов в С необходимо всегда знать максимальный размер второго индекса, иначе невозможно адресовать конкретный элемент массива. Если вы преобразуете указатель на двумерный массив к обычному указателю, то там, как вы догадываетесь, никакой информации о размерностях нет. Именно поэтому, при передаче в функцию указателя на двумерный массив, приходится явно указать размер старшего индекса. Или же вы должны в функцию передать абстрактный указатель, и максимальные значения обеих размеров. Или использовать C++ объект, информация о размерах которого хранится в нем самом.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 14 2009, 10:12
Сообщение #42


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Wano @ Jun 14 2009, 16:04) *
Вопрос: почему, если :
*(c_Uk+2)=5;
и
c_Uk[2]=5;
синонимы, то не проходят коснтрукции типа
c_Uk[1][1]=5;


Потому что неизвестна первая размерность массива.
Можно вот так:
Код
typedef char TMatrix5[][5];

TMatrix5 m5_1 =
{
    {1,2,3,4,5},
    {11,12,13,14,15},
    {21,22,23,24,25},
    {31,32,33,34,35},
};

char * chars = "12345678901234567890";

void test2(void * pv)
{
    TMatrix5 * m5 = pv;
    (*m5)[1][2] = 3;
}

int main(void)
{
    test2(chars);
}


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 14 2009, 10:16
Сообщение #43


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Wano @ Jun 14 2009, 13:04) *
то не проходят коснтрукции типа
c_Uk[1][1]=5;
Потому что c_Uk - указатель, из которого можно получить лишь одномерный массив. Вы не сообщили компилятору размер строки, а хотите от него получить адрес по формуле: номер строки * размер строки + номер столбца. Попробуйте сами написать формулу, которую компилятор должен подставить для вычисления адреса элемента c_Uk[1][1]. Если вы хотите обращаться с c_Uk как с двумерным массивом, то и объявляйте его как указатель на двумерный массив. Но при этом вам надо отдавать себе отчет, что правила языка С89 требуют, чтобы одно из измерений такого массива было фиксировано на этапе компиляции. Если вам надо внутри функции работать с массивом, в котором оба измерения неизвестны на этапе компиляции - вам прямой путь или в С99 (как показал ReAl), или в адресную арифметику. Т.е. сначала вручную находите адрес нужной вам строки, потом с этой строкой можете работать как с одномерным массивом или как с указателем.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 10:31
Сообщение #44


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(AHTOXA @ Jun 14 2009, 14:12) *
Потому что неизвестна первая размерность массива.


Не первого, а второго (если вы не считаете с нулевого, конечно)
Go to the top of the page
 
+Quote Post
Wano
сообщение Jun 14 2009, 10:34
Сообщение #45


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Цитата(Сергей Борщ @ Jun 14 2009, 13:16) *
Т.е. сначала вручную находите адрес нужной вам строки, потом с этой строкой можете работать как с одномерным массивом или как с указателем.


void func(void *temp){//для массива 5х5
char * c_Uk[20];
c_Uk[0]= (char *)temp;
c_Uk[1]= c_Uk[0]+5;
c_Uk[2]= c_Uk[1]+5;
c_Uk[3]= c_Uk[2]+5;
c_Uk[4]= c_Uk[3]+5;

c_Uk[2][2]=5;
}

если забить на лишние указатели,то не плохо. Всем спасибо.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 10:51
Сообщение #46


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Wano @ Jun 14 2009, 14:34) *
если забить на лишние указатели,то не плохо. Всем спасибо.


Жуть, что вы тут понаписали.
Go to the top of the page
 
+Quote Post
Wano
сообщение Jun 14 2009, 10:56
Сообщение #47


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Цитата(sergeeff @ Jun 14 2009, 13:51) *
Жуть, что вы тут понаписали.


как посоветовали, образно прикинул начала строк, присвоил их адреса к элементам массива указателей, в котором есть уже одна размерность. Что не так? Ясно что нужно ещё передавать размерность в функцию и грамотно расписать.

char array[5][5];

void func(void *temp,char x,char y){
char * c_Uk[20];//заранее больше одной размерности
char i;
c_Uk[0]= (char *)temp;
for(i=1;i<y;i++){
c_Uk[i]=c_Uk[i-1]+x;
}
c_Uk[1][2]=5;
}

int main (void)
{
func(&array[0][0],5,5);
return 0;
}
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 11:11
Сообщение #48


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Wano @ Jun 14 2009, 14:56) *
как посоветовали, образно прикинул начала строк, присвоил их адреса к элементам массива указателей, в котором есть уже одна размерность. Что не так? Ясно что нужно ещё передавать размерность в функцию и грамотно расписать.



Ну-ну, флаг в руки. Вы каждый раз будете переписывать свою функцию, если жизнь заставит чего-то в структуре ваших данных поменять?
А если забудете подправить? А если подобных этой, функций в вашем проекте будет 10-100-... ? Себя, родного, не любите что-ли?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 14 2009, 11:33
Сообщение #49


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Wano @ Jun 14 2009, 13:56) *
как посоветовали, образно прикинул начала строк, присвоил их адреса к элементам массива указателей, в котором есть уже одна размерность. Что не так?
Мама!!! "Не так" - реализация. Я не понял, что должна делать ваша функция, поэтому в качестве примера просто прохожу по всему массиву и присваиваю элементам константу 1:
Код
#include <stdint.h>
uint8_t array[5][5];  // у вас ведь массив не символов а именно беззнаковых 8-битных чисел

void func(uint8_t *temp, uint8_t x, uint8_t y) // temp именно указатель на uint8_t, а ни в коем случае не на на void, чтобы случайно не передать в функцию чего попало. Тип, на который указывает temp определяет размер элемента массива и этот размер дальше учитывается в адресной арифметике.
{
    uint8_t *c_Uk;    // размерность неизвестна, поэтому просто указатель
    
    uint8_t i;
    for(i = 0; i < y; ++i) // перебор строк массива
    {
        c_Uk = &temp[i * x];       // находим в линейном массиве temp адрес, с которого начинается i-я строка размером x.
        // c_Uk = temp + i * x;    // то же самое другими словами
        
                                    // теперь c_Uk указывает на строку двумерного массива
        uint8_t j;
        for(j = 0; j < x; ++j)     // проходим по строке
        {
            c_Uk[j] = 1;
        }
    }
    
    
    // "Дембельский" аккорд
    
    c_Uk = &temp[2 * x];       // вторая строка
    c_UK[1] = 5;               // первый элемент в строке. т.е. массив[1][2] = 5
}

int main (void)
{
    func(array                 // имя массива есть указатель на его нулевой элемент. Поэтому & и [0][0] не нужны.
         ,sizeof(array[0]) / sizeof(array[0][0])    // размерность x
         ,sizeof(array) / sizeof(array[0])          // размерность y
        );  
    return 0;
}
А книжку все же почитайте. Как только поймете, что такое указатель - сразу все станет просто.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Wano
сообщение Jun 14 2009, 12:48
Сообщение #50


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Ладно шариться по массиву можно хорошо и так:
void func(char *temp,char x,char y){
int i,j;
for(i=0;i<y;i++)//по столбцам
for(j=0;j<x;j++){//по строкам
*(temp+i*y+j)=1;
}
}
и ещё кучей способов.
мне хотелось именно квадратные скобки, дабы повысить наглядность коэффициентов при расчёте определителей матрицы. Определитель матрицы 5х5 , выполненный сначало на индексах - и начинает рябить.И чем больше, тем труднее ошибку в индексе найти.
А огород из void , & и [0][0] начал городить из-за того, что

uint8_t array[5][5];

void func(uint8_t *temp, uint8_t x, uint8_t y){.......}

func(array ,sizeof(array[0]) / sizeof(array[0][0]),sizeof(array) / sizeof(array[0]));

вызывает ошибку компилера RV:
main.c(28): error: #167: argument of type "char (*)[5]" is incompatible with parameter of type "char *"
вот и пошла фонтазия художника smile.gif
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 14 2009, 14:20
Сообщение #51


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Wano @ Jun 14 2009, 15:48) *
uint8_t array[5][5];

void func(uint8_t *temp, uint8_t x, uint8_t y){.......}

func(array ,sizeof(array[0]) / sizeof(array[0][0]),sizeof(array) / sizeof(array[0]));

вызывает ошибку компилера RV:
main.c(28): error: #167: argument of type "char (*)[5]" is incompatible with parameter of type "char *"
вот и пошла фонтазия художника smile.gif
Ну вот тут-то как раз &array[0][0] было бы полезным - чтобы на соответствие типов не ругался.
Имя массива - это указатель на его первый (в смысле с нулевым индексом) элемент, но первым элементом для array будет array[0] - певый подмассив из 5 элементов в массиве array[5][5] (да, в языке С двумерных массивов [index,index] тоже "не очень есть", а есть массивы массивов).

А указывать как параметр первый подмассив array[0], чтобы передался адрес первого элемента этого подмассива...
Тут конфликта типов не будет, но это нечитаемо. Так что если имя массива не катит, то тогда - как и было изначально, &array[0][0].

По поводу func( int sy, int sx, int array[sy][sx]), введённом в С99 - может компилятору надо отдельно включить C99 каким-то ключиком? А то сюда ну просто очень просится.
Или он не умеет С99? Или умеет, но не весь? (а что тогда остаётся - //-комментарии да inline-функции? А, объявление переменных где угодно...).


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 16:07
Сообщение #52


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ReAl @ Jun 14 2009, 18:20) *
По поводу func( int sy, int sx, int array[sy][sx]), введённом в С99 - может компилятору надо отдельно включить C99 каким-то ключиком? А то сюда ну просто очень просится.
Или он не умеет С99? Или умеет, но не весь? (а что тогда остаётся - //-комментарии да inline-функции? А, объявление переменных где угодно...).

Умеет, но весьма избирательно. И переменные объявлять где попало нельзя sad.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 14 2009, 16:33
Сообщение #53


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Wano @ Jun 14 2009, 15:48) *
мне хотелось именно квадратные скобки, дабы повысить наглядность коэффициентов при расчёте определителей матрицы. Определитель матрицы 5х5 , выполненный сначало на индексах - и начинает рябить.
Если размерность массива неизвестна на этапе компиляции - то только С99 или плюсы. В С89 с квадратными скобками - невозможно. Вам это пытаются объяснить уже 4 страницы. Если размерность известна - то можно и в С89, но тогда нафига ее (размерность) передавать в качестве парметров в функцию?
Цитата(Wano @ Jun 14 2009, 15:48) *
вызывает ошибку компилера RV:
Да, тут я фигню спопрол. ReAl уже поправил.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
XVR
сообщение Jun 15 2009, 09:18
Сообщение #54


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(Wano @ Jun 14 2009, 01:13) *
ЫЫЫЫЫ чего-то не катит

typedef char TypeD[5][5];

char array[5][5];

void func(TypeD * temp){
*temp[1][0]=5;//лезет не в &array+5 ,а в &array+25
}

int main (void)
{
func(&array);
return 0;
}

В disassembly видно что забит сдвиг от начала массива не на пять байт ,а на 25. Всё щастье пашет только на диапазоне *temp[0][0]....*temp[0][4] sad.gif
Мдя. Вы к вашему исходному array тоже через *array[1][0] обращаетесь? И зачем надо было лепить лишние '*' в описании void func(TypeD * temp), вы к исходному массиву тоже где то звездочки пририсовывали? Тип TypeD нужно использовать СТРОГО так же, как исходный массив - лишние звездочки будут изображать уже другие сущности
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 15 2009, 09:24
Сообщение #55


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(XVR @ Jun 15 2009, 12:18) *
Мдя. Вы к вашему исходному array тоже через *array[1][0] обращаетесь? И зачем надо было лепить лишние '*' в описании void func(TypeD * temp), вы к исходному массиву тоже где то звездочки пририсовывали? Тип TypeD нужно использовать СТРОГО так же, как исходный массив - лишние звездочки будут изображать уже другие сущности


Затем, что человек хочет передать в функцию указатель на массив (что правильно), а не копию всего массива.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 15 2009, 09:54
Сообщение #56


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(sergeeff @ Jun 15 2009, 15:24) *
Затем, что человек хочет передать в функцию указатель на массив (что правильно), а не копию всего массива.


Массивы в Си передаются всегда как указатель на первый элемент smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 11th August 2025 - 06:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.02152 секунд с 7
ELECTRONIX ©2004-2016