# Επιπρόσθετα > Software Η/Υ >  >  Μεταβλητές σε βιβλιοθήκη C

## picdev

Έχω μια ερώτηση για τις βιβλιοθήκες στη C, σε μια πρώτη ματιά φένεται "εύκολο" αλλά όταν ανοίγω έτοιμες βιβλιοθήκες δεν καταλαβαίνω τι γίνεται αλλά πάμε στα απλά.

Σε μία βιβλιοθήκη έχουμε 2 αρχεία το .h και το .c

Στο .h γράφουμε τις συναρτήσεις που θα χρησιμοποιήσουμε και είναι ορατές στο κύριο πρόγραμμα μας.

Με τις μεταβλητές και τα define τι γίνεται? τα γράφουμε μόνο στο .h? τα γράφουμε μόνο στο .c? και στα 2? 
θα φαίνονται στο κύριο πρόγραμμα ?

----------


## SeAfasia

akis εννοείς(εκτός την main.c) τις delay.h και delay.c;

----------


## picdev

αναφέρομαι σε βιβλιοθήκη που θέλω να φτιάξω εγώ,

----------


## bolsevikos

Φίλε Ακη,
Η βιβλιοθήκες στη C είναι συλλογές από αρχεία επικεφαλίδες  που περιέχουν τα χαρακτηριστικά των συναρτήσεων της συγκεκριμένης  βιβλιοθήκης και αρχεία συναρτήσεων που περιέχουν αυτές καθεαυτές τις  συναρτήσεις 
Στον κώδικά σου ορίζεις ποιες βιβλιοθήκες χρειάζεσαι  ώστε να αξιοποιήσεις τις αντίστοιχες συναρτήσεις στο κύριο προγραμμά  σου. πχ #INCLUDE <stdio.h>
Εχωντας ορίσει τις βιβλιοθήκες  μπορείς να καλέσεις τις συναρτήσεις στο κύριο προγραμμά σου. Στο  συγκεκριμένο παράδειγμα με την stdio.h περιέχετιαι η συνάρτηση printf  την οποία καλείς για να δώσεις έξοδο στην οθόνη.

πχ
main ()
{printf ("Hello ilektronika.gr");
}

Τις  μεταβλητές και τις σταθερές σου (βλέπε DEFINE) τις ορίζεις στον κωδικά  σου μέσα ή εξω από την main ανάλογα με το πως θέλεις να τις  χρησιμοποιήσεις.
Αλλά αυτό αστο σε δευτερο στάδιο.
Ξεκίνα προσπαθώντας να πάρεις μια έξοδο για αρχή και σιγά σιγά θα γίνονται όλα περισσότερο κατανοητά.
Αν κατάλαβα λάθος και θέλεις να δημιουργήσεις δικές σου βιβλιοθήκες ρίξε μια ματιά εδώ http://www.it.uom.gr/teaching/c_sys/node36.html

Ελπίζω να βοήθησα για αρχή.

----------


## bolsevikos

> Φίλε Ακη,
> Η βιβλιοθήκες στη C είναι συλλογές από αρχεία επικεφαλίδες  που περιέχουν τα χαρακτηριστικά των συναρτήσεων της συγκεκριμένης  βιβλιοθήκης και αρχεία συναρτήσεων που περιέχουν αυτές καθεαυτές τις  συναρτήσεις 
> Στον κώδικά σου ορίζεις ποιες βιβλιοθήκες χρειάζεσαι  ώστε να αξιοποιήσεις τις αντίστοιχες συναρτήσεις στο κύριο προγραμμά  σου. πχ #INCLUDE <stdio.h>
> Εχωντας ορίσει τις βιβλιοθήκες  μπορείς να καλέσεις τις συναρτήσεις στο κύριο προγραμμά σου. Στο  συγκεκριμένο παράδειγμα με την stdio.h περιέχετιαι η συνάρτηση printf  την οποία καλείς για να δώσεις έξοδο στην οθόνη.
> 
> πχ
> main ()
> {printf ("Hello ilektronika.gr");
> }
> ...



Μάλλον γράφαμε μαζί...οπότε προχώρα κατευθείαν στο link. :p

----------


## picdev

ξέρω για την ορατότητα των μεταβλητών , έχω απορία συγκεκριμένα για βιβλιοθήκες που θέλω να φτιάξω.
Για παράδειγμα βλέπω βιβλιοθήκης που άλλες μεταβλητές τις ορίζουν στο .h και άλλες στο .c.

----------


## SeAfasia

ερώτηση:
για προγραμματισμό pic mcu εννοείς έτσι;

----------


## bolsevikos

εχει να κάνει με την ορατότητα των μεταβλητών της συνάρτησης. Αλλες είναι για εσωτερική κατανάλωση και άλλες για επικοινωνία με τον έξω κόσμο.

----------


## picdev

Αναφερομαι στα 2 διαφορετικα αρχεια .c και .h. πρεπει να οριστουν και στα 2 οσες πρεπει να φενονται στη μαιν?

Στάλθηκε από το GT-S6312 μου χρησιμοποιώντας Tapatalk 2

----------


## SeAfasia

> Αναφερομαι στα 2 διαφορετικα αρχεια .c και .h. πρεπει να οριστουν και στα 2 οσες πρεπει να φενονται στη μαιν?
> 
> Στάλθηκε από το GT-S6312 μου χρησιμοποιώντας Tapatalk 2



ναι καλούνται απο τη main.c περιέχουν απαραίτητες συναρτήσεις....
Άκη μιλάμε για pic programming έτσι;

----------


## picdev

Ναι για με ειναι αλλα δεν παιζει κ τοσο ρολο

Στάλθηκε από το GT-S6312 μου χρησιμοποιώντας Tapatalk 2

----------


## SeAfasia

> Ναι για με ειναι αλλα δεν παιζει κ τοσο ρολο
> 
> Στάλθηκε από το GT-S6312 μου χρησιμοποιώντας Tapatalk 2



oκ τότε,αν είναι για ενα κώδικα στη C που θα μεταγλωτιστει μεσω ενός προγράμματος σαν το dev c++ ή το codeblocks θα έχει διαφορά από ότι να γραφτεί για προγραμματισμο mcu..
Αύριο θα σου πω διαφορές. ..

----------


## klik

> Αναφερομαι στα 2 διαφορετικα αρχεια .c και .h. πρεπει να οριστουν και στα 2 οσες πρεπει να φενονται στη μαιν?
> 
> Στάλθηκε από το GT-S6312 μου χρησιμοποιώντας Tapatalk 2



στο .c θα εχεις πχ int variableA;
ενω στο .h external int variableA;
Στο .c της βιβλιοθήκης θα κανεις include και το .h της βιβλιοθήκης. Μπορεις να κόβεις τα extern για το c της βιβλιοθηκης.

Ολα τα αλλα global variables στο c που δεν θελεις να ειναι ορατα αλλου, μπορουν να ειναι static.

----------


## picdev

δηλαδή πρέπει να οριστούν και στο .h και στο .c, αν θέλω να φαίνονται στο main ? και μάλιστα να τα κάνω extern?
μπορεί να υπάρχουν μεταβλητές μόνο στο .h και όχι στο .c? δηλαδή μπορεί να ειναι ανεξάρτητα ?
γιατί εδώ πχ https://github.com/elechouse/nRF905/...hield/NRF905.h 
έχει κάνει κάποια define μονο στο .h , στο .c δεν υπάρχουν.
Αν η μεταβλητή-συνάρτηση δεν είναι extern δεν φαίνεται ?

και κάτι άλλο που δεν έχω καταλάβει είναι το παρακάτω, αυτό είνai struckt, και το ορίζει μονο στο .h

typedef enum
{
    US = 0,             /** 908.42Mhz */
    EUROPE = 1,         /** 868.42MHz */
    AFRICA  = 2,         /** 868.42MHz */
    CHINA = 3,          /** 868.42MHz */
    HK = 4,             /** 919.82MHz */
    JAPAN = 5,          /** 853.42MHz */
    AUSTRALIA = 6,      /** 921.42MHz */
    NEW_ZEALAND = 7,    /** 921.42MHz */
    BRASIL = 8,         /** 921.42MHz */
    Russia = 9,         /** 896.00MHz */
} nrf905_freq_type;

----------


## klik

Eίπαme ότι το .h θα το κανεις include και στη main και στο .c της βιβλιοθήκης. Μόνο μια φορά θα γράφεις τις μεταβλητές/τύπους κλπ.

π.χ. 


```
//@ lib1.h

#ifndef _LIB1_H
#define _LIB1_H           1

#ifndef _EXTERN
#define _EXTERN extern
#endif

enum fooe {
        fa,fb,fc,fd
};

typedef struct {
  int a;
  double b;
  unsigned int x:3;
} data1;

_EXTERN data1 xfoo;

void xxx(void);

#endif    //_LIB1_H
```





```
//@main.c
#include "lib1.h"
int main(){
   xfoo.b = 3.3;
}
```





```
//@lib1.c
#define _EXTERN
#include "lib1.h"
#undef _EXTERN
#include <stdio.h>

void xxx(void){
    xfoo.a = fa;
}
```

----------


## bchris

Ειναι πολυ απλο.
ας πουμε οτι φτιαχνεις μια library "prasina_aloga" με το "prasina_aloga.c" και το "prasina_aloga.h"
Εννοειται οτι στο prasina_aloga.c θα εχεις include το prasina_aloga.h
Επισης μιας και μιλαμε για library, δεν υπαρχει int main(). Αυτη θα βρισκεται στο .c του προγραμματος που θα χρησιμοποιιησει την library σου.

Τωρα, οσες μεταβλητες βαλεις στο "prasina_aloga.h" θα φαινονται και στο "prasina_aloga.c" καθως επισης και οπου κανεις include το "prasina_aloga.h" συνηθως στο κεντρικο .c οποτε θα τις βλεπει και η εν λογω int main() που λεγαμε πιο πριν.
Οσες μεταβλητες τις βαλεις στο "prasina_aloga.c" ομως, θα ειναι ορατες μονο εκει μεσα. Θα ειναι κατα καποιο τροπο για εσωτερικη καταναλωση απο την library.

Αυτα...

----------


## picdev

στο .h πρέπει να γράψουμε και με extern τις συναρτήσεις του .c αρχείου.
+ να ορίσουμε μεταβλητές που θα έχουν πρόσβαση απο το main. Αλλά αυτές τις ορίζουμε μονο στο .h
Αν ορίσουμε μεταβλητή στο .c της βιβλιοθήκης θα φαίνεται μόνο απο εκεί.
καλά τα είπα?

Κλικ καλά τα λές , αλλά ακόμα προσπαθώ να καταλάβω τη σύνταξη σου σε κάποια πράγματα

----------


## picdev

@#$ όσο διαβάζω παραδείγματα στο νετ για extern και τα συναφή τόσο μπερδεύομαι και  2 βιβλία που έχω δεν λένε τίποτα

----------


## picdev

Εδώ είδα ένα παράδειγμα , τη μεταβλητή τη δηλώνει σαν extern  στο .h για να είναι ορατή και στο main., αλλά είναι δηλωμένη στο .c της βιβλιοθήκης.
Απο την άλλη ποιος ο λόγος να δηλώσεις μεταβλητή στο .h και όχι στο αρχείο .c της βιβλιοθήκης ?


http://computer.howstuffworks.com/c15.htm


και κάτι τελευταίο αν κάνω κάτι define στο αρχείο της main
θα μπορώ να το χρησιμοποιήσω στο .c της βιβλιοθήκης? 
κάποια pin θέλω να κάνω define

----------


## klik

> κάτι τελευταίο αν κάνω κάτι define στο αρχείο της main
> θα μπορώ να το χρησιμοποιήσω στο .c της βιβλιοθήκης? 
> κάποια pin θέλω να κάνω define



οχι..........

----------


## picdev

καμιά ιδέα? πως μπορώ να χρησιμοποιώ τα pin στη  βιβλιοθήκη με περιγραφές?
Πρέπει να γίνονται define στο .h? κάθε φορά?

.........

Μόλις βρήκα μια βιβλιοθήκη που κάνει define τα pin στο .h, κάτι είναι και αυτό

----------


## troller_coaster

Θα προσπαθήσω να τα βάλω σε μια σειρά:

Τα #define, #include και γενικά ό.τι ξεκινά με # δεν έχουν καμμία σχέση με μεταβλητές ή γενικότερα με τη γλώσσα. Είναι directives του preprocessor. Φαντάσου ότι πριν πάει το αρχείο σου στον compiler ο preprocessor θα το "πετσοκόψει" εκτελώντας τα directives που έχεις ορίσει. Αν έχεις 2 c αρχεία που κάνουν include το π.χ. stdio.h αυτό θα "ταϊστεί" πολλαπλώς στον compiler. Επειδή όμως δεν μπορείς να ορίσεις το ίδιο σύμβολο 2 φορές, στα header συνηθίζεται η extern που λέει: αυτό είναι ένας π.χ. ακέραιος αλλά μην το ορίσεις στο object file μετά το compilation! Θα το βρεις από αλλού! (Ή άλλο c αρχείο ή κάποια βιβλιοθήκη).

Γενικά τα headers ορίζουν το "τι;" και τα c το "πώς;". Για το λόγο που σου είπα παραπάνω, τα headers των βιβλιοθηκών έχουν extern στις δηλώσεις τους.

----------


## picdev

Ωραια μου τα ειπες. Αλλα εχω δει κ ορισμους μεταβλητων  σε 
Header. Αυτο τι σκοπο εχει?

Στάλθηκε από το GT-S6312 μου χρησιμοποιώντας Tapatalk 2

----------


## troller_coaster

Ο σκοπός εξαρτάται από το header. Χωρίς να ξέρω κάτι για αυτό, δεν μπορώ να σου πω γιατί το έκανε. Υποθέτοντας, λοιπόν, μπορώ να σου πω εγώ γιατί θα το έκανα.

Έχω π.χ. μια βιβλιοθήκη που με κάποιο μαγικό τρόπο διαβάζει τη θερμοκρασία και θέλω να την προσπελάζει ο χρήστης μέσω μιας global μεταβλητής. Την ορίζω σε header ως:

extern volatile int temperature;

extern γιατι ορίζεται στη βιβλιοθήκη μου, δεν χρειάζεται να δημιουργήσει άλλο σύμβολο ο compiler στο object file γιατί θα κάνει conflict με αυτό της βιβλιοθήκης. Μην ξεχνάς ότι το header γίνεται include από τον κώδικα του χρήστη.
volatile γιατί είναι μέγεθος που μπορεί να αλλάξει από κάποιο παράλληλο thread της βιβλιοθήκης και θέλω ο compiler να το διαβάζει όταν χρησιμοποιείται, χωρίς να βασίζεται στην τιμή που έχει ήδη διαβάσει.

----------


## klik

> Ωραια μου τα ειπες. Αλλα εχω δει κ ορισμους μεταβλητων  σε 
> Header. Αυτο τι σκοπο εχει?
> 
> Στάλθηκε από το GT-S6312 μου χρησιμοποιώντας Tapatalk 2



να δειξει ποσο αρχαριος ηταν ο προγραμματιστης...

----------


## troller_coaster

> να δειξει ποσο αρχαριος ηταν ο προγραμματιστης...



Αυτό εξυπακούεται! Το να χρησιμοποιείς globals, ειδικά για τέτοιους λόγους, είναι κακή τακτική. Αλλά ας μη μπερδεύουμε τον picdev χειρότερα...

----------


## picdev

έψαχνα  πως μπορώ να φτιάξω βιβλιοθήκες στη mikroc και είναι κάπως περίπλοκο αφού πρέπει να γίνει για κάθε μΕ ξεχωριστά.
Μία πρόταση σε φόρουμ ήταν να φτιάξεις *μονο* αρχείο .h , το δοκίμασα με το φίλο μου και δουλεύει, δηλαδή γράφουμε συναρτήσεις με κώδικα στο .h και μετά γίνεται include κανονικά.
Είναι σωστή πρακτική ? 
άντε κλικ απάντα  :Lol:

----------


## klik

Ναι και οχι :Tongue2: .
Ναί όταν έχεις χαζοπρογράμματα και χαζοcompiler.
Όχι για όλες τις άλλες περιπτώσεις!

Μην το κάνεις.

Θα κάνεις add στο project τα .c αρχεία και θα μεταγλωτίζονται μια φορά μόνο για το κάθε project (επειδή δεν θα έχουν αλλαγές) και άσε τα υπόλοιπα να τα αναλάβει ο compiler και ο linker.
 To include σε κώδικα προβλέπεται πλήρως από τη c99 αλλά και στη c++. (inline συναρτήσεις, multiple instances of vars κλπ Οι inline υπήρχαν και σε παλιότερα πρότυπα βλέπε intrisict).
Αλλιώς θα έχεις καθυστερήσεις στο compile, δυσκολία στο debug κλπ

Είσαι σίγουρος ότι πρέπει να ξαναφτιάξεις το lib για κάθε μΕ;
π.χ. αν σε καλύπτει το p18cxxxx.h (δηλαδή δουλεύεις με p18 διάφορα μΕ) τότε δεν χρειάζεται να ξαναμεταγλωτισεις. Θα αναλάβει ο linker τις συνδέσεις και είσαι έτοιμος.
  Αν θέλεις βέβαια ταυτόχρονα για p18, p24 και p32 ναι, τότε θέλεις ή να κάνεις μεταγλώτιση χωριστά (και να έχεις 3 διαφορετικές βιβλιοθηκες lib18mlib24,lib32) ή να βάλεις τα .c στο project.

----------


## picdev

απλά είναι ευκολία έτσι , δηλαδή θα έχω πρόβλημα στο compile? παίζει να κάνει τρέλες?
δυσκολία στο debug γιατί?

----------


## klik

Στο debug μπορεί να μπερδεύει γραμμές, να μην μπορεί να κάνει watch μεταβλητές κλπ.
Γιατί δεν κάνεις add τα .c αρχεία;
Δες π.χ. το eeprom.c
xxx1.jpg

----------


## picdev

δεν γράφω με το Mplab αλλά με mikroC, και θέλει μία διαδικασία γιατί ειναι σκατό compiler.
To mplab το καινούριο δεν έχει βιβλιοθήκες για 16f

----------


## klik

To project υπάρχει παντού. gcc, sdcc, hitech κλπ. Είναι η GUI έκδοση των makefiles. Δεν είναι απαραίτητο να γράφεις σε mplab. Αν και δεν έχω ασχοληθεί με τη microC, σίγουρα μπορείς να κάνεις project ή έστω makefile και ο linker να σου ενώσει τα objects. 

Compiler -> objects 
Objects + Libraries -> Link -> Executable/Hex

Ελπίζω να μην έχεις μόνο ένα .c αρχείο για κάθε πρόγραμμα σου με τα πάντα όλα μέσα.

----------


## picdev

έφτασα να έχω 500 γραμμές κώδικα σε ένα αρχείο μονο, οπότε τώρα μου έτυχε μια δουλειά και θέλω να το κάνω όμορφα και ωραία, 
οπότε θέλω να αρχίσω να το οργανώσω καλά.
Η mikroC σου δίνει βιβλιοθήκες αλλά είναι για τα σκουπίδια, ούτε Inline δεν υποστηρίζει τέλος πάντων, απλά δεν έχω χρόνο τώρα για να πάω σε κάτι άλλο.

Και όταν δούλευα για ένα χρόνο πάνω σε ανάπτυξη, χρησιμοποιούσα το MPLAB, εκεί το αφεντικό τα ήξερε όλα απο το 1980  :Rolleyes: 
και δεν με άφηνε ούτε να βάζω συναρτήσεις , ούτε βιβλιοθήκες να φτιάχνω, το inline δεν το ήξερε , οπότε καταλαβαίνεις τι γινόταν.
Τώρα θέλω να νοικοκυρευτώ  :Lol:

----------


## klik

Άσε λίγο να το δω (mikroC)...

----------


## picdev

γίνεται Klik θα το κάνω σωστά όπως πρέπει με .c μην κάνω πειράματα , απλά το έγραψε ένας σε ένα φορουμ και λέω είναι ευκολία

----------


## picdev

Λοιπόν έφτιαξα τη πρώτη μου βιβλιοθήκη σε mikroC, τελικά ήταν πιο εύκολο από ότι έλεγαν στα φόρουμ ,
Θέλω να ρωτήσω για κάτι που είδα σε ένα πρόγραμμα και το έκανα και εγώ.

Εχω κάποια defines για πόρτες κτλ στη main μου, που θέλω να τα χρησιμοποιώ και στις βιβλιοθήκες μου,
έφτιαξα ένα αρχείο main.h και το κάνω include και στα .c της βιβλιοθήκες αλλά και στη main , είναι σωστή πρακτική?

Πρέπει να μάθω τώρα τις εντολές του compiler με τα ifndefine κτλ, θα μελετήσω το κώδικα που έχεις ποστάρει,
που πάλι με μπέρδεψε γιατί παντού βλέπω ότι ορίζουμε(defining) τις μεταβλητές μονο στο .c στο .h τις κάνουμε extern που είναι declair και κάνουμε γνωστό ότι η μεταβλητή είναι ορατή και εκτός του δικού της αρχείου.
Εσύ όμως έχεις ορίσει μεταβλητές μόνο στο .h, ότι δουλεύει το ξέρω, γιατί κάνεις και include to .h στο .c,
αλλά είναι ορθό ? το επιτρέπουν οι κανόνες?>

----------


## klik

Δεν είμαι βέβαιος ότι έχεις καταλάβει τι είναι η βιβλιοθήκη (.lib). Την βιβλιοθήκη την κάνουμε και δεν αλλάζουμε κάτι μέσα της μετά.
 Δηλαδή όταν έχεις φτιάξει τη βιβλιοθήκη (με ότι defines είχες τότε), δεν μπορείς να ξανακάνεις διαφορετικά define στη main και να να δουλέψουν στην ήδη έτοιμη .lib. Μπορεί φυσικά να γίνει να αλλάζεις ακίδες από μια έτοιμη βιβλιοθήκη, αλλά όχι με αυτό τον τρόπο (αν σου πως πως, θα μπερδευτείς περισσότερο).

Μήπως εσύ βιβλιοθήκη ονομάζεις αρχεία .c που τα κάνεις add στο project;

----------


## picdev

φτιάχνω αρχεία .c και .h και μοιράζω τις συναρτήσεις. Δηλαδή έφτιαξα ένα αρχείο με συναρτηση keypadMatrix και debounce px.
Εσύ λές βιβλιοθήκες πλήρως δυναμικές? με δομές δεδομένων κτλ? πουν  σε σετάρονται με pointers κτλ χωρίς defines κτλ?

* Τα defines που αφορούν το keypad τα έβαλα  στο .h της keypad*
είναι defines που συνδέεται το keypad. 

Νομίζω ότι εννοείς ότι η βιβλιοθήκη δεν ξαναγίνεται compile........
o IDE της mikroC έχει επιλογή "buld all files like library" και το έχω ενεργοποιημένο

----------


## klik

> φτιάχνω αρχεία .c και .h και μοιράζω τις συναρτήσεις.



σωστά




> Εσύ λές βιβλιοθήκες πλήρως δυναμικές? με δομές δεδομένων κτλ? πουν  σε σετάρονται με pointers κτλ χωρίς defines κτλ?



 για το κομμάτι των ακίδων, ναι αυτό λέω.

* 





 Αρχικό μήνυμα από picdev


Τα defines που αφορούν το keypad τα έβαλα  στο .h της keypad



*



> είναι defines που συνδέεται το keypad.



σωστά





> Νομίζω ότι εννοείς ότι η βιβλιοθήκη δεν ξαναγίνεται compile........



 ναι, εκτός αν αντί για add το .lib κάνεις αδδ τα .c





> o IDE της mikroC έχει επιλογή "buld all files like library" και το έχω ενεργοποιημένο



δεν ξέρω τι κάνει αυτό.

----------


## picdev

ναι κάνω add τα αρχεία .c και τα .h στο project και κάθε φορά που κάνω build τα κάνει όλα build μαζί και αυτά.
Υπάρχει τρόπος να φτιάξω ειδικό αρχείο που δεν θα ξαναγίνεται compile mcl files τα λέει η mikroc.
Τα βάζεις στο φάκελο με τις δικιές της βιβλιοθήκες που είναι κρυμένο το source code και μετά με xml editor το εμφανίζεις και στο μενου.
 αλλά είναι δύσκολο για αυτά που ξέρω να φτιάξω δομές δεδομένων για τέτοια βιβλιοθήκη, που να αλλάζουν τα pin δυναμικά.
Μέχρι στιγμής οργανώνω καλύτερα το κώδικα μου και δεν το έχω σε ένα αρχείο και βοηθάει πολύ.

Αυτό που κάνω πως ονομάζεται? μλκ ?  :Lol:  αντί για βιβλιοθήκη ?

----------


## klik

> ...Εσύ όμως έχεις ορίσει μεταβλητές μόνο στο .h, ότι δουλεύει το ξέρω, γιατί κάνεις και include to .h στο .c,
> αλλά είναι ορθό ? το επιτρέπουν οι κανόνες?>



Αν το έγραφα δυο φορές, μια στο .c και μια στο .h, θα μπορούσε να γίνει κάποιο λάθος, τώρα ή σε μελλοντική διόρθωση.
Το γράφω μόνο μια και είμαι βέβαιος ότι είναι σωστό.

Τους ορισμούς των συναρτήσεων φυσικά και πρέπει να είναι και στο .h και στο .c, ώστε αν έχεις κάποιο τυπογραφικό λάθος, ο compiler θα γκρινιάξει μόλις κάνει το .c της βιβλιοθήκης.
Τα struct/typedef τα κάνω φυσικά στο .h και απο εκεί τα διαβάζει και το .c της βιβλιοθήκης.

Με τις μεταβλητές τώρα, αντί να τις ορίσω στο .c και να τις ξαναγράφω κάνωντας τες extern στο .h, τις ορίζω με
EXTERN int x;

Το EXTERN για το .c της βιβλιοθήκης το έχω κενό (άρα εκεί πραγματικά δεσμεύω χώρο για τη μεταβλητή), ενώ για όλα τα άλλα αρχεία που το κάνουν include, το EXTERN είναι extern (δήλωση απομακρυσμένης μεταβλητής).

----------


## klik

> ...
> Αυτό που κάνω πως ονομάζεται? μλκ ?  αντί για βιβλιοθήκη ?



  Όχι βρε, αυτό σου είχα προτείνει να κάνεις (add τα .c στο project). Σε σχέση με το #include τα .c είναι σκάλες καλύτερο. Μια χαρά πρακτική είναι για μικρά έως μεσαία project. Τις βιβλιοθήκες (.lib) σου έλεγα να αποφύγεις. Αυτές έχουν άλλη έκδοση για κάθε πυρήνα μE.

----------


## picdev

κατάλαβα περίπου τι λές , αλλά αυτά θέλουν διάβασμα, αν θές πρότεινε μου ένα βιβλίο για τέτοια πιο προχωρημένα θέματα.
Εχω αγοράσει ένα για C++ δεν θυμάμαι πως το λένε τώρα.
Ευτυχώς που βλέπω και τον admin του forum μας να παλεύει με flow chart σε άλλο θέμα  λες και πάει γυμνάσιο  και παρηγορούμαι λίγο  :Lol:

----------


## klik

Το μόνο βιβλίο που έχω διαβάσει για C είναι των K&R και για C++ του Bjarne Stroustrup.
Μου άρεσε πολύ η ιστοσελίδα: http://www.cplusplus.com/ και την προτείνω για C++, διότι δεν λέει μπαρούφες όπως τα περισσότερα (Ελληνικά kai jena) βιβλία που έπεσαν κάποιες στιγμές στα χέρια μου.

----------


## picdev

κλικ συγγνώμη που σε έχω πρήξει αλλά μου γράφεις 
*Σε σχέση με το #include τα .c είναι σκάλες καλύτερο.*

εγώ κάνω *include τα .h* στη main μου και αν δεις δεξιά έχω προσθέσει τα αρχεία στο project. 
Aν δεν τα κάνω include δεν τα βλέπει
exx.jpg

----------


## klik

Τα .h είναι για να τα κάνουμε include (και δεν πρέπει να περιέχουν συναρτήσεις μέσα). Τα .c (που εχουν κωδικα) δεν πρέπει να κάνεις include σε άλλα .c
Δεν πρέπει να κάνεις δηλαδή αυτό:




> Μία πρόταση σε φόρουμ ήταν να φτιάξεις *μονο* αρχείο .h , το δοκίμασα με το φίλο μου και δουλεύει, δηλαδή γράφουμε συναρτήσεις με κώδικα στο .h και μετά γίνεται include κανονικά.
> Είναι σωστή πρακτική ?

----------


