Loading...

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

fristgerb avatar fristgerb 50 Точки

[Homework] C Pointers

Здравейте! :)

Това е моето домашно за C Pointers - всички задачи. Надявам се да ви е от полза: http://www.libtec.org/dev/softuni/09-pointers/

С Mercurial може да изтегляте всички мои домашни, примерно през терминал с комндата:

hg clone http://www.libtec.org/dev/softuni/
Тагове:
2
C Programming 27/10/2015 22:59:10
HPetrov avatar HPetrov 822 Точки

Малко след дъжд качулка но задачата ти с клиентите сравнението по баланс е грешно. Можеш да тестваш с различни стойности да видиш, че реално нищо не се сортира. Проблема идва от цялостното сравнение на long doubles. Ако просто ги проверяваш first > second ще си работи няма да има проблем. Но когато искаш да си сигурен, че единия е по-голям от другия даже от естеството на самия floating-point число ще трябва да измислиш друг начин. Например каквото ти върне fabs(first - second) ако е >= от esp то тогава да върнеш сравнението first > second вместо чисто 1

0
itonev avatar itonev 22 Точки

Всъщност  fristgerb  искаше ми се да изкоментирам нещо във връзка с твоя код.

Смятам, че пишеш качествен код.

Мисля, че си и по-добър от мен. 

Но наистина ми е чудно защо така инклудваш  "c"  файл ?

Инклудват се хедъри. Компилаторът сам ще си намери  "c"  файл-ът.

Та, ако може да ми обясниш каква е целта на тая практика ?

 

0
fristgerb avatar fristgerb 50 Точки

Извинявай, че малко се забавих с отговора.

Правя го така, защото иначе е излишен труд. :)

Така не пиша излишно декларациите на функциите по два пъти (.c и .h) и не трябва да ги синхронизирам файловете когато правя нови функции или редактирам стари.  Същевременно нямам никаква полза да е разделено на два файла.

Като цяло смятам, че в повечето случаи ползването на header файла и предеклариране на функции (прототипи) е безсмислено, вредно и не помага изобщо.  Губи се време в излишно писане и кодът става ненужно по-дълъг и по-трудено за разбиране.  Файловете също стават двойно повече от нужното.

В някои случаи наистина трябва да се правят тези неща, когато няма как иначе.  Примерно, когато имаш две функции, които се извикват помежду си, тогава е нужно да се предекларират тези функции.  Хедър файлове може да са нужни когато искаш част от програмата да се компилира отделно от друга, примерно за да ползваш различни настройки за комплиране за отделните части.

Някои хора разделят на .c и .h за да не компилират всичкия код едновременно, като оптимизация на компилирането, но при повечето програми нещата не се забързват значително и съответно няма полза от това.  От друга страна, като бонус, директно иклудването на .c файлове и компилирането на всичко като едно позволява на компилатора да inline-ва повече функциите, което оптимизира изпълняването на програмата.

Компилаторът сам ще си намери  "c"  файл-ът.

Компилаторът не намира автоматично .c файла.  Трябва да му казваш да компилира .c файла и да линква резултата към основната програма.

Инклудват се хедъри.

Мисля, че повечето хора препоръчват да се правят винаги .c и .h файлове, защото правят нещата наизуст, за да се презастраховат или просто защото "така се прави".  Но смятам, че е много по-разумно да се прави нещо само когато се виждаш, че има полза от него в конкретния случай.

Сходно ми е мнението и за освобождаването на заделена памет с (free()) преди края на програмата.  Абсолютна загуба на време, както за програмиста така и за процесора.  Хората го правят наизуст без никаква логика, просто защото "така се прави".  Освобождаването на памет трябва да се прави само когато конкретния случай го изисква.

1
03/11/2015 19:42:20
itonev avatar itonev 22 Точки

O, да коригирам се затова, че компилаторът си намирал сам файл. Малко си скъсих така мисълта, че чак я измених.  :) Сам ще си намери дефиницията на  функцията във "c"  файла  стига да му го укажеш, да. Иначе настрана от това, разбрах твоите аргументи относно инклудването

За free -ването си има доста логика. 

Щото случая е аналогичен като при викане на  exit();

Разбира се,  така няма да ти се валидира на  Valgrind

Но кои са според теб онези важни случаи на изрично викане на  free ?

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

1
fristgerb avatar fristgerb 50 Точки

Щото случая е аналогичен като при викане на exit();

Не разбирам какво имаш предвид.

Но кои са според теб онези важни случаи на изрично викане на free ?

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

Типично няма смисъл да викаш free в такава ситуация. Обикновено в една практическа програма, ако не успееш да malloc-неш или realloc-неш, единственото следващо нещо което може да направиш е да прекратиш програмата. Ако трябва да прекратиш, това означава, че няма смисъл да правиш free.

Случаите в които има смисъл от free общо взето стават ясни, когато се сблъскаш с тях, стига да разбираш какво се случва на ниво операционна система, когато правиш free, malloc и realloc.

Примерен случай когато може да ти трябва free е когато многократно заделяш (и използваш) много памет и има опасност да попречиш на системата и на другите програми да работят добре. Да кажем, ако заделяш и си използвал над 100 MB памет или нещо такова. Колкото точно е "много памет" зависи много от това каква програма правиш, колкото дълго ще работи тя и на какви системи ще работи.

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

Между другото, няма значение колко памет заделяш с malloc или подобни, а е важно единствено колко информация си записал върху заделената памет. Операционните системи са достатъчно умни. Може да си malloc-неш и цялата RAM ако искаш, но частта върху която не си записвал операционната система знае, че е свободна.

На уроците учим как да правим read_line() функция в която malloc-ваш и realloc-ваш многократно, така че да "пести" колкото може повече памет, но това е подвеждащо. Всъщност не се случва никакво пестене, а точно обратното - губи се процесорно време без да се пести памет. Ако си записвал само върху първите 64 байта в дадена памет, използваната памет си е все толкова, без значение дали си malloc-нал 1 GB или си malloc/realloc-нал така, че да е точно 64 байта.

Друг е въпросът, че Valgrind ще се оплаче, а на изпита ще те скъсат понеже не правиш излишните malloc, realloc и free повиквания. Това е бъг в типичното преподаване на C и C++, и той засяга включително и този курс.

1
03/11/2015 21:35:46
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.