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

 
 
4 страниц V  « < 2 3 4  
Reply to this topicStart new topic
> Двумерный массив и указатель на него, Как объявить чтобы можно было обращаться massiv[x][y]?
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  « < 2 3 4
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 06:19
Рейтинг@Mail.ru


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