## picdev

ναι το ξεκαθάρισα αυτό, δεν τα έχω έτσι σε καμία περίπτωση

----------


## picdev

Λοιπόν klik πήγα να ορίσω μεταβλητή στο .h και που πέταξε error ο Compiler,(και καλά έκανε γιατί μία μεταβλητή με το include του header την ορίζω 2-3 φορές αυτό το κατάλαβα, επίσης ξεκαθάρισα ότι το extern δεν δεσμεύει μνήμη αλλά κάνει μια κοινοποίηση στον linker)
είδα και στο stack overflow την τεχνική που χρισημοποιείς αλλά δεν την έχω κατανοήσει,
αυτά πως λέγονται τα ifndef ktl macros του compiler?
Να τα μελετήσω λίγο μην τα κάνω παπαγαλία.

το _EXTERN ειναι εντολή και αυτή? έχω απορία πως δεσμεύει μνήμη για τη μεταβλητή.

----------


## klik

Το _EXTERN είναι definition του preprocessor.

Αν κάνω στο xxx.c: 
#define EXT   //κενο
#include "xxx.h"

Και στο xxx.h
#ifndef EXT
#define EXT extern
#endif

στο yyy.c
#include "xxx.h"

τότε στο xxx.h όταν διαβαζεται για το xxx.c, το EXT έχει τιμη κενη (τιποτα)
τότε στο xxx.h όταν διαβαζεται για το yyy.c, το EXT έχει τιμη extern

----------


## picdev

εδώ και 2 μέρες έχω κολήσει σε ένα "περίεργο" πρόβλημα.

Αρχικά έχω ορίσει κάποιους 2d πίνακες σε const για να αποθηκεύονται στη μνήμη





> const  short 2d_Table[20][11]={ mpla mpla mpla}



μετά έχω φτιάξει μία συνάρτηση που δέχεται *2d const* *πίνακα*





> function(const short array[20][11]){mpla mpla}



που είναι το πρόβλημα τώρα, όταν τρέχω αυτή τη συνάρτηση μέσα στη MAIN μου όλα μια χαρά
αλλά όταν την τρέχω μέσα απο άλλη συνάρτηση , μου πετάει ERROR ο compiler
* Index out of bounds 
 Illegal typecast 'can not convert to pointer*

To πρόβλημα "λύνεται" αν δεν ορίσω το μέγεθος του πίνακα σαν είσοδο στη συνάρτηση αλλά έτσι κρεμάει το πρόγραμμα  και είναι λογικό γιατί πρέπει να ξέρει τη δεύτερη διάσταση.

Πως εξηγείται το παραπάνω ? :Confused1:

----------


## picdev

Λοιπόν νομίζω ότι βρήκα το πρόβλημα, πέρασα τα στοιχεία του πίνακα σαν μεταβλητές στη συνάρτηση.
δηλαδή




> function_2)(short row,short collums){
>        function(row,collums);
> 
> }



με τον παραπάνω τρόπο κάνει compile κανονικά και παίρνει τα στοιχεία του πίνακα.
αν όμως γράψω με το χέρι τα στοιχεία τότε δεν κάνει compile





> function_2)(){
>        function(11,20);
> 
> }



θα το δοκιμάσω το απόγευμα και βλέπουμε

----------


## klik

Εχεις συντακτικα λαθη και δεν βγαζω ακρη τι εχεις κανει. Βαλε αποσπασμα απο δηλωση συναρτησης και πινακα, ορισμο συναρτησης και πινακα  καθως και την κληση της

----------


## picdev

ορίζω το πίνακα.




```
const unsigned short 2d_Teble[20][11]=
 {
 {1,1,1,1,1,1,1,1,1,1,END},
 {1,1,1,1,1,1,1,1,1,1,END},

....
.....
}
```


ορίζω συνάρτηση που έχει είσοδο 2d πίνακα




```
 
void function(const unsigned short array[20][11]){

}
```


*ως εδώ όλα καλά γιατί η συνάρτηση δουλεύει μια χαρά στη main*
Έστω όμως ότι θέλω να τη καλέσω μέσα απο άλλη συνάρτηση και πρέπει να πάρει παραμέτρους του πίνακα




```
 
function2(){
    function(2d_Table[20][11]);
}
```


εδώ δεν μου κάνει compile και δεν παίρνει τα ορίσματα, του πίνακα το 20 και το 11.
Πρέπει να τα περάσω σαν μεταβλητές στη function 2 , έτσι κάνει compile,το απόγευμα θα το περάσω στον μΕ




```
 
function2(row,collumns){
    function(2d_Table[row][collumns]);
}
```

----------


## klik

> ορίζω το πίνακα.
> 
>  const unsigned short 2d_Teble[20][11]=
> 
> To 2d_Test είνααι αποδεκτό όνομα identifier?
> 
> 
> 
> 
> ...






```
//@(#)test.c

#include <stdio.h>

/*
ο 2διαστατος πίνακας είναι ή πίνακας πινάκων (dynamic allocation) 
ή μονοδιάστατος με τακτοποιημένα τα στοιχεία σε σειρά (static allocation).

Για static allocation, πρέπει να ξερει όλες τις διαστάσεις πλην της πρώτης.
Παράδειγμα η συνάρτηση check()

*/

int tarray[3][4] = {
	{1,2,3,4},
	{11,12,13,14},
	{21,22,23,24}
};

int check(int a[][4 /*columns*/],size_t lines){
	int i,j,err=0;
	for(i=0;i<lines;i++){
		for(j=0;j<4;j++)
			if(a[i][j] != i*10+j+1)
				err++;
	}
	return err;
}

int check2(int *a,size_t lines,size_t columns){
	int i,j,err=0;
	for(i=0;i<lines;i++){
		for(j=0;j<columns;j++)
			if(a[i*columns + j] != i*10+j+1)
				err++;
	}
	return err;
}

void main(void){
	check(tarray,3);
	check2(tarray,3,4);
}
```

----------


## klik

Όταν τα δοκιμάσεις και βρεις τη λύση για να δουλέψουν αυτά, θα σου πω και τη "σωστή" μέθοδο για να κάνεις τέτοιες δουλειές.
Μέχρι τότε μπορείς να διαβάσεις ένα εξαιρετικό κείμενο για το στυλ: https://www.kernel.org/doc/Documentation/CodingStyle

----------


## picdev

το ξέρω ότι πρέπει να δηλώσει τη δεύτερη διάσταση.
το λάθος μου ήταν ότι έβαζα ακέραιο όρισμα συνάρτησης εκτός της MAIN
Eδώ πέταγε Error στο compile , τη Function1 αν τη καλούσα στη main δούλευε κανονικα



```
function2(){
    function1(2d_Table[20][11]);
}
```


μετά άλλαξα τη function2 σε 




```
function2(unsigned short row,unsigned short collumns){
    function1(2d_Table[row][collumns]);
}
```

----------


## picdev

Ευχαριστώ για τη βοήθεια κλικ, πρώτη φορά ασχολούμαι με τέτοια κόλπα, δεν ξέρω αν βρω χρόνο να το διαβάσω γιατί έμεινα πίσω.
Ο κώδικας ήταν παράδειγμα και τον έγραψα τώρα, βάζω κανονικές περιγραφές ολόκληρες λέξεις , σε καμία περίπτωση δεν τα έχω έτσι στο κώδικα,
αλλά δεν ακολουθώ κάποιο στυλ συγκεκριμένο

if(a[i*columns + j] , ωραίο κόλπο αυτό

----------


## picdev

εντάξει μικρό είναι μόλις πάω σπίτι θα το διαβάσω,  :Biggrin:

----------


## picdev

Εχω κάνει κάποιες σκέψεις για διαχείριση πινακαών.  Ας πούμε ότι έχω μερικές ομάδες πινάκων αποθηκευμένους στη ROM με σταθερό μήκος, κάθε ομάδα έχει ένα κοινό στοιχείο και χρησιμοποιούνται όλοι μαζί.  
Μέχρι στιγμής κάθε ομάδα την είχα σε έναν δισδιάστατο πίνακα οπότε ήταν εύκολη η πρόσβαση, 
Τώρα όμως δεν υπάρχει παραπανίσια μνήμη οπότε οι πίνακες πρέπει να σπάσουν σε μονοδιάστατους με διαφορετικό μήκος ο καθένας.
 Σκέφτηκα λοιπόν κάθε ομάδα πινάκων να έχει και έναν πίνακα που θα περιέχει τις διευθύνσεις μνήμη  του κάθε μονοδιάστατου πίνακα πίνακα. Σαν σκέψη είναι καλή? υπάρχει κάτι πιο ορθό ?

----------


## klik

κάτι σαν αυτό θέλεις φαντάζομαι 



```

typedef  short int datam;

 const code datam a[] = {1,2,3};
 const code datam b[] = {3,4,5};

 const code datam *p[] = {
        a,
        b
 };
```


υπάρχουν και άλλες λύσεις, π.χ. για πίνακες με πολλά μηδενικά στα περιεχόμενα (αραιοί), λίστες, 
υπάρχει eeprom (εσωτερική και εξωτερική), κλπ

----------


## picdev

ναι αυτό ακριβώς, σαν σκέψη είναι σωστή? στα υπόλοιπα που λές ανοίκουν στις δομές δεδομένων να φανταστώ

----------


## klik

Ναι σωστό είναι. 

Μπορείς να έχεις:
α) πίνακα δεικτών στη RAM που να δείχνει σε πίνακες στη ROM.
β) πίνακα δεικτών στη ROM που να δείχνει σε πίνακες στη ROM.

----------


## picdev

