Τα πάντα για την C

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό clepto » 19 Ιουν 2011, 14:55

Κώδικας: Επιλογή όλων
chris@chris-aspire5732z:~/C$ ./age2
Πόσο έχει σήμερα (η μ χ): 30 2 2011
Πότε γεννηθήκατε (η μ χ); 24 9 1995

Είστε 15 χρονών, 5 μηνών και 6 ημερών

press ENTER to exit...
chris@chris-aspire5732z:~/C$ ./age2
Πόσο έχει σήμερα (η μ χ): 19 6 2011
Πότε γεννηθήκατε (η μ χ); 24 9 2578

Είστε -568 χρονών, 8 μηνών και 25 ημερών

press ENTER to exit...
chris@chris-aspire5732z:~/C$
1 Γνώσεις Linux: Ικανοποιητικό ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Ικανοποιητικό
2 Ubuntu 13.04 raring 3.8.0-30-generic 64bit (en_US.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic, Windows 7
3 Intel Core i7-3537U CPU @ 2.00GHz ‖ RAM 3840 MiB ‖ ASUS K56CB
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 wlan0: Atheros Inc. AR9485 Wireless Network Adapter [168c:0032] (rev 01) ⋮ eth0: Realtek RTL8111/8168 PCI Express Gigabit Ethernet controller [10ec:8168] (rev 0a)
clepto
antiwinTUX
antiwinTUX
 
Δημοσιεύσεις: 4102
Εγγραφή: 07 Ιαν 2010, 16:27
Τοποθεσία: Πάτρα
Launchpad: christriant
IRC: Clepto
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 19 Ιουν 2011, 19:38

Μα αυτό δεν είπα; Πρέπει η 2η ημερομηνία να είναι μικρότερη της 1ης (και πρέπει να μπει έλεγχος για αυτό)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό clepto » 19 Ιουν 2011, 19:51

από βιασύνη μου κατάλαβα λάθος...εντάξει!ας το να το προσπαθήσω εγώ...
1 Γνώσεις Linux: Ικανοποιητικό ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Ικανοποιητικό
2 Ubuntu 13.04 raring 3.8.0-30-generic 64bit (en_US.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic, Windows 7
3 Intel Core i7-3537U CPU @ 2.00GHz ‖ RAM 3840 MiB ‖ ASUS K56CB
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 wlan0: Atheros Inc. AR9485 Wireless Network Adapter [168c:0032] (rev 01) ⋮ eth0: Realtek RTL8111/8168 PCI Express Gigabit Ethernet controller [10ec:8168] (rev 0a)
clepto
antiwinTUX
antiwinTUX
 
Δημοσιεύσεις: 4102
Εγγραφή: 07 Ιαν 2010, 16:27
Τοποθεσία: Πάτρα
Launchpad: christriant
IRC: Clepto
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό clepto » 19 Ιουν 2011, 20:07

να ρωτήσω, τι κάνει αυτό;
Κώδικας: Επιλογή όλων
#define isleap(y) ( !((y) % 4) && ( (y) % 100 || !((y) % 400) ) )


πρόσθεσα αυτό αλλά παίρνω Segmentation fault
Κώδικας: Επιλογή όλων
// έλεγχος με do while για την δευτερη ημερομηνια
do {
printf("Πότε γεννηθήκατε (η μ χ); ");
scanf("%d %d %d", &d2, m2, y2);
} while( y2>y1 );
Τελευταία επεξεργασία από clepto και 19 Ιουν 2011, 20:23, έχει επεξεργασθεί 1 φορά/ες συνολικά
1 Γνώσεις Linux: Ικανοποιητικό ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Ικανοποιητικό
2 Ubuntu 13.04 raring 3.8.0-30-generic 64bit (en_US.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic, Windows 7
3 Intel Core i7-3537U CPU @ 2.00GHz ‖ RAM 3840 MiB ‖ ASUS K56CB
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 wlan0: Atheros Inc. AR9485 Wireless Network Adapter [168c:0032] (rev 01) ⋮ eth0: Realtek RTL8111/8168 PCI Express Gigabit Ethernet controller [10ec:8168] (rev 0a)
clepto
antiwinTUX
antiwinTUX
 
Δημοσιεύσεις: 4102
Εγγραφή: 07 Ιαν 2010, 16:27
Τοποθεσία: Πάτρα
Launchpad: christriant
IRC: Clepto
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 19 Ιουν 2011, 20:23

Επιστρέφει TRUE αν το y είναι δίσεκτο έτος, αλλιώς επιστρέφει FALSE.

Επίσης δεν είμαι σίγουρος αν είναι σωστή η γραμμή 32 του κώδικα
Κώδικας: Επιλογή όλων

if ( m2 == 2 && isleap(y2) )


Ίσως θέλει κι άλλους ελέγχους, αλλά μόλις γύρισα από μπάνιο (έχω πιει και κάτι ούζα, έχω φάει και τον άμπακο :lol:) και δεν είμαι για πολλές σπαζοκεφαλιές τώρα. Θα σου κάνω τον έλεγχο για το αν η 2η ημερομηνία είναι μικρότερη της 1ης αν θέλεις, αλλά νομίζω πρώτα είναι πιο χρήσιμο να λύσουμε απορίες που έχεις στον μέχρι τώρα κώδικα.

Π.χ. κατάλαβες γιατί έβαλα τον πίνακα mdays[] με τις ημέρες του κάθε μήνα και πως τον χρησιμοποιώ μετά;
clepto έγραψε:να ρωτήσω, τι κάνει αυτό;
Κώδικας: Επιλογή όλων
#define isleap(y) ( !((y) % 4) && ( (y) % 100 || !((y) % 400) ) )
Τελευταία επεξεργασία από migf1 και 19 Ιουν 2011, 20:32, έχει επεξεργασθεί 1 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 19 Ιουν 2011, 20:31

Έχεις ξεχάσει τα & μπροστά από τα m2 και y2, στην scanf().

ΥΓ. Δεν αρκεί μόνο αυτός ο έλεγχος, θέλει και για τους μήνες (ακόμα κι αν είναι κι οι 2 στο ίδιο έτος)

clepto έγραψε:πρόσθεσα αυτό αλλά παίρνω Segmentation fault
Κώδικας: Επιλογή όλων
// έλεγχος με do while για την δευτερη ημερομηνια
do {
printf("Πότε γεννηθήκατε (η μ χ); ");
scanf("%d %d %d", &d2, m2, y2);
} while( y2>y1 );
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό clepto » 19 Ιουν 2011, 20:35

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


migf1 έγραψε:Έχεις ξεχάσει τα & μπροστά από τα m2 και y2, στην scanf().

ΥΓ. Δεν αρκεί μόνο αυτός ο έλεγχος, θέλει και για τους μήνες (ακόμα κι αν είναι κι οι 2 στο ίδιο έτος)

clepto έγραψε:πρόσθεσα αυτό αλλά παίρνω Segmentation fault
Κώδικας: Επιλογή όλων
// έλεγχος με do while για την δευτερη ημερομηνια
do {
printf("Πότε γεννηθήκατε (η μ χ); ");
scanf("%d %d %d", &d2, m2, y2);
} while( y2>y1 );
λάθος βιασύνης...θα κοιτάξω και για τους μήνες...
1 Γνώσεις Linux: Ικανοποιητικό ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Ικανοποιητικό
2 Ubuntu 13.04 raring 3.8.0-30-generic 64bit (en_US.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic, Windows 7
3 Intel Core i7-3537U CPU @ 2.00GHz ‖ RAM 3840 MiB ‖ ASUS K56CB
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 wlan0: Atheros Inc. AR9485 Wireless Network Adapter [168c:0032] (rev 01) ⋮ eth0: Realtek RTL8111/8168 PCI Express Gigabit Ethernet controller [10ec:8168] (rev 0a)
clepto
antiwinTUX
antiwinTUX
 
Δημοσιεύσεις: 4102
Εγγραφή: 07 Ιαν 2010, 16:27
Τοποθεσία: Πάτρα
Launchpad: christriant
IRC: Clepto
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 19 Ιουν 2011, 20:47

Για να μην σπαζοκεφαλιάσεις κι εσύ τσάμπα, να σου πω πως για να βρίσκεις αν μια ημερομηνία είναι μικρότερη ή μεγαλύτερη μιας άλλης, ο πιο συνηθισμένος τρόπος είναι να τις μετατρέπεις σε Ιουλιανούς αριθμούς (Julian Day Number ή Julian Day Count)... δεν έχει σχέση με το Ιουλιανό ημερολόγιο. Τους οποίους τους αποθηκεύεις σε μεταβλητές τύπου long.

Ο μαθηματικός αλγόριθμος μετατροπής οποιασδήποτε ημερομηνίας σε Ιουλιανό αριθμό είναι ο παρακάτω:

Κώδικας: Επιλογή όλων

JDN = ( 1461 * ( y + 4800 + ( m - 14 ) / 12 ) ) / 4 +
( 367 * ( m - 2 - 12 * ( ( m - 14 ) / 12 ) ) ) / 12 -
( 3 * ( ( y + 4900 + ( m - 14 ) / 12 ) / 100 ) ) / 4 +
d - 32075;
όπου d, m, y η ημέρα, ο μήνας και το έτος μιας οποιασδήποτε ημερομηνίας μεγαλύτερης ή ίσης της 15 Οκτ 1582.

Αντίστοιχα, ο μαθηματικός αλγόριθμος για να μετατρέψεις έναν Ιουλιανό αριθμό σε κανονική ημερομηνία, μεγαλύτερης ή ίσης της 15 Οκτ 1582 είναι ο παρακάτω:
Κώδικας: Επιλογή όλων

l = JDN + 68569;
n = ( 4 * l ) / 146097;
l = l - ( 146097 * n + 3 ) / 4;
i = ( 4000 * ( l + 1 ) ) / 1461001;
l = l - ( 1461 * i ) / 4 + 31;
j = ( 80 * l ) / 2447;
D = l - ( 2447 * j ) / 80;
l = j / 11;
M = j + 2 - ( 12 * l );
Y = 100 * ( n - 49 ) + i + l;

όπου JDN ο Ιουλιανός αριθμός και όπου D, M , Y η ημέρα, ο μήνας και το έτος της ημερομηνίας.

Για να βρεις σε ποια ημέρα της εβδομάδας αντιστοιχεί μια οποιαδήποτε ημερομηνία, διαιρείς τον Ιουλιανό της αριθμό με το 7 και εξετάζεις το υπόλοιπο της διαίρεσης, όπου το 0 αντιστοιχεί στη Δευτέρα και το 6 στην Κυριακή...
Κώδικας: Επιλογή όλων

weekday = jdn % 7; // 0 = Δευτέρα, ..., 6 = Κυριακή
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό clepto » 19 Ιουν 2011, 20:53

χρήσιμο αυτό....
ευχαριστώ για την βοήθεια!
1 Γνώσεις Linux: Ικανοποιητικό ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Ικανοποιητικό
2 Ubuntu 13.04 raring 3.8.0-30-generic 64bit (en_US.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic, Windows 7
3 Intel Core i7-3537U CPU @ 2.00GHz ‖ RAM 3840 MiB ‖ ASUS K56CB
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 wlan0: Atheros Inc. AR9485 Wireless Network Adapter [168c:0032] (rev 01) ⋮ eth0: Realtek RTL8111/8168 PCI Express Gigabit Ethernet controller [10ec:8168] (rev 0a)
clepto
antiwinTUX
antiwinTUX
 
Δημοσιεύσεις: 4102
Εγγραφή: 07 Ιαν 2010, 16:27
Τοποθεσία: Πάτρα
Launchpad: christriant
IRC: Clepto
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 19 Ιουν 2011, 21:20

clepto έγραψε:ναι κατάλαβα τον πίνακα...δεν έχω καταλάβει πλήρως πως το χρησιμοποιείς...


Στον κώδικά σου είχες ήδη υπολογίσει σωστά πως αν η διαφορά των ημερών είναι αρνητική, τότε πρέπει να προστεθεί στο 30 (και να αφαιρεθεί 1 μήνας).

Αλλά οι μήνες δεν έχουν όλοι 30 ημέρες, οπότε στον υπολογισμό σου όταν π.χ. ο m2 είναι Ιανουάριος, τότε η διαφορά των ημερών πρέπει να προστεθεί στο 31 (αντί του 30). Ομοίως, αν ο m2 είναι Φεβρουάριος, τότε πρέπει να προστεθεί στο 28 (ή στο 29 αν είναι σε δίσεκτο έτος) και ούτω κάθε εξής.

Οπότε φτιάξαμε έναν πίνακα mdays[12] να περιέχει το πλήθος ημερών όλων των μηνών, σε μη δίσεκτα έτη.

Επειδή όμως στη C τα στοιχεία των πινάκων ξεκινάνε από την θέση 0 (και όχι από τη θέση 1) το πλήθος ημερών π.χ. του Ιανουαρίου αντιστοιχεί στο:
Κώδικας: Επιλογή όλων

mdays[0]; // και όχι στο mdays[1]... αυτό περιέχει το πλήθος ημερών του Φεβρουαρίου


Άρα, όταν ο χρήστης σου περάσει στη μεταβλητή m2 για μήνα π.χ. τον Ιανουάριο (τον αριθμό 1 δηλαδή), για να βρεις το πλήθος ημερών που του αντιστοιχούν στον πίνακα mdays[] πρέπει να αφαιρέσεις 1 από το m2:
Κώδικας: Επιλογή όλων

mdays[ m2-1 ];
κι εννοείται πως έχεις ήδη ελέγξει το m2 που σου έδωσε ο χρήστης να είναι ακέραιος από 1 έως 12 !

Επίσης, αν το m2 είναι 2 (Φεβρουάριος) , τότε βάση του πίνακά μας, το...
Κώδικας: Επιλογή όλων

mdays[ m2-1];
θα σου δώσει 28, αλλά κατόπιν πρέπει να ελεγχθεί αν πρόκειται για Φεβρουάριο δίσεκτου έτους, περίπτωση κατά την οποία πρέπει να προστεθεί άλλο 1 στο days (εκείνο το days++). Αλλά νομίζω πως ο έλεγχος που έχω βάλει για Φεβ δίσεκτου έτους ΔΕΝ είναι επαρκής (δεν είμαι σίγουρος, θέλει τσεκάρισμα με καθαρό μυαλό).

Το αν ένα έτος είναι δίσεκτο ή όχι, το βρίσκεις με το macro isleap(y) που με ρώτησες παραπάνω τι κάνει. Βασικά είναι ο μαθηματικός αλγόριθμος για να βρίσκεις αν το έτος y είναι δίσεκτο ή όχι (αν δεν σου αρέσει ως macro, μπορείς να το κάνεις συνάρτηση).

ΥΓ. Όλα αυτά και πολύ περισσότερα, τα έχω κάνει στο ολοκληρωμένο πρόγραμμα που έχω ποστάρει με κώδικα εδώ: viewtopic.php?f=6&t=18996 (αν θες να πάρεις ιδέες δηλαδή).
Τελευταία επεξεργασία από migf1 και 19 Ιουν 2011, 21:30, έχει επεξεργασθεί 1 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι