Премини към съдържанието
Форумът в приложение

По-лесно сърфиране. Научи повече.

Kaldata.com - Форуми

Приложение на форума на цял екран с push известия, значки и други.

За да инсталирате това приложение на iOS и iPadOS
  1. Докоснете Иконата за споделяне в Safari
  2. Превъртете менюто и докоснете Добавяне към началния екран.
  3. Докоснете Добавяне в горния десен ъгъл.
За да инсталирате това приложение на Android
  1. Докоснете менюто с 3 точки (⋮) в горния десен ъгъл на браузъра.
  2. Докоснете Добавяне към началния екран или Инсталиране на приложение.
  3. Потвърдете, като докоснете Инсталиране.

Добре дошли!

Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

 

теоретичен въпрос относно масиви(или как да си го предствим в съзнанието)

Featured Replies

здравейте въпросът ми може да се окаже много глупав но предполагам че за много новобранци в програмирането тия неща са тъмна индия. И по темата имам си идея какво е двумерен масив (представям си го като матрица) да въведеш масив и да го изведеш е лесно

(for(i=0;i<n;i++)

for(i=0;i<n;i++)

{

cout<<i<<" "<<j<<" "; cin>>a[j];

}

for(i=0;i<n;i++)

for(i=0;i<n;i++)

{

cout<<i<<" "<<j<<" ">>a[j];

} )

обаче стигаме до момента в които с този масив трябва да се направи нещо понеже няма полза да си въвейдаме и извеждаме масиви.

примерно да изведем сбора на елементите на редовете и да ги въведем като елементи на масива b,

или да сравним елементите на масива а и да изведем най-голямата стоиност (или индекса на наи коглемия елемент),

или някаква друга задача (отворен съм за идеи).

лично аз стигам до моментите с въвеждането инициализацията на масива е ясна за да разчете елементите се използва пак функциите

for(i=0;i<n;i++)

for(i=0;i<n;i++)

и след това става някакво адско объркване. не изписвам код понеже незнам какъв за което се и извинявам но той е в основата на въпроса ми. Не моля да ми се реши задача  понеже така всеки може. молбата ми е ако някой може и му се занимава да обясни някакви подходи на работа на теория и с код кое от каде идва и защо става така. ясно ми е че въпроса е адски обемен но предполагам че много хора са се зблъсквали с тези проблеми.

Има достатъчно уроци в интернет примерно . Не знам за да видят дали внимавате или защото просто и те са хора даскалите правят умишлено или неволно грешки - като разбереш как се работи с масиви сам ще я/ги намериш в горния урок.

Редактирано от ined (преглед на промените)

Здравей,

 

Ти сам си го казал двумерният масив е нищо повече от една матрица. Като достъпваш до съответният елемент като използваш съответно индексите за ред и колона. За да обходиш масива ти трябва конструкция на два вложени цикъла, например с for. А пък в общият случай задачите с двумерен масив се свеждат до инициализация на масива, обхождане и извеждане на резултатите. Като при обхождането му, съответно достъпването на даден елемент и изпълнението на някакво условие е решението на задача. Например :

//Find the max element of matrixint maxElement = array[0][0]; //Initialize max element with first element of the matrixfor(int i = 0 ; i < rowCount ; i++) // Iteration of rows of the matrix  for(int j = 0 ; j < columnsCount; j++) // Iteration of columns of the matrix {    if(maxElement < array[i][j]) // If max element is less than current element    {       maxElement = array[i][j];    } }

Може би е добре, като допълнение към написаното от @ined да отбележим и как обаче един двумерен масив физически съществува в паметта. Тук е даден един частичен отговор на въпроса, като остава да се отбележи и какво всъщност е двойния (n- торния) указател към даден тип данна (т.е. какво е примерно int**). В случая, броя на '*' отбелязва броя на нивата на адресация (мисля, че това беше термина) на указваната памет.

Както знаем от програмирането, n* съдържа адрес към памет, която може да е както един - единствен елемент от съответния приложим тип, така и поредица от елементите, с адрес на първия елемент, записан като стойност в паметта на променливата n. 

 

Визуално това може да се интерпретира така:

TYPE* n -> |0xA1A3BF|  (Типа на данната в реферираната памет е TYPE)

 

                  |0x111112|    |0x212122|   |0x43AAC3|   (Типа на данните в тази памет е TYPE)

                  |0x111111|    |0x212121|   |0x43AAC2|   (Типа на данните в тази памет е TYPE)

                            ^                 ^                  ^

                            |                  |                   |