ευχαριστώ κλικ, 
έχω κάποιο μειονέκτημα να χρησιμοποιώ δεδομένα συχνά από τη rom, προφανώς η ταχύτητα αλλά υπάρχουν άλλα προβλήματα?
αλλά σε τέτοια συστήματα ίδια μνήμη ειναι αλλά χωρισμένη νομίζω.
Πάντως οι τιμές δεν θα αλλάζουν μόνο θα διαβάζονται

----------


## klik

Δεν υπάρχει πρόβλημα.

----------


## picdev

τελικά την πάτησα........

Λοιπόν μπαίνω στο ψητό , έχω 8 2d πίνακες σταθερούς ωραία? οι διαστάσεις τους είναι μεγάλες ας πούμε 20x150, οπότε για ram ούτε λόγος  :Sad: 
ορίζονται CONST και μπαίνουν στη rom

επειδή κάθε φορά χρησιμοποιώ έναν μόνο αλλά πρέπει να υπάρχουν στη rom και οι υπόλοιποι  
*λέω ας φτιάξω έναν pointer που δείχνει στον 2d πίνακα*

*char *2d_Array_pointer[][150];*

μετά είδα ότι ο compiler στη προκειμένη περίπτωση mikroc (κλικ μην με βρίσεις)
δεν επιτρέπει να κάνω το παρακάτω , επειδή ο 2d array ειναι στη rom

*2d_Array_pointer=&2d_array


..................................................  ....................................
*Νομίζω ότι βρήκα λύση , const pointer :Huh: 

FontTable=*(const unsigned char *)*FONT8x8;
αυτό είναι σύνταξη casting αντί να βάλει *&* ??

και μετά γράφει




> // get pointer to the beginning of the selected font table
> pFont = (unsigned char *)FontTable[0];}



δεν μπορώ να έχω πρόσβαση στο πίνακα με τον κλασικό τρόπο *FontTable[1][0] ????


http://www.mikroe.com/forum/viewtopic.php?f=72&t=48004&

----------


## klik

Δοκίμασε κανένα τέτοιο



```
const char d[100];
const char *data = (const char *)d;
```

----------


## picdev

ναι αυτό το κάνει compile 
απλά ποια ειναι η διαφορά σε αυτά τα 2 

data=(const char *)d
*data=&d*

----------


## picdev

Λοιπόν νομίζω ότι κατάλαβα τη μλκ μου
Το d είναι πίνακας, άρα είναι pointer οπότε το *&d* δεν στέκει σωστά?
Για πιο λόγω γίνεται το CASTING??

----------


## picdev

λοιπόν τελικά ήθελε casting 

data=(const char *)d  μόνο αυτό δουλεύει , αλλά μου φένεται περίεργο που δεν δουλεύει και το data=d αφού και τα 2 είναι pointer, και πίνακας pointer δεν θεωρείται ?

----------


## Silas

Χωρις να ειμαι ο πλεον καταλληλος ανθρωπος να σου απαντησει, θα σου πω τι καταλαβαινω 

το d ειναι array. Το d σαν literal κανει decay σε pointer. Δηλαδη το d ειναι η διευθυνση του πρωτου στοιχειου του πινακα σου. Ο τελεστης & επιστρεφει διευθυνση. Αρα οταν του λες data=&d πας να βαλεις την διευθυνση της διευθυνσης του πρωτου στοιχειου του πινακα στο data. Δηλαδη προσπαθεις να βαλεις στο data ( το οποιο περιμενει διευθυνση στοιχειου  τυπου const char ) κατι το οποιο δεν ειναι διευθυνση στοιχειου τυπου const char αλλα διευθυνση διευθυνσης στοιχειου με τυπο const char.   

Το οτι δεν δουλευει το data = d μου φαινεται και εμενα περιεργο γιατι τωρα το εκανα σε gcc και δουλευει κανονικα.

----------


## picdev

απο τις πολλές δοκιμές είπα μλκ, κάνει compile το data=d και σε μένα τελικά
το απόγευμα θα δοκιμάσω και στον μΕ να δω αν έχει πρόσβαση στο πίνακα.

Μετά είδα και αυτά στο help της mikroc όταν μιλάει για const 


Pointer to constant space (Flash memory) is allocated in RAM.Due to the previous note, it is not possible to define an extern  const.Constants of a simple type are not allocated in the Flash memory nor in RAM,  but changed in the compile time, and therefore, address of a such constant can  not be obtained.PIC16 Enhanced family has 16-bit FSRs, FSRxL and FSRxH, capable of accessing  entire RAM and Flash memory. 
This makes pointers to constants and pointers  to variables compatible.

----------


## picdev

είδα ένα παράδειγμα της Mikroc και είδα 2 περίεργα.

1)έχει ορίσει pointer και δεν σετάρει πουθενά σε ποια θέση μνήμης βλέπουν???
είναι char pointer , και βάζει μέσα string. Μπορεί να γίνει κάτι τέτοιο? αν δείχνει σε θέση μνήμης που έχεις άλλα δεδομένα? και μέχρι πόσο γράφει?
δεν κάνει πουθενά malloc

2) επίσης είδα κουλαμάρες με .c αρχεία, χωρίς header κάνει extern μεταβλητές σε άλλο .c
Επίσης δεν κάνει πουθενά include :Huh:

----------


## klik

> είδα ένα παράδειγμα της Mikroc και είδα 2 περίεργα.
> 
> 1)έχει ορίσει pointer και δεν σετάρει πουθενά σε ποια θέση μνήμης βλέπουν???
> είναι char pointer , και βάζει μέσα string.



Λειτουργικά δεν υπάρχει θέμα.
π.χ.



```
unsigned long x = 0x11223344l;
unsigned char *p = &x;
 p[0] = 0x55;
if(x == 0x11223355l){
       ......
}
```


Αν δεν ξέρεις τι θα αποθηκεύσεις, υπάρχει και ο γενικής φύσης pointer 


```
void *p;
```







> και μέχρι πόσο γράφει?



 μέχρι όσο θέλεις εσύ. Η C σε αφήνει να τα κάνεις μαντάρα.





> 2) επίσης είδα κουλαμάρες με .c αρχεία, χωρίς header κάνει extern μεταβλητές σε άλλο .c
> Επίσης δεν κάνει πουθενά include



είναι θέμα προγραμματιστη...

----------


## picdev

άρα δεν είσαι καλλημένος ότι δεν θα γίνει μλκ?
Πολύ περίεργο μιας και το πρόγραμμα είναι της mikroC, το έχουν σαν παράδειγμα.

Εσύ klik γράφεις .h μόνο του ή .C, γιατί άκουσα και σε εταιρεία που έχουν πρόγραμμα που σε ένα .h ορίζουν μεταβλητές.
Τελικά δεν ξέρω τι ισχύει και απλά το πρόγραμμα που δουλεύω έχει αρκετά source file , που τα δομώ με τον παραδοσιακό τρόπο

----------


## Silas

Καλυμμενος δεν εισαι ποτε στην C. Θελει μεγαλη προσοχη γιατι null pointers, dangling pointers, memory overlaps ειναι ολα πολυ πιθανα. 


Γενικα declaration μεταβλητης σε .h δεν ειναι καλο practice γιατι απο compiler σε compiler δεν ξερεις τι θα συναντησεις. 
Δηλωνεις μεταβλητη σε module1.c αρχειο και αν το χρειαστεις σε καποιο αλλο module το δηλωνεις extern στο .h αρχειο του module2. 


δηλαδη 

module1.c 
=================
- #include "module1.h" 
- 
- int globalvar = 0;
=================

module2.c
===================
= #include "module2.h" 
= 
= int localvar = globalvar+2; 
===================

module2.h
=================
extern int globalvar; 
=================

----------


## klik

Σε .h είναι χαζομάρα να βάζεις ορισμό μεταβλητής.
Μπορείς να βάλεις δήλωση (extern).
Ο compiler δεν έχει θέμα, αν θα κάνεις ορισμούς ή όχι, στα τέτοια του, αρκεί να μη δει δυο ορισμούς κατά την μεταγλώττιση στο ίδιο .c.
Ο linker επίσης δεν θέλει δυο ορισμους ίδιας ονομασίας μεταβλητής (global).

Εμένα δεν μου αρέσει να χρησιμοποιώ μεταβλητές χύμα. Είναι όλα οργανωμένα σε structs και πακέτο με τις συναρτήσεις που το αφορούν, σε ένα .h. Οι structs φυσικά είναι σε .c ορισμένες. Ψευδο c++ δηλαδή.

Φροντίζω επίσης, όταν ο κώδικας είναι μεγάλος, να μην είναι μπλεγμένος σαν μακαρόνι, αλλά να έχει λογικά τμήματα (ανεξάρτητα προγράμματα) που δουλεύουν με κάποιον task manager που κάνει διευθέτηση χρόνου. Ένα στυλ rtos δηλαδή.





> άρα δεν είσαι καλλημένος ότι δεν θα γίνει μλκ?...



 όχι. Αυτή είναι η δύναμη της C. Είσαι πάντα sudo!

----------


## picdev

δηλαδή βάζεις και τις συναρτήσεις σε struct και μετά τις καλείς σαν ειναι κλάσεις ?
 δημιουργείς και "αντικείμενα" (δηλαδή struct) στη main?
ρε κλικ μπορείς να μου στείλεις ένα .c και ένα .h? η αλήθεια είναι ότι θέλω να δω πως γράφεις το κώδικα,
διάβασα μία φορά αυτά απο το κερνελ και κάποια τα έχω εφαρμόσει , θα τα διαβάσω άλλη μία φορά βέβαια αλλά το στίλ σου είναι πολύ καλό.
Υπάρχει κάποιο βιβλίο? Να ψάξω για kernel style C ?

Επίσης μου είπαν και ένα άλλο κόλπο, κάνεις type def unsigned shortκαι το ονομάζεις u8 και γλιτώνεις το μακρινάρι

