Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Структура с массивами внутри 
:(
    Опции темы
Rockie
Дата 21.10.2007, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: нет
Всего: 31



Здравствуйте! 

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

Код

       public struct Rect
        {
           public int [] xPoints  = new int[4]; 
           public int [] yPoints = new int[4];
        };

        Rect ABCD = new Rect();


Добавлено через 5 минут и 50 секунд
Пытаюсь создать конструктор - конструктор по ждефолту вроде запрещен.. при добавлении коснтруктора с параметром получаю следующую ошибку:
Цитата

Field 'GraphicalFunctions.Form1.Rect.yPoints' must be fully assigned before control leaves the constructor


Код

       public struct Rect
        {
           public int[] xPoints;
           public int[] yPoints;

           Rect(int a) 
           {
               int [] xPoints = new int[4];
               int [] yPoints = new int[4];
               xPoints[0] = xPoints[1] = xPoints[2] = xPoints[3] = 0;
               yPoints[0] = yPoints[1] = yPoints[2] = yPoints[3] = 0;
           }
        };



--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
thomas
Дата 22.10.2007, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доцент... почти
***


Профиль
Группа: Завсегдатай
Сообщений: 1385
Регистрация: 3.10.2006
Где: " Сказочное королевство"

Репутация: 6
Всего: 65



Rockie, 
Структуры это типы значений.
Потому как структуры являеются типами значений операция new с ними работает иначе, чем с классами. В частности, компилятор всегда генерирует конструктор по умолчанию БЕЗ ПАРАМЕТРОВ, который переопределить НЕВОЗМОЖНО.
Поэтому тебе сначала нужно инициировать твои массивы, а уже потом присваивать их твоей структуре.

Код

// обьявил структуру
public struct Rect
        {
           public int[] xPoints;
           public int[] yPoints;
        }
// инициируй массивы
int [] xPoints = new int[4];
int [] yPoints = new int[4];
xPoints[0] = xPoints[1] = xPoints[2] = xPoints[3] = 0;
yPoints[0] = yPoints[1] = yPoints[2] = yPoints[3] = 0;
// присвой значения структуре
Rect ABCD;


По моему так.
Или так
Код

ABCD.xPoints[0]=0;
ABCD.xPoints[1]=0;
...
ABCD.yPoints[0]=0;
...


Это сообщение отредактировал(а) thomas - 22.10.2007, 00:43


--------------------
Крепко жму горло, искренне ваш Thomas. (С)vingrad
Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну!
Проблемы негров шерифа не волнуют.
PM MAIL   Вверх
stab
Дата 22.10.2007, 01:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 7
Всего: 48



Код

public struct Rect
{
    public int[] xPoints;
    public int[] yPoints;

    public Rect(int a)
    {
        xPoints = new int[4]; // !!!
        yPoints = new int[4]; // !!!
        xPoints[0] = xPoints[1] = xPoints[2] = xPoints[3] = 0;
        yPoints[0] = yPoints[1] = yPoints[2] = yPoints[3] = 0;
    }
}



--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
1stain
Дата 22.10.2007, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 486
Регистрация: 30.7.2007
Где: Киев - Харьков

Репутация: 3
Всего: 40



с вашего позволения, вставлю свои 5коп.
когда ты пишешь так:
Код

        public class MyClass
        {
            public Int32[] Xarray = new Int32[4];
        }

,на самомо деле компилятор создает конструктор умолчанию, в котором создает массив элементов и инициализирует их значениями по умолчанию. А так как для структурных (Value) типов конструктор по умолчанию переопределять нельзя, то такая запись не прокатывает.
Кстате, исходя из этого "инициализирует их значениями по умолчанию", вот это
Код

        xPoints[0] = xPoints[1] = xPoints[2] = xPoints[3] = 0;
        yPoints[0] = yPoints[1] = yPoints[2] = yPoints[3] = 0;

абсолютно не имеет смысла


--------------------
Все знают, что это невозможно. Но вот приходит невежда, которому это неизвестно - он-то и делает открытие. (Albert Einstein)
user posted image
PM MAIL   Вверх
archeg
Дата 22.10.2007, 11:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

Репутация: 4
Всего: 27



Ну и я немного добавлю.... Пихать в структуры массивы - очень и очень плохая идея.
Структуры созданы для того чтобы увеличить производительность при малых объемах памяти. По-скольку массив - занимает не мало памяти его лучше пихать в класс - структура просто не играет никакой роли в таком случае

И есть еще одно но. Массивы в структуре вообще нельзя инициализировать. В том дело что в предыдущих примерах инициализация происходит в конструкторе (структуры требуют инициализацию всех полей в конструкторах), но с другой стороны структура может быть создана без ключего слова new - в таком случае конструктор просто не вызывается, а все поля инициализируются нулями - в данном случае null. Так что в таком случае вы просто не знаете, проинициализированы или нет поля структуры.

Впринципе в структуры лучше пихать только valuable-типы из-за этой проблемы

Это сообщение отредактировал(а) archeg - 22.10.2007, 11:38


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
Rockie
Дата 22.10.2007, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: нет
Всего: 31



Ну так как мне все же правильно сделать инициализацию? Мне нужно логически объеденить два массива, в структуру либо класс. Как это делается на C#?

Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public class Rect
    {
        public int[] xPoints;
        public int[] yPoints;

        public Rect()
        {
            // это кстати компилится
            this.xPoints = new int[4] {0,0,0,0};
            this.yPoints = new int[4] {0,0,0,0};

        }
    };
 
    public partial class Form1 : Form
    {
        public Rect ABCD = new Rect();

        // как сделать вот это:
        // ABCD.xPoints[0] = 5;

        public Form1()
        {
            InitializeComponent();
        }
    }
}



--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
Wanderer2019
Дата 22.10.2007, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 937
Регистрация: 3.12.2004
Где: Санкт-Петербург/П рага

Репутация: 2
Всего: 17



Собстно это

Цитата(Rockie @  22.10.2007,  13:04 Найти цитируемый пост)
        // как сделать вот это:
        // ABCD.xPoints[0] = 5;


должно работать.
PM ICQ MSN   Вверх
Rockie
Дата 22.10.2007, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: нет
Всего: 31



Цитата(Wanderer2019 @  22.10.2007,  16:37 Найти цитируемый пост)
должно работать.

Wanderer2019, ан не делает этого  smile 
Цитата

Error    1    Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)    
Error    2    Invalid token '=' in class, struct, or interface member declaration    

Студия MSVS 2005, .NET 2.0

Положим у меня есть код на С++. Каким образом он будет выглядеть применительно к C# (учитывая что в данном случае в C# не будем использовать указатели? 

Код
class TwoArrays{
public:
    // класс с двумя указателями на массивы
    int* pArray1, *pArray2;

    // cstr
    TwoArrays()
    {
        // выделяем память
        pArray1 = new int[4],
        pArray2 = new int[4];

        // инициализируем:
        for(int i=0;i<4;i++)
        {
            pArray1[i] = pArray2[i] = 0;
        }
    }

    // dstr
    ~TwoArrays()
    {
        // освобождаем память
        delete[] pArray1,
        delete[] pArray2;
    }
};


int main()
{
    // указатель на класс двух массивов,
            // выделили под него память
    TwoArrays* pTwoArrays = new TwoArrays();

    //работаю с массивами
    pTwoArrays->pArray1[0] = 3;
    pTwoArrays->pArray2[2] = 4;
    
            // очищаем память, delete вызывает деструктор
    delete pTwoArrays;

    return 0;
}



--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
tol05
Дата 22.10.2007, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



stab, 1stain, archeg уже ответили тебе.
Цитата(Rockie @  22.10.2007,  21:15 Найти цитируемый пост)
// класс с двумя указателями на массивы

по-моему (если я еще что-то помню), то даже в плюсах массив, указатель на массив и указатель на первый элемент массива - одно и тоже.
В шарпе - тем более. 

Деструктор для массива в шарпе не нужен (если конечно этот массив не содержит неуправляемые ресурсы smile ). Массивы собираются сборщиком мусора. Перечитай посты stab, 1stain, archeg про инициализацию элементов массива. Добавить к этому ничего не могу.

твой код будет выглядеть так:
Код

class TwoArrays{
    // класс с двумя массивами
    public int[] pArray1;
    public int[] pArray2;

    // cstr
    public TwoArrays()
    {
        // выделяем память
        pArray1 = new int[4];
        pArray2 = new int[4];
    }  
}
...
static int Main()
{
    //ссылка на класс двух массивов
    TwoArrays pTwoArrays = new TwoArrays();
    //работаю с массивами
    pTwoArrays.pArray1[0] = 3;
    pTwoArrays.pArray2[2] = 4;
    
    return 0;
}


Это сообщение отредактировал(а) tol05 - 22.10.2007, 21:55


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
stab
Дата 23.10.2007, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 7
Всего: 48



Rockie, расскажи зачем тебе эти массивы? как и для чего ты их собираешся использовать? может быть задача действительно требует структуры, а не класса..


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
1stain
Дата 23.10.2007, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 486
Регистрация: 30.7.2007
Где: Киев - Харьков

Репутация: 3
Всего: 40



Цитата(Rockie @  22.10.2007,  21:15 Найти цитируемый пост)
Студия MSVS 2005, .NET 2.0