TYPE** n -> |0xA1A3BF | 0xA1A3C0 |  0xA1A3C1|    (Типа на данните в тази памет в TYPE* )

(Стойносттa на n е 0xA1A3BF )

(Стойността на записаната информация в памет с адрес 0xA1A3BF e 0x111111)

(Стойността на записаната информация в памет с адрес 0xA1A3C0 e 0x212121)

(Стойността на записаната информация в памет с адрес 0xA1A3C1 e 0x43AAC2)

В случая TYPE** n се чете "Указател към указател от тип TYPE". 

Т.е. всяка референция сочи към последователно заделена памет, в която имаме 1 или повече на брой данни от тип, който образно казано е с една '*' по - малко от типа, който го реферира. Т.е. : 

 

TYPE (k)* = {TYPE (k-1)*, TYPE (k-1)*, TYPE (k-1)*, ...};

 

Надявам се това да внесе повече разяснения, отколкото шум :).

 

Поздрави !

Редактирано от soundtracker (преглед на промените)

...

 soundtracker, да знаеш че всеки път когато някой спомене двоен указател, масив и урок в едно изречение, аз си представям краш. И според мен е много грешно да се представя многомерен масив като многократен указател. Защото НЕ Е така. двумерният масив от тип type НЕ Е двоен указател от тим type. Той е указател към "тип едномерен масив от тип type".

Много много заблуждаващо е да представяш нещата така. Хората си слагат след това знак за еквивалентност и почват да използват двойни указатели като двумерни масиви. Масивите носят информация на компилатора за броя елементи "зад" указателя. Чистите указатели НЕ.

Това го обяснявах преди много време накратко, тук.

 

Приемам забележката с едно малко "но" - в обясненията си в последния пост, говоря за "памет" - не конкретизирам директно масивите, защото както и ти спомена, не трябва да правим директен аналог между двете. Имат косвена връзка, но си имат и достатъчно разлики (както и отбеляза).  

 

двумерният масив от тип type НЕ Е двоен указател от тим type. Той е указател към "тип едномерен масив от тип type".

 

Т.е. всяка референция сочи към последователно заделена памет, в която имаме 1 или повече на брой данни от тип, който образно казано е с една '*' по - малко от типа, който го реферира. Т.е. : 

 

TYPE (k)* = {TYPE (k-1)*, TYPE (k-1)*, TYPE (k-1)*, ...};

Може би не съм се изразил, както ми се е искало, но идеята на примера и диаграмката ми беше именно тази, за която и ти споменаваш :)

 

Много много заблуждаващо е да представяш нещата така. Хората си слагат след това знак за еквивалентност и почват да използват двойни указатели като двумерни масиви.

Да, тук вече може би беше моя вина, че не разписах разликите. Двоен указател може да се използва, за да изгради структура, наподобяваща двумерен масив, но не и да създаде еквивалентна такава. Най-малко един истински двумерен масив ще е заделен в един непрекъснат блок от памет, докато при работа със указатели, имаме доста по - фрагментирано заделяне и рефериране (както се и вижда от примера в последния ми пост). 

 

Поздрави и отново благодаря за градивната критика !

Поздрави и отново благодаря за градивната критика !

Основната причина за намесата ми беше включването на многократните указатели. Тъй като те носят много малко информация (тоест никаква) за това дали зад тях стои един елемент, или сложна структура от елементи, не трябва самостоятелно да се ползват за описването и предаването на такава. Предпочитам нещо като клас или (структура + комплект функции за работа). А многократен указател - само когато трябва да се заделя/освобождава/променя "многократен-1" указател. Това е лично мое мнение, но особено много държа на него. Работата с указатели в C и C++ е изключително податлива на грешки и е хубаво да се пазиш колкото може повече.

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Разглеждащи това в момента 0

  • Няма регистрирани потребители разглеждащи тази страница.

Дарение

  • Подкрепи съществуването на форума - направи дарение
    32%
    Дарени 315 € от нужните 1 000 €

Бюлетин

Получавайте известие, когато има важна промяна или новина свързана с форума.

Профил

Навигация

Търсене

Търсене

Конфигуриране на push известия в браузъра

Chrome (Android)
  1. Докоснете иконата на катинар до адресната лента.
  2. Докоснете Разрешения → Известия.
  3. Променете предпочитанията си.
Chrome (Desktop)
  1. Кликнете върху иконата на катинар в адресната лента.
  2. Изберете Настройки на сайта.
  3. Намерете Известия и коригирайте предпочитанията си.