----------


## picdev

όλο με πριζώνεις , μου λες και για task manager , :Lol:  κάνω πως δεν το άκουσα

----------


## klik

> δηλαδή βάζεις και τις συναρτήσεις σε struct και μετά τις καλείς σαν ειναι κλάσεις ?



όχι, περάς το struct σαν παράμετρο στη συνάρτηση (αν τα δεδομένα είναι δυναμικά και με πολλές instances ή η συνάρτηση ξέρει που να βρει το struct αν είναι static).





> δημιουργείς και "αντικείμενα" (δηλαδή struct) στη main?



αν είχα χύμα καμιά δεκαριά μεταβλητές δεν θα έβγαζα ακρη μετά απο κανένα χρόνο, αν έχεις data+συναρτησεις οργανωμένα σε modules, τότε έχεις και μεταφέρσιμο κώδικα και ευκολότερα υποστηριζόμενο





> Υπάρχει κάποιο βιβλίο?



 δεν γνωρίζω 





> Επίσης μου είπαν και ένα άλλο κόλπο, κάνεις type def unsigned shortκαι το ονομάζεις u8 και γλιτώνεις το μακρινάρι



 τα uint8,uint16 κλπ, υπάρχουν (κάπως έτσι) στους ορισμούς των νεότερων C, ώστε να ξέρεις τι μέγεθος έχουν.
Εγώ προτιμώ να κάνω:



```
typedef unsigned char uchar;
```


 *Spoiler:*       
Ακολουθεί απόσπασμα απο .η που έχει την add_task του task_manager για gsm communication.
Ορίζεις πότε θα σταλεί κάτι, τι θα σταλεί (string ram, string rom, number), τι απάντηση θα έρθει σε περίπτωση επιτυχίας, 
τι θα έρθει σε περίπτωση σφάλματος, πόσο timeout θα υπάρχει...
Σκέψου κάτι αντίστοιχο αλλά αντί για το string να έχεις ponter σε function



```
//xxx.h

//δομή με δεδομένα για τα uart_tasks

struct _gsm_spawn1tag {
		struct {
			union {
				ccpstr	c;	//rom
				lpstr	r;	//ram
				struct {
					byte	n;	//number
						//all flags bellow are initialy zero
					bool	decades		:1;
					bool	decimals	:1;
				};
			} str;
			byte type	:3;	//enum gsm_spawn_type
			byte _DB_idx	:2;	//index of char to transmit from DoubleByte translation
		} submit_str;

		bool	add_eol		:1;	//print eol at end of submit_str
		//
		bool	spawn_not_empty	:1;	//αν ειναι false, τοτε το συγκεκριμενο
						//entry array δεν εχει περιγραφη εργασιας
						//προς εκτελεση (ειναι αδειο)
		//
	/*SWm*/	byte	wait_ok		:3;	//what to wait on correct execution
	/*SWm*/	byte	wait_err	:2;	//what to expect on error (normaly "ERROR" answer from modem)

		byte	timeOut_ticks;	//ποσα 100msec calls θα περιμενουμε πριν κυριξουμε
					//αποτυχια timeout
	#define MAX_GSM_SPAWN	9	//was 8 till gm862, just added it for safety
	} spawn[MAX_GSM_SPAWN];
	GSmE	last_error;
	#define spawn_clear_error()	(gsm_spawn.last_error = GSmE_SP_NULL)
		//κατασταση εκτελεσης απο την λιστα
		//spawn.
	spawn_atend	procedure;	//αν θα εκτελεστει καποια procedure μολις γινει idle
					//το spawn (οταν δηλαδη τελειωσουν ολες οι εργασιες)

struct _process_uart_tag {
	struct _gsm_spawn1tag {
		struct {
			union {
				ccpstr	c;	//rom
				lpstr	r;	//ram
				struct {
					byte	n;	//number
						//all flags bellow are initialy zero
					bool	decades		:1;
					bool	decimals	:1;
				};
			} str;
			byte type	:3;	//enum gsm_spawn_type
			byte _DB_idx	:2;	//index of char to transmit from DoubleByte translation
		} submit_str;

		bool	add_eol		:1;	//print eol at end of submit_str
		//
		bool	spawn_not_empty	:1;	//αν ειναι false, τοτε το συγκεκριμενο
						//entry array δεν εχει περιγραφη εργασιας
						//προς εκτελεση (ειναι αδειο)
		//
	/*SWm*/	byte	wait_ok		:3;	//what to wait on correct execution
	/*SWm*/	byte	wait_err	:2;	//what to expect on error (normaly "ERROR" answer from modem)

		byte	timeOut_ticks;	//ποσα 100msec calls θα περιμενουμε πριν κυριξουμε
					//αποτυχια timeout
	#define MAX_GSM_SPAWN	12
	} spawn[MAX_GSM_SPAWN];
	GSmE	last_error;
	#define spawn_clear_error()	(gsm_spawn.last_error = GSmE_SP_NULL)
		//κατασταση εκτελεσης απο την λιστα
		//spawn.
	spawn_atend	procedure;	//αν θα εκτελεστει καποια procedure μολις γινει idle
};					//το spawn (οταν δηλαδη τελειωσουν ολες οι εργασιες)



//προσθήκη διεργασίας που θα εκτελεστεί σε συγκεκριμένο χρόνο και τις παραμέτρους που θα πάρει
//private members
byte __AddGSMSpawn(
	ccpstr c,lcpstr r,byte number,gsm_spawn_type tp,	//παραμετρος που θα αξιοποιηθεί από την διεργασία όταν αποκτήσει την ALU
	bool add_eol,						//αν θα σταλθεί EOL όταν τελειώσει η διεργασία, με τι μήνυμα τερματίζει επιτυχώς 
	byte sec_tenths_timeout,				//μετά από πόσο χρόνο θα εκτελεστεί
	SWm mok,SWm merror					
								//και με τι μηνυμα τερματίζει σε περίπτωση λάθους η διεργασά
);	//αν το sec==0xff τοτε περιμενε μεχρι να μην ερθει κανενας χαρακτηρας για 100msec
	//το sec_tenths_timeout είναι σε δεκατα του δευτερολέπτου
	
//εναλλακτικες κλησεις (με λιγότερες παραμέτρους):
#define AddGSMSpawn_ram(ra,addeol,tmout,mok,merr)	__AddGSMSpawn(NULL,	ra,	0,	is_ram_ptr,	addeol,	tmout,	mok,		merr)
#define AddGSMSpawn_ram2b(ra,addeol,tmout,mok,merr)	__AddGSMSpawn(NULL,	ra,	0,	is_ram_ptr_DB,	addeol,	tmout,	mok,		merr)
#define AddGSMSpawn_rom(ro,addeol,tmout,mok,merr)	__AddGSMSpawn(ro,	NULL,	0,	is_rom_ptr,	addeol,	tmout,	mok,		merr)
#define AddGSMSpawn_rom2b(ro,addeol,tmout,mok,merr)	__AddGSMSpawn(ro,	NULL,	0,	is_rom_ptr_DB,	addeol,	tmout,	mok,		merr)
#define AddGSMSpawn_num(nu,addeol,tmout,mok,merr)	__AddGSMSpawn(NULL,	NULL,	nu,	is_number,	addeol,	tmout,	mok,		merr)
#define AddGSMSpawn_delay(dl) /*delay in multiples of 0,1 sec*/	\
```

----------


## picdev

ευχαριστώ κλίκ , θα προσπαθήσω να το μελετήσω  :Unsure:   έχω τόσες απορίες όσες είναι οι γραμμές  :Lol:

----------


## picdev

λοιπόν κλικ, έφτιαξα το στιλ σε κερνελ στο προτζεκτ που κάνω, και έβαλα και τα type def, η εικόνα βελτιώθηκε πολύ.
Ρώτησα και έναν φίλο προγραμματιστή που γράψει java  βέβαια, και μου είπε για το βιβλίο που έχεις διαβάσει και εσύ, οπότε θα το διαβάσω.
Σίγουρα πρέπει να διαβάσω και βιβλίο για δομές δεδομένων γιατί δεν το πήρα το μάθημα στη σχολή ο @#$. 
Μία τελευταία ερώτηση για το κώδικα που πόσταρες, το struct μέσα σε struct είναι μορφή δομής δεδομένων? αν ναι πως λέγεται
...... το βρηκα nested

----------


## Silas

Το βιβλιο των K&R ειναι περισσοτερο reference παρα introduction. Δεν με ειχε βοηθησει ιδιαιτερα οταν ειχα ξεκινησει γιατι τοτε δεν ηξερα να γραφω καποια αλλη γλωσσα. 
Ενα βιβλιο που επεσε τυχαια στα χερια μου και με βοηθησε πολυ ειναι αυτο :

http://www.amazon.com/Dissection-The.../dp/0201713748


Για δομες δεδομενων ( λιστες, δεντρα, sparse arrays ) εχω διαβασει αυτο :: http://www.amazon.com/Fundamental-St.../dp/0201087251 και ηταν πολυ καλο αλλα ειναι και πολυ παλιο οποτε σιγουρα θα υπαρχει κατι καλυτερο και πιο ενημερωμενο

----------

picdev (25-05-15)

----------


## picdev

έχω μπλέξει λίγο με τα enum

έχω ορίσει ένα enum




```
enum melody {MELODY_SYNTHESIS_SCREEN=0,
      BELL_PULSE_SCREEN,
      CHURCH_NAME_SCREEN,
      PASSWORD_SCREEN
     } melody_Button_Screens=MELODY_SYNTHESIS_SCREEN;
```


και απο κάτω σε μία συνάρτηση κάνω τις εξείς πράξεις 




