Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | | | | | | |
Thx 08.04.02 21:55 Число просмотров: 876
Автор: Idkfa Статус: Незарегистрированный пользователь Отредактировано 08.04.02 22:04 Количество правок: 1
|
Век живи - век учись ;)
Облом, походу и здесь индексация привязывается к типу ....
+ Странный игнор индексов вообще .....
|
<programming>
|
[Pascal] [CPP] Описание типов\доступ к многомерным динамическим массивам 08.04.02 15:03
Автор: Idkfa Статус: Незарегистрированный пользователь
|
Что-то туплю.
Кто-нибудь знает нормальный способ создания subj-а?
Первое, что в голову пришло (сорсы см далее) глючит c размещением
значений в памяти.
[CPP]+ Есть соображения как сделать определение типа массива в typedef-е, а не трахаться с его определением в структуре.
[ Сорс на пасе ]
type
PTA = ^TA;
TA = array[1..1,1..1,1..2] of integer;
var
a : PTA;
i,j,k : integer;
begin
GetMem(a,SizeOf(TA)*3*3);
for i:=1 to 3 do
for j:=1 to 3 do
{ for k:=1 to 2 do}
begin
write('Enter a[',i,',',j,',',k,']:'); readln(a^[i][j][1]);
end;
writeln;
for i:=1 to 3 do
begin
for j:=1 to 3 do
{ for k:=1 to 2 do}
begin
write(' ',a^[i][j][1]);
end;
writeln;
end;
FreeMem(a,SizeOf(TA)*3*3);
end.
[ Вариант сорса на сях ]
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
typedef struct {
int m_data[1][1][1];
} ARR,*LPARR;
int main(int argc, char* argv[])
{
LPARR lpArr;
lpArr = (LPARR)malloc(sizeof(ARR)*3*3*3);
for ( int i=0 ; i < 3 ; i++ )
for ( int j=0 ; j< 3; j++)
{
printf("Enter A[%d][%d][1]",i,j);
scanf("%d",lpArr->m_data[i][i][1]);
}
for ( i=0 ; i < 3; i++ )
{
for ( int j=0 ; j < 3; j++)
printf(" %d",lpArr->m_data[i][j][1]);
printf("\n");
}
free(lpArr);
return 0;
}
|
|
А если new 09.04.02 01:33
Автор: Korsh <Мельников Михаил> Статус: Elderman
|
А если
int m = 3; // THE NUMBER OF ROWS.
int n = 5; // THE NUMBER OF COLUMNS.
long double **data;
data = new long double*[m]; // STEP 1: SET UP THE ROWS.
for (int j = 0; j < m; j++)
data[j] = new long double[n]; // STEP 2: SET UP THE COLUMNS
Стандартный пример Borlanda
|
| |
А если new 09.04.02 01:41
Автор: Biasha <Бяша> Статус: Member
|
> А если > int m = 3; // THE NUMBER OF > ROWS. > int n = 5; // THE NUMBER OF > COLUMNS. > > long double **data; > > data = new long double*[m]; // STEP 1: SET UP > THE ROWS. > for (int j = 0; j < m; j++) > data[j] = new long double[n]; // STEP 2: SET UP > THE COLUMNS > > Стандартный пример Borlanda Только недостаток - память лишняя (STEP 1) выделяется. Особенно это чувствоватся будет на большом количестве измрений.
|
|
Круто, сколько на С пишу - ничего не понял из твоего кода ;) 08.04.02 16:16
Автор: PS <PS> Статус: Elderman
|
а просто сделать никак нельзя ?
Ну например:
int** set; /*двумерный массив*/
int*** set; /*трехмерный массив*/
и т.д.
Но при такой штуке у тебя будет хорошая фрагментация памяти. Хотя кого она волнует ?
Я всегда пишу одномерный массив, а доступ как к двумерному делаю через индексы: y*Xlen+x.
|
| |
Круто, сколько на С пишу - ничего не понял из твоего кода ;) 08.04.02 16:41
Автор: Idkfa Статус: Незарегистрированный пользователь
|
насчет фрагментации - да , весело)
насчет арифметики указателей ,не всегда удобна,потом в сях ее заменяет[]
насчет своего вопроса - просто было интересно почему паскаль глючит на логически верных конструкциях адресации ...
> а просто сделать никак нельзя ? > Ну например: > > int** set; /*двумерный массив*/ > int*** set; /*трехмерный массив*/ > и т.д. > Но при такой штуке у тебя будет хорошая фрагментация > памяти. Хотя кого она волнует ? > Я всегда пишу одномерный массив, а доступ как к двумерному > делаю через индексы: y*Xlen+x.
|
|
[Pascal] Описание типов\доступ к многомерным динамическим массивам 08.04.02 15:37
Автор: Cyril <sc> Статус: Member
|
> Что-то туплю. > Кто-нибудь знает нормальный способ создания subj-а? > Первое, что в голову пришло (сорсы см далее) глючит c > размещением > значений в памяти. > [CPP]+ Есть соображения как сделать определение типа > массива в typedef-е, а не трахаться с его определением в > структуре. > > [ Сорс на пасе ] > type > PTA = ^TA; > TA = array[1..1,1..1,1..2] of integer;
TA = array[1..20,1..20,1..20] of integer;
================================
> var > a : PTA; > i,j,k : integer; > begin > GetMem(a,SizeOf(TA)*3*3);
GetMem(a,SizeOf(integer)*2*3*3);
============================
> for i:=1 to 3 do > for j:=1 to 3 do > { for k:=1 to 2 do} > begin > write('Enter a[',i,',',j,',',k,']:'); > readln(a^[i][j][1]); > end; > > writeln; > for i:=1 to 3 do > begin > for j:=1 to 3 do > { for k:=1 to 2 do} > begin > write(' ',a^[i][j][1]); > end; > writeln; > end; > > FreeMem(a,SizeOf(TA)*3*3);
FreeMem(a, SizeOf(integer)*2*3*3);
==============================
> end.
и все будет работать нормально
|
| |
[Pascal] Описание типов\доступ к многомерным динамическим массивам 08.04.02 15:51
Автор: Idkfa Статус: Незарегистрированный пользователь
|
Это не полноценное решение, я говорил о массивах с произвольной размерностью и о багах в их адресации ... в принципе!
> > Что-то туплю. > > Кто-нибудь знает нормальный способ создания subj-а? > > Первое, что в голову пришло (сорсы см далее) глючит c > > размещением > > значений в памяти. > > [CPP]+ Есть соображения как сделать определение типа > > массива в typedef-е, а не трахаться с его > определением в > > структуре. > > > > [ Сорс на пасе ] > > type > > PTA = ^TA; > > TA = array[1..1,1..1,1..2] of integer; > > TA = array[1..20,1..20,1..20] of integer; > ================================ > > > var > > a : PTA; > > i,j,k : integer; > > begin > > GetMem(a,SizeOf(TA)*3*3); > > GetMem(a,SizeOf(integer)*2*3*3); > ============================ > > for i:=1 to 3 do > > for j:=1 to 3 do > > { for k:=1 to 2 do} > > begin > > write('Enter a[',i,',',j,',',k,']:'); > > readln(a^[i][j][1]); > > end; > > > > writeln; > > for i:=1 to 3 do > > begin > > for j:=1 to 3 do > > { for k:=1 to 2 do} > > begin > > write(' ',a^[i][j][1]); > > end; > > writeln; > > end; > > > > FreeMem(a,SizeOf(TA)*3*3); > > FreeMem(a, SizeOf(integer)*2*3*3); > ============================== > > end. > > и все будет работать нормально
|
| | |
[Pascal] Чем не полноценное решение ??? 08.04.02 16:04
Автор: Cyril <sc> Статус: Member
|
> Это не полноценное решение, я говорил о массивах с > произвольной размерностью и о багах в их адресации ... в > принципе!
верхние границы индексов можно(и даже нужно) задавать любые лишь бы массив влезал в 64к
|
| | | |
[Pascal] Чем не полноценное решение ??? 08.04.02 16:35
Автор: Idkfa Статус: Незарегистрированный пользователь
|
;)
Насчет 64к - возьми, например, дельфи или TMT)
Вопрос был о том почему языковые конструкции глючат или где я не прав.
> > Это не полноценное решение, я говорил о массивах с > > произвольной размерностью и о багах в их адресации ... > в > > принципе! > > верхние границы индексов можно(и даже нужно) задавать любые > лишь бы массив влезал в 64к
|
| | | | |
[Pascal] С первым вариантом я был не прав, сорри ;-) 08.04.02 19:51
Автор: Cyril <sc> Статус: Member Отредактировано 08.04.02 20:18 Количество правок: 2
|
> ;) > Насчет 64к - возьми, например, дельфи или TMT) > Вопрос был о том почему языковые конструкции глючат или где > я не прав. > > > > Это не полноценное решение, я говорил о массивах > с > > > произвольной размерностью и о багах в их > адресации ... > > в > > > принципе! > > > > верхние границы индексов можно(и даже нужно) задавать > любые > > лишь бы массив влезал в 64к
Когда объявляешь массив
TArray = array [1..20, 1..20, 1..2] of integer,
а после выделяешь память под a : TArray
то вся индексная арифметика генерится на основе обявленного типа TArray
поэтому и тот вариант который я предлагал, и твой, - оба неверны
Предположим что массив объявлен сл. образом
TA = array[1..1,1..1] of byte
будем пользоваться формулой для расчета адреса addr = y*xlen+x
на основе объявления типа TA компилер расчитывает длину xlen=1,
тогда получаем следующие адреса:
x=1 y=1 addr=2
x=1 y=2 addr=3
x=2 y=1 addr=3
x=2 y=2 addr=4
Похоже, что отсюда вытекает следующий вывод: пользоваться встроенным индексированием для динамических массивов нельзя, как это не печально ;-(
|
| | | | | |
Thx 08.04.02 21:56
Автор: Idkfa Статус: Незарегистрированный пользователь
|
|
| | | | |
[Object Pascal] Multidimensional dynamic arrays 08.04.02 17:29
Автор: Cyril <sc> Статус: Member
|
Для Delphi можно написать и так
type
TMultiArray = array of array of array of integer;
var
A : TMultiArray;
begin
// Выделим память под массив (0..2, 0..2, 0..1)
SetLength(A, 3,3,2);
|
| | | | |
"Где я не прав" 08.04.02 16:47
Автор: PS <PS> Статус: Elderman
|
> Вопрос был о том почему языковые конструкции глючат или где > я не прав.
Языковые конструкции не глючат - аксиома :) (исключение - namespace в VC6)
Итак
struct S
{
int i[3];
}
и
struct S
{
int* i;
}
Отличаются тем, что в первом случае у тебя при создании структуры выделяется 12 байт, а во втором 4.
Т.е. можно написать даже так:
для первого случая:
struct S s;
int* tmp =(int*)&s;
tmp[1]...; то же самое что и s.i[1];
Для второго - такое не пройдет :)
А теперь давайте внимательно посмотрим на приведенный код... :)
|
| | | | | |
"Где я не прав" 08.04.02 17:03
Автор: Idkfa Статус: Незарегистрированный пользователь
|
;))
Я говорил не о
struct S
{
int i[3];
}
,а о
struct S
{
int i[1][1][1];
}
3 измерения разделяют один int (4 байта), конструкция сделана только для
обеспечения 'массивной' адресации ...
:Языковые конструкции не глючат - аксиома :) (исключение -
:namespace в VC6)
Протрассируй мой пример на пасе и посмотри как там рамещены значения массива)
А теперь давайте внимательно посмотрим на приведенный код... ;))
P.s. Вопрос был скорее по паскалю ...
> > Вопрос был о том почему языковые конструкции глючат > или где > > я не прав. > > Языковые конструкции не глючат - аксиома :) (исключение - > namespace в VC6) > > Итак > struct S > { > int i[3]; > } > > и > > struct S > { > int* i; > } > > Отличаются тем, что в первом случае у тебя при создании > структуры выделяется 12 байт, а во втором 4. > Т.е. можно написать даже так: > для первого случая: > struct S s; > int* tmp =(int*)&s; > tmp[1]...; то же самое что и s.i[1]; > Для второго - такое не пройдет :) > А теперь давайте внимательно посмотрим на приведенный > код... :)
|
| | | | | | |
Извини, по паскалю ничего не скажу, но (продолжение) 08.04.02 17:37
Автор: PS <PS> Статус: Elderman Отредактировано 08.04.02 18:30 Количество правок: 1
|
кажется я понял, что мне в твоем С коде не нравится:
typedef struct {
int m_data[1][1][1];
} ARR,*LPARR;
LPARR lpArr;
lpArr = (LPARR)malloc(sizeof(ARR)*3*3*3);
Ты создаешь не массив в структуре, а массив структур. Это немного разные вещи.
В принципе твой код можно переписать так:
typedef struct {
int m_data;
} ARR,*LPARR;
LPARR lpArr;
lpArr = (LPARR)malloc(sizeof(ARR)*3*3*3);
И это будет абсолютно то же самое.
Посмотри что у тебя получается:
#include <stdio.h>
#include <stdlib.h>
typedef struct S2
{
char i[1][1];
}SS2;
void main()
{
SS2* ss2 = (SS2*)malloc(sizeof(SS2*)*3*3);
printf("%ld\n", &(ss2->i[0][2]));
printf("%ld\n", &(ss2->i[2][0]));
}
Видимо ты ожидаешь, что ячейки памяти ss2->i[0][2] и ss2->i[2][0] у тебя будут разные ? А теперь запусти эту нехитрую програмку и убедишся в обратном.
|
| | | | | | | |
Thx 08.04.02 21:55
Автор: Idkfa Статус: Незарегистрированный пользователь Отредактировано 08.04.02 22:04 Количество правок: 1
|
Век живи - век учись ;)
Облом, походу и здесь индексация привязывается к типу ....
+ Странный игнор индексов вообще .....
|
|
|