да хоть в блокноте пиши, хоть в 2008-й студии. Компилятор тебе же ясно написал, что оператор присваивания нельзя использовать в теле класса, структуры или интерфейса вне функций. Засунь вот это 
Код

        ABCD.xPoints[0] = 5;

в конструктор формы после вызова Initialize() и будед тебе щасте.

з.ы. имхо начинать знакомство с языком стоит все-таки с консольных приложений


--------------------
Все знают, что это невозможно. Но вот приходит невежда, которому это неизвестно - он-то и делает открытие. (Albert Einstein)
user posted image
PM MAIL   Вверх
Rockie
Дата 23.10.2007, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: нет
Всего: 31



Цитата(tol05 @  22.10.2007,  21:50 Найти цитируемый пост)
уже ответили

Это так, но хотелось бы еще работающий код. Спасибо!


Цитата(tol05 @  22.10.2007,  21:50 Найти цитируемый пост)
по-моему (если я еще что-то помню), то даже в плюсах массив, указатель на массив и указатель на первый элемент массива - одно и тоже.В шарпе - тем более. 

[offtop]Ну, вообще-то нет: в С++ массив и указатель на первый элемент это не одно и то же(если речь об этом), хотя неявно массив приводится к указателю.[/offtop]

Спасибо кто помог разобраться! smile




--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
tol05
Дата 23.10.2007, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



Цитата(Rockie @  23.10.2007,  11:03 Найти цитируемый пост)
Ну, вообще-то нет: в С++ массив и указатель на первый элемент это не одно и то же(если речь об этом) 

я имел в виду что
Цитата

Любое выражение, имеющее тип массива, может быть преобразовано к указателю того же типа: результатом будет указатель на первый элемент массива.

Например:

char cStr[_MAX_PATH];     
  // Массив типа char
char *pStr = cStr;       
  // Указатель на массив:
  // эквивалентно выражению &cStr[0]
источник
и вот еще об этом же
и, еще
Цитата

In C, the standard states that wherever we might use &var_name[0] we can replace that with var_name, thus in our code where we wrote: 

    ptr = &my_array[0];

we can write: 

    ptr = my_array;

to achieve the same result. 

This leads many texts to state that the name of an array is a pointer. I prefer to mentally think "the name of the array is the address of first element in the array". Many beginners (including myself when I was learning) have a tendency to become confused by thinking of it as a pointer. For example, while we can write 

    ptr = my_array;

we cannot write 

    my_array = ptr;

The reason is that while ptr is a variable, my_array is a constant. That is, the location at which the first element of my_array will be stored cannot be changed once my_array[] has been declared. 

Earlier when discussing the term "lvalue" I cited K&R-2 where it stated: 

"An object is a named region of storage; an lvalue is an expression referring to an object". 
This raises an interesting problem. Since my_array is a named region of storage, why is my_array in the above assignment statement not an lvalue? To resolve this problem, some refer to my_array as an "unmodifiable lvalue". 

Modify the example program above by changing 

    ptr = &my_array[0];

to 

    ptr = my_array;

and run it again to verify the results are identical. 


источник
а ты что? smile 


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Wanderer2019
Дата 23.10.2007, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 937
Регистрация: 3.12.2004
Где: Санкт-Петербург/П рага

Репутация: 2
Всего: 17



Цитата(Wanderer2019 @  22.10.2007,  16:37 Найти цитируемый пост)
Собстно это

Цитата(Rockie @  22.10.2007,  13:04 Найти цитируемый пост)
        // как сделать вот это:
        // ABCD.xPoints[0] = 5;


должно работать.


Цитата(Rockie @  22.10.2007,  21:15 Найти цитируемый пост)
Wanderer2019, ан не делает этого  smile 


Подожди ка... но ведь я проверил.. все отработало.
PM ICQ MSN   Вверх
Rockie
Дата 23.10.2007, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: нет
Всего: 31



tol05, то, что и написал smile если приводить цитаты полностью, то будет примерно такой диалог:
Цитата(tol05 @  22.10.2007,  21:50 Найти цитируемый пост)
в плюсах массив, указатель на массив и указатель на первый элемент массива - одно и тоже.

Цитата(Rockie @  23.10.2007,  11:03 Найти цитируемый пост)
в С++ массив и указатель на первый элемент это не одно и то же(если речь об этом), хотя неявно массив приводится к указателю.

Цитата(tol05 @  23.10.2007,  11:16 Найти цитируемый пост)
я имел в виду что

Цитата(tol05 @  23.10.2007,  11:16 Найти цитируемый пост)
Любое выражение, имеющее тип массива, может быть преобразовано к указателю того же типа




--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1481 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.