```
melody_Button_Screens++;
                if(melody_Button_Screens > 3)melody_Button_Screens=MELODY_SYNTHESIS_SCREEN;
```


κάνω extern τη συνάρτηση, δεν πετάει κάποιο error στο compile αλλά όταν πάω να την τρέξω σε κάποιο αλλο source file 
δεν μου το κάνει compile και μου λέει 

0 360 Unresolved extern 'melody_Button_Screens' Config_Menu.c

----------


## picdev

άκυρο, σε ένα .η είχα ξεχάσει ένα extern και χτύπαγε στο enum κουφό

----------


## klik

Μερικές προτάσεις για βελτιώσεις στον κώδικα




```
typedef enum  {
      MELODY_SYNTHESIS_SCREEN,
      BELL_PULSE_SCREEN,
      CHURCH_NAME_SCREEN,
       PASSWORD_SCREEN,
      MELODY_UNUSED
      } melody;

    melody melody_Button_Screens=MELODY_SYNTHESIS_SCREEN;

   ....
   if(++melody_Button_Screens >= MELODY_UNUSED)
        melody_Button_Screens=MELODY_SYNTHESIS_SCREEN;
```

----------

picdev (12-06-15)

----------


## picdev

Κλικ αυτό το κόλπο με το ++ μέσα στο if to έχω δοκιμάσει αλλά δεν δούλεψε σωστά 

Στάλθηκε από το 2014813 μου χρησιμοποιώντας Tapatalk

----------


## klik

Δουλεύει ΠΑΝΤΑ σωστά. Φυσικά, άλλο το 


```
if(++x>10)
```


 και άλλο to 


```
if(x++>10)
```

----------


## picdev

θα το δοκιμάσω με παρένθεση, είχα αντιμετωπίσει το ίδιο πρόβλημα με τους pointer και το έλυσα με τη παρένθεση.
Τότε δεν το ήξερα και το παράτησα.
Ωραίο και το κόλπο με το unused. 
Αρε κλικ την έχεις κάψει τη C!

Εφτιαξα blink , και χρησιμοποίησα pointer που δείχνει σε function,και είναι παράμετρος σε συνάρτηση. εκεί έμαθα τι γίνεται αν ο pointer είναι άδειος και δείχνει όπου να ναι  :Lol: 
Και τότε θυμήθηκα που μου είχες πει για τον Task manager,  κάτι αντίστοιχο δεν κάνεις? και στη main με flags και timers τρέχεις τις συναρτησεις.

----------


## klik

> ...Και τότε θυμήθηκα που μου είχες πει για τον Task manager,  κάτι αντίστοιχο δεν κάνεις? και στη main με flags και timers τρέχεις τις συναρτησεις.

----------


## picdev

:Lol:  :Lol:  ε τώρα που παρετήθηκα απο τη πρωινή δουλειά, όλη μέρα τη C σκέφτομαι.
Μου πήρε μια μέρα για να δω πως θα κάνω το blink και να επιλέγω στο μενού της οθόνης  :Lol:  θα σου στείλω βίντεο σε pm.
Εχω φτάσει στα 20 source file, και μόλις σκέφτομαι κάτι καινούριο μετά τα αλλάζω όλα ,
καλά το πάω αλλά καμία σχέση , έχω χρόνια ακόμα μπροστά μου......... αν δεν τα παρατήσω  :Lol:  
C μαθαίνεις μέχρι τα βαθιά γεράματα και c++ για να μάθεις θες 3 ζωές

----------


## picdev

μόλις διαπίστωσα ότι δεν γίνεται να κάνω αντιγραφή απο την EEPROM σε ενα array const, είναι λογικό , λόγω του ορισμού της Const?

----------


## klik

Ή είναι const ή δεν είναι!  :Tongue2: 
Μπορείς να γράψεις και στη ROM αν θέλεις :Biggrin:

----------


## picdev

τώρα βρήκα λύση, μπακαλίστικη, γιατί έχω πολύ ram,τα έβαλα στη ram.
αλλά γίνεται με κάποιο τρόπο να γράψω απο την eeprom στη rom??
θα μου πεις γιατί δεν τα διαβάζεις απο την eeprom και αυτό γίνεται αλλά θέλει αλλαγές.

στο stack λένε ότι δεν πρέπει να αλλάξει γιατί μπορεί να γίνει μλκ@#$ και ότι δεν είναι σύμφωνα με το specification ktl

εδώ λέει ότι γίνεται με pointer, τον pointer τον έχω έτοιμο έτσι και αλλιώς γιατί το 2δ const πίνακα τον δουλεύω με pointer
Αλλά έτσι και αλλιώς μου έχει γεμίσει η ROM, και έχω τη ram άδεια οπότε θα τα αφήσω στη ram αυτά, και αν δεν με παίρνει θα βάλω κάθε πίνακα με διαφορετική διάσταση 




```
const int const_var = 10; //Here we have declared our const variable. 

const int *p_const_var = &const_var; /*We passed the address of const_var to our pointer to const variable */ 

int i = 95; //temp variable to change the value. 

p_const_var = &i;
```




http://stackoverflow.com/questions/12104839/how-to-modify-value-of-const-variable

----------


## klik

> τώρα βρήκα λύση, μπακαλίστικη, γιατί έχω πολύ ram,τα έβαλα στη ram...



Στην eeprom μπορείς να έχεις όλους τους πίνακες και στη ram να φορτώνεις από την eeprom αυτόν που σε ενδειαφέρει
Φυσικά και μπορείς να διαβάζεις απ'ευθείας από την eeprom.




> αλλά γίνεται με κάποιο τρόπο να γράψω απο την eeprom στη rom??



TABLE WRITES (TABLAT στα PIC18F) αλλά δεν βλέπω το λόγο για την περίπτωση αυτή που έχεις.





> στο stack λένε ότι δεν πρέπει να αλλάξει γιατί μπορεί να γίνει μλκ@#$ και ότι δεν είναι σύμφωνα με το specification ktl



Αυτό (η παρά φύση αλλαγή περιεχομένου) γίνεται α) όταν δεν έχεις optimiztion ΚΑΙ (AND)  β) σε cpu με ίδιο memory array για data και code ΚΑΙ (AND) γ) ΧΩΡΙΣ hardware memory protection.

Δηλαδή σε 32bit compilers με την τυπική χρήση protected mode στο CPU δεν παίζει.
Φυσικά είναι εκτός προδιαγραφών στη C.

Ο optimizer είναι πιθανό για ακεραίους τύπου const να βάζει inline την τιμή όπου χρειάζεται και να μην έχει κρατήσει καθόλου χώρο στη RAM/ROM.

Υπάρχουν πολλές παράμετροι που δεν έχει νόημα να γράψω και θα δημιουργήσουν από πρόβλημα στην εκτέλεση έως  protection fault.

----------


## picdev

ναι δίκιο έχεις κλικ, μπορώ να χρησιμοποιώ και απο eprom ή να ορίσω και έναν πίνακα στη ραμ και να τον φορτώνω απο την eeprom κάθε φορά.
Αλλά δεν θέλω να πειράξω το πρόγραμμα γιατί θα πάω και άλλο πίσω και έχω αρκετά να κάνω, ετσι όπως το έχω δουλεύει,
3kb ραμ έχει και 64kb rom, δεν γεμίζει με τίποτα, γράφω κώδικα , βάζω συναρτήσεις μέσα σε συναρτήσεις , έχω φτάσει στα 20 source files, δεν μασάει το εργαλείο :Lol: 
και είμαι τόσο large που τους πίνακες τους έχω 2d ,αν βάλω διαφορετικό μέγεθος μπορούν να μικρύνουν, αλλά τώρα έχω έναν pointer για 2d και βολεύει ο κώδικας.

----------


## The_Control_Theory

Εχω χάσει κάποια πράγματα στην συνομιλία γιατί έχει πολύ πληροφορία. Θέλω να προσθέσω κάτι γενικά αλλά πολύ χρήσιμο.

Μικρές θαυματουργές συμβουλές για μιά βιβλιοθήκη τύπου ζεύγος *.h και *.c:


Προσπαθούμε να μην βάζουμε μεταβλητές χύμα μέσα γιατί τρώνε μνήμη. Οι λεγόμενες *global ή καθολικές μεταβλητές*. Το κάνουμε όταν είναι απολύτως αναγκαίο.Προσπαθούμε να βάζουμε τα πάντα στo *.c. Στο *.h βάζουμε μόνο ότι θα καλείτε από το υπόλοιπο πρόγραμμα. Αυτό ονομάζεται *εγκλεισμός και απόκρυψη δεδομένων* και είναι πολύ καλή πρακτική για bug-free αυτόνομες βιβλιοθήκες. Αυτό ισχύει για όλα. Συναρτήσεις, global μεταβλητες, #definitions κλπ κλπΔεν είδα πουθενά( μπορεί να κάνω λάθος γιατί υπάρχει πολύ πληροφορία ) για προστασία της header με #ifndef mpla_h \ #def mpla_h κλπ κλπ αλλιώς η βιβλιοθήκη θα φορτωνεται πολλές φορές στον κώδικα.Ενα *.h μπορεί να έχει πολλά *.c ώστε να γίνεται καλύτερη οργάνωση του κώδικα. Σπάνια όμως.Κάθε αρχείο *.c ή *.h θεωρούμαι ότι είναι ένα ξεχωριστό αρχείο και κάνουμε include μόνο ότι πρέπει. Ούτε παραπάνω include ούτε λιγότερα τα οποία μπορεί τα "βρίσκει από αλλού". 

Το πότε χρησιμοποιούμε τα static, extern, volatile, register και αν ξέχασα τίποτα άλλο keyword σε βιβλιοθήκες μπορούμε να το αναλύσουμε σε άλλο θέμα γιατί δεν είναι αναγκαίο για να δουλέψει μιά hello world βιβλιοθήκη.

