|
|
  |
Двумерный массив и указатель на него, Как объявить чтобы можно было обращаться massiv[x][y]? |
|
|
|
Jun 14 2009, 10:56
|
Местный
  
Группа: Свой
Сообщений: 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; }
|
|
|
|
|
Jun 14 2009, 11:11
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(Wano @ Jun 14 2009, 14:56)  как посоветовали, образно прикинул начала строк, присвоил их адреса к элементам массива указателей, в котором есть уже одна размерность. Что не так? Ясно что нужно ещё передавать размерность в функцию и грамотно расписать. Ну-ну, флаг в руки. Вы каждый раз будете переписывать свою функцию, если жизнь заставит чего-то в структуре ваших данных поменять? А если забудете подправить? А если подобных этой, функций в вашем проекте будет 10-100-... ? Себя, родного, не любите что-ли?
|
|
|
|
|
Jun 14 2009, 11:33
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jun 14 2009, 12:48
|
Местный
  
Группа: Свой
Сообщений: 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 *" вот и пошла фонтазия художника
|
|
|
|
|
Jun 14 2009, 14:20
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 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 *" вот и пошла фонтазия художника  Ну вот тут-то как раз &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-функции? А, объявление переменных где угодно...).
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jun 14 2009, 16:33
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jun 15 2009, 09:18
|
Гуру
     
Группа: Свой
Сообщений: 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]  Мдя. Вы к вашему исходному array тоже через *array[1][0] обращаетесь? И зачем надо было лепить лишние ' *' в описании void func(TypeD * temp), вы к исходному массиву тоже где то звездочки пририсовывали? Тип TypeD нужно использовать СТРОГО так же, как исходный массив - лишние звездочки будут изображать уже другие сущности
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|