Το lib είναι βιβλιοθήκη της οποίας το αρχείο *.c υπέστη compile και πλεόν έγινε γλώσσα μηχανής. Πλέον χρειαζόμαστε μόνο το *.h για να την καλέσουμε από το πρόγραμμά μας. Αν θυμάμαι καλά επειδή ποτέ δεν τις κάνω compile είναι με κατάληξη *.a στον GCC. Αυτό το εξήγησα λίγο χοντρικά αλλά αυτή είναι η ουσία.

----------

picdev (19-12-15)

----------


## klik

> ...Δεν είδα πουθενά( μπορεί να κάνω λάθος γιατί υπάρχει πολύ πληροφορία ) για προστασία της header με #ifndef mpla_h \ #def mpla_h κλπ κλπ αλλιώς η βιβλιοθήκη θα φορτωνεται πολλές φορές στον κώδικα...[/list]



Μήνυμα 15 με υπόδειγμα .h αρχειου: http://www.hlektronika.gr/forum/show...l=1#post687744





> Κάθε αρχείο *.c ή *.h θεωρούμαι ότι είναι ένα ξεχωριστό αρχείο και κάνουμε include μόνο ότι πρέπει. Ούτε παραπάνω include ούτε λιγότερα τα οποία μπορεί τα "βρίσκει από αλλού".[/list]



Μπορείς να κάνεις include όσα άχρηστα .h θέλεις. Αν δεν χρησιμοποιήσεις συναρτήσεις ή δεδομένα τους (external data), ο linker δεν θα τα συνδέσει το τελικό εκτελέσιμο/hex. Γι'αυτό στα std lib της C, κάθε συνάρτηση είναι σε δικό της .C αρχείο, ώστε να μην φορτώνονται όλες οι π.χ. str* αν εσύ θέλεις μόνο την strcpy

----------

picdev (19-12-15)

----------


## klik

Άσχετο, αλλά αν κάποιος ενδιαφέρεται για εξάσκηση στη C/C++/Java/Pascal σε επίλυση προβλημάτων, μπορεί από το site προετοιμασίας για τους εθνικούς και διεθνείς διαγωνισμούς (Βαλκανιάδα, Ολυμπιάδα) www.hellenico.gr να παίξει.
Αν κάποιος ενδιαφέρεται για προγραμματισμό και είναι εως λύκειο, μπορεί να δει και το site του εθνικου διαγωνισμού www.pdp.gr
Για αγγλόφωνους υπάρχει και το αντίστοιχο αμερικάνικο www.usaco.org για προετοιμασία (μπορεί να γραφτεί οποιοσδήποτε για να ασχοληθεί).

----------

picdev (19-12-15)

----------


## The_Control_Theory

> Μπορείς να κάνεις include όσα άχρηστα .h θέλεις. Αν δεν χρησιμοποιήσεις συναρτήσεις ή δεδομένα τους (external data), ο linker δεν θα τα συνδέσει το τελικό εκτελέσιμο/hex. Γι'αυτό στα std lib της C, κάθε συνάρτηση είναι σε δικό της .C αρχείο, ώστε να μην φορτώνονται όλες οι π.χ. str* αν εσύ θέλεις μόνο την strcpy



Ναι έχεις δίκιο αλλά χάνεις αυτονομία. Φαντάσου δύο ζευγάρια *.h και *.c. Το ένα βιβλιοθήκη για *lcd* και το άλλο βιβλιοθήκη για οδήγηση *stepper motor*.
Μπορείς μέσα στην lcd να κάνεις ένα include το stepper_motor.h και να μην χρησιμοποιήσεις ποτέ την βιβλιοθήκη από κει( μέσα από την lcd).
To stepper θα είναι επίσης include από την main.c.
Παρόλο η lcd δεν θα χρησιμοποιεί καμία συνάρτηση της stepper θα ζητάει να συμπεριλάβεις και τα αρχεία lcd.h και lcd.c.
Θα πεις δεν πειράζει κανένα πρόβλημα γιατί έτσι κι αλλιώς θα τα συμπεριέλαβα αφού to stepper_mottor το χρησιμοποιεί και η main.

Περνάνε 3 χρόνια από τότε και φτιάχνεις ένα νέο project με μόνο lcd οθόνη. Δεν θα θυμάσαι γιατί ζητάει και βιβλιοθήκη για stepper.
Η βιβλιοθήκη χάνει αυτονομία...

Το παράδειγμα της lcd και stepper είναι εμφανής θα πείτε. Φανταστείτε όμως να κάνεις 10 include και να μην θυμάσαι τι από αυτά θες?

----------


## klik

> Ναι έχεις δίκιο αλλά χάνεις αυτονομία. Φαντάσου δύο ζευγάρια *.h και *.c. Το ένα βιβλιοθήκη για *lcd* και το άλλο βιβλιοθήκη για οδήγηση *stepper motor*.
> Μπορείς μέσα στην lcd να κάνεις ένα include το stepper_motor.h και να μην χρησιμοποιήσεις ποτέ την βιβλιοθήκη από κει( μέσα από την lcd).
> To stepper θα είναι επίσης include από την main.c.
> Παρόλο η lcd δεν θα χρησιμοποιεί καμία συνάρτηση της stepper θα ζητάει να συμπεριλάβεις και τα αρχεία lcd.h και lcd.c.



Λάθος κάνεις, δεν υπάρχει ζήτηση δεδομένων/κώδικα και ο Linker ΔΕΝ θα σου φορτώσει τη stepper motor.
Σου εξήγησα το απλό παράδειγμα με τη strcpy. Εσύ κάνεις include το string.h για να χρησιμοποιήσεις τη strcpy. Νομίζεις ότι θα σου έρθει μαζί και η strcmp,strstr,strchr,strrchr? Δες το .map αρχείο σου να δεις ότι δεν έρχονται αυτά. Το ίδιο και με το step motor.

----------


## The_Control_Theory

Οχι δεν κάνω λάθος. Μιλάμε για δυό διαφορετικά πράγματα.

edit: Εγώ μιλάω για την περίπτωση που βάλεις #include stdlib.h και δεν χρησιμοποιήσεις ποτέ τελικά κάποια συνάρτηση από stdlib.
       Το stdlib είναι παράδειγμα. Βάλε αντί για stdlib το lcd.h. κάτι που να μην είναι στην βασική βιβλιοθήκη.

edit2: Θα σε αναγκάσει να κάνεις ή delete την γραμμή #include <lcd.h> ή να αναγκαστείς να προσθέσεις στο πρόγραμμά σου την άχρηστη βιβλιοθήκη.

edit3: Με το αναγκαστείς να προσθέσεις στο πρόγραμμα σου την άχρηστη βιβλιοθήκη δεν εννοώ θα την προσθέσει ο linker. Εννοώ θα την προσθέσεις εσύ στον IDE ή ότι χρησιμοποιείς makefile κλπ κλπ ενώ είναι άχρηστη.

----------


## klik

Φτιάχνω βιβλιοθήκη lib1a και αρχείο lib1a.h
lib1.jpg
Έχω περιλάβει 2 αρχεία .c, το ένα έχει μια μεγάλη συνάρτηση και έναν μεγάλο πίνακα. Το άλλο έχει μόνο μια μικρή συνάρτηση. Και τα δύο αρχεία περιγράφονται στο .h αρχείο,


Φτιάχνω εφαρμογή app1 και χρησιμοποιώ μόνο μια συνάρτηση (τη μικρή) από τη βιβλιοθήκη (οπότε τα υπόλοιπα αρχεία της βιβλιοθήκης με τα 2Κ data και 1Κ περίπου κώδικα, δεν φορτώνονται).
app1.png



Φτιάχνω εφαρμογή app2 που κάνω include το lib1a.h αλλά δεν καώ καμία συνάρτηση του lib1a. Δεν χρειάζεται ούτε στο IDE να βάλω το .lib αρχείο να φορτώνεται.
app2.jpg


Όσα include και να βάλεις, αν δεν ΚΑΛΕΣΕΙΣ συναρτήσεις τους ή δεδομένα τους, δεν θα επιβαρύνουν το πρόγραμμα σου. Αν κάνεις λάθος στη σχεδίαση της βιβλιοθήκης ή του header αρχείου, είναι άλλο θέμα. Ακολούθησε τις οδηγίες που έχω δώσει από την αρχή για σωστή σχεδίαση των .h αρχείων και δεν υπάρχει θέμα.

----------


## klik

Φυσικά αν επίτηδες ή κατά λάθος έχει *χρησιμοποιήσει* στοιχεία της βιβλιοθήκης, τότε πρέπει να κάνεις include το library.
app2b.jpg

----------


## The_Control_Theory

> Όσα include και να βάλεις, αν δεν ΚΑΛΕΣΕΙΣ συναρτήσεις τους ή δεδομένα τους, δεν θα επιβαρύνουν το πρόγραμμα σου. Αν κάνεις λάθος στη σχεδίαση της βιβλιοθήκης ή του header αρχείου, είναι άλλο θέμα. Ακολούθησε τις οδηγίες που έχω δώσει από την αρχή για σωστή σχεδίαση των .h αρχείων και δεν υπάρχει θέμα.



Πάντως εγώ δεν μιλάω γι' αυτό. Δεν ξέρω πως να το εξηγήσω αλλιώς. Πάντως για να κλείσουμε αυτό ότι λες εδώ είναι σωστό και συμφωνώ.

Εγώ μιλάω για εγκλεισμό και απόκρυψη δεδομένων. Όχι για το τι κάνει ο linker. Εσύ λες για τον linker και έχεις δίκιο. Αλλά κι εγώ έχω δίκιο και δεν καταλάβατε τι εννοώ.

----------

