Προς το περιεχόμενο

Ερωτήσεις για C


capoelo

Προτεινόμενες αναρτήσεις

Για να μην ανοιγω αλλο thread...O αλγοριθμος είναι καποιος απο τους γνωστούς αλγοριθμους ταξινόμησης;

 


Function Find( array , first , last )
  if (last-first == 0) return Α[first];
  mid = floor((first+last)/2);
  for j = first to mid do {
      if (Α[j] < Α[j+mid]) then {
       swap A[j], A[j+1]        
      }
    }
   max = Find(Α, first , mid);
   return max;
}
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Το εφτιαξα, ηταν τυπωγραφικό λαθος...

Θα κοιταξω αυτο που  μου ειπες και θα δω αν μπορω να καταλαβω τι παιζει..

Αυτο που με μπερδευει ειναι οτι αντιμεταθετει διαφορετικα στοιχεια απο αυτα που ελεγψει αν ειναι ' < '  

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επομένως, αν ο κώδικάς μας πρόκειται να γίνει compile με διαφορετικούς compilers (είτε από εμάς είτε από τρίτους) ο μόνος τρόπος να σιγουρέψουμε πως θα γίνονται πάντα inline τα σημεία που θέλουμε, είναι να τα γράψουμε στον προεπεξεργαστή.

 

Ο πυρήνας του Linux που αναφέρθηκε, είναι κλασσικό τέτοιο παράδειγμα... όπου δηλαδή δεν είναι λογικό να επαφίενται τα κρίσιμα κομμάτια του κώδικα στις ορέξεις (ή μη) του εκάστοτε compiler.

Επειδή το θέμα preprocessor το έχουμε αναλύσει για πολλά μηνύματα στο παρελθόν, απλά να πω ότι στο πλαίσιο του φόρουμ διαφωνώ με την παραπάνω πρόταση.

 

Το γεγονός ότι το linux ακολουθεί μια πρακτική δεν είναι ικανός λόγος για κάποιον αρχάριο που διαβάζει το φόρουμ να κάνει το ίδιο. Αυτοί που αναπτύσσουν το linux έχουν μια κάποια εμπειρία παραπάνω που τους επιτρέπει να κάνουν κόλπα με τον preprocessor χωρίς να προκύπτουν προβλήματα (και αυτό όχι πάντα).

 

Επίσης, η χρήση macros δεν γίνεται για να μην "επαφίενται κρίσιμα κομμάτια του κώδικα στις ορέξεις του compiler" μια και το linux γίνεται (ακόμη) compile μόνο με τον gcc. Σε ένα μεγάλο ποσοστό, τα τρελά macros μπαίνουν λόγω διαφορετικής συμπεριφοράς αρχιτεκτονικών και όχι compilers. Το Χ τμήμα κώδικα για να καλύπτει όλες τις αρχιτεκτονικές μπορεί να γραφτεί δόκιμα με μια σειρά συναρτήσεων (ή enums ή οτιδήποτε) ή με ένα σύντομο αλλά πολύπλοκο και άσχημο macro. Μια και η ανάπτυξη του πυρήνα δεν απευθύνεται σε αρχάριους, το κόστος της readability είναι μικρό μπροστά στο κόπο που θα γλυτώσει ο developer για αυτό και προτιμάται το macro.

 

Στο πλαίσιο του φόρουμ καλό είναι να αποφεύγεται ο preprocessor όταν αυτό είναι εφικτό.

  • Like 2
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Απλά ο κώδικας της συνάρτησης αντικαθιστά το function call. Είναι σαν μέσα στο function απο όπου καλείς το inline function, απλά να είχες τον κώδικα στη θέση του function. Έτσι γλιτώνεις το function overhead....οπότε αν καλείς μια συναρτησούλα 800 φορές είναι καλό να την ορίσεις ως inline (αν και θα την κάνει ο compiler λογικά) .

 

Καταλαβα. Αρα αν κάποια συναρτηση γινει inline τοτε μπορουμε να γλιτώσουμε κοστος σε μνήμη ... Το function code segment δεν υφισταται?

 

http://www.parashift.com/c++-faq/inline-and-perf.html

 

εδω λεει οτι δεν υπαρχουν απλες απαντησεις παντως σε αυτα :P

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

...

 

Επίσης, η χρήση macros δεν γίνεται για να μην "επαφίενται κρίσιμα κομμάτια του κώδικα στις ορέξεις του compiler" μια και το linux γίνεται (ακόμη) compile μόνο με τον gcc. Σε ένα μεγάλο ποσοστό, τα τρελά macros μπαίνουν λόγω διαφορετικής συμπεριφοράς αρχιτεκτονικών και όχι compilers. Το Χ τμήμα κώδικα για να καλύπτει όλες τις αρχιτεκτονικές μπορεί να γραφτεί δόκιμα με μια σειρά συναρτήσεων (ή enums ή οτιδήποτε) ή με ένα σύντομο αλλά πολύπλοκο και άσχημο macro. Μια και η ανάπτυξη του πυρήνα δεν απευθύνεται σε αρχάριους, το κόστος της readability είναι μικρό μπροστά στο κόπο που θα γλυτώσει ο developer για αυτό και προτιμάται το macro.

 

Στο πλαίσιο του φόρουμ καλό είναι να αποφεύγεται ο preprocessor όταν αυτό είναι εφικτό.

Παρόλο που δεν διαφωνώ πως η "αρχιτεκτονική" είναι πιο εύστοχη σαν παρατήρηση από τον "compiler", εν τούτοις κανείς δεν εγγυάται (και πολύ περισσότερο δεν υποχρεώνει) τους κατασκευαστές ενός compiler να κάνουν inline τα ίδια πράγματα σε διαφορετικές εκδόσεις του ίδιου compiler. Εννοώ πως το πρότυπο το αφήνει ελεύθερο. Επίσης, παρόλο που δεν έχω ψαχτεί ειδικά για το inlining στον gcc, είναι 100% σίγουρο πως έχουν παρουσιαστεί ασυμβατότητες σε διάφορα (που δεν τα θυμάμαι απέξω, αλλά δεν είναι δύσκολο να τα αναζητήσει κανείς στο google) μεταξύ διαφορετικών εκδόσεων του gcc, ειδικά στο optimization. Πόσο μάλιστα στις διάφορες υλοποιήσεις ακόμα και της ίδιας έκδοσης σε διαφορετικές πλατφόρμες (εδώ κολλάει και η αρχιτεκτονική μαζί με τον compiler).

 

Σχετικά με το "πλαίσιο του φόρουμ" (μιας και το θίγεις για 2η ή 3η φορά) προσωπικά δεν αντιλαμβάνομαι τι το ειδικό έχει το συγκεκριμένο φόρουμ συγκριτικά με οποιοδήποτε άλλο φόρουμ προγραμματισμού, εντός κι εκτός Ελλάδας. Αναγράφεται πουθενά κάποιος περιορισμός στους κανονισμούς αυτού εδώ του φόρουμ πως π.χ. απευθύνεται μονάχα σε αρχάριους ή πως π.χ. είναι ανεπιθύμητα, αποπροσανατολιστικά ή ότι άλλο μηνύματα που αναδεικνύουν πιο προχωρημένα θέματα και τεχνικές;

 

Αν υπάρχει κάποια τέτοια γραμμή, παρακαλώ να μου το πείτε για να την γνωρίζω στο εξής, ώστε να αποφεύγω να συμμετέχω σε νήματα που άπτονται σε κώδικες δυσκολότερους π.χ. του "hello world".

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καταλαβα. Αρα αν κάποια συναρτηση γινει inline τοτε μπορουμε να γλιτώσουμε κοστος σε μνήμη ... Το function code segment δεν υφισταται?

 

http://www.parashift.com/c++-faq/inline-and-perf.html

 

εδω λεει οτι δεν υπαρχουν απλες απαντησεις παντως σε αυτα :P

Φυσικά και δεν είναι απλό το θέμα. Μπορεί αντί να κάνει καλό το inlining κάλλιστα να κάνει κακό για αυτό το λόγο στους περισσότερους compilers ο όρος inline είναι hint και όχι νόμος. Το ίδιο έγινε και με το register. Υπήρξαν άπειρες περιπτώσεις που το register έκανε κακό αντί για καλό οπότε σταμάτησαν να το σέβονται οι compilers.

Σχετικά με το "πλαίσιο του φόρουμ" (μιας και το θίγεις για 2η ή 3η φορά) προσωπικά δεν αντιλαμβάνομαι τι το ειδικό έχει το συγκεκριμένο φόρουμ συγκριτικά με οποιοδήποτε άλλο φόρουμ προγραμματισμού, εντός κι εκτός Ελλάδας. Αναγράφεται πουθενά κάποιος περιορισμός στους κανονισμούς αυτού εδώ του φόρουμ πως π.χ. απευθύνεται μονάχα σε αρχάριους ή πως π.χ. είναι ανεπιθύμητα, αποπροσανατολιστικά ή ότι άλλο μηνύματα που αναδεικνύουν πιο προχωρημένα θέματα και τεχνικές;

 

Αν υπάρχει κάποια τέτοια γραμμή, παρακαλώ να μου το πείτε για να την γνωρίζω στο εξής, ώστε να αποφεύγω να συμμετέχω σε νήματα που άπτονται σε κώδικες δυσκολότερους π.χ. του "hello world".

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

 

Μήπως αντί να βάζεις στο στόμα μου πράγματα που δεν έχω πει και αντί να χρησιμοποιείς ειρωνικές υπερβολές τύπου "δυσκολότερους κώδικες του hello world" να δοκίμαζες κάποια φορά να έχεις επιχειρήματα ? Μπορεί να σου αρέσει.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

...

Μήπως αντί να βάζεις στο στόμα μου πράγματα που δεν έχω πει και αντί να χρησιμοποιείς ειρωνικές υπερβολές τύπου "δυσκολότερους κώδικες του hello world" να δοκίμαζες κάποια φορά να έχεις επιχειρήματα ? Μπορεί να σου αρέσει.

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

Λοιπον δοκιμασα να λυσω μια ασκηση που λεει οτι υποθετουμε οτι οι ακολουθες μακροεντολές βρισκονται σε ισχυ :

 

 

 
#define IDENT(x) PRAGMA(ident #x)
#define PRAGMA(x) _PRAGMA(#x)
 

 

Πως θα μοιάζει η ακολουθη γραμμή μετα την επέκταση

 

 
IDENT(foo)
 

 

 

 

Την δοκιμασα στο χαρτι.... πιστευω οτι αρχικα γινεται η επεκταση

 

με IDENT(foo) -> PRAGMA(ident "foo")

 

μετα επεκτεινεται η PRAGMA μακροεντολή κανοντας αποστρινγκοποιηση :P στο foo και αφηνοντας πισω την οδηγια #pragma δηλαδη :

 

#pragma ident foo

 

οπου λογικα το ident θα πρεπει να ειναι οδηγια στον μεταγλωτιστη για να κανει ident στην foo?

 

δοκιμασα με gcc -E αρχειο.c να δω την λυση αλλα εχει σφαλμα μεταγλωτισης : tests.cpp:8: error: ‘_PRAGMA’ was not declared in this scope

 

 

 
#include<stdio.h>
#define IDENT(x) PRAGMA(ident #x)
#define PRAGMA(x) _PRAGMA(#x)
void foo();

int main(void)
{
    IDENT(foo);
    
    return 0;
}
void foo()
{
puts("Hello");

return;
}
 
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επειδη κοντευω να τρελαθώ...Πειτε μου με σιγουρια αν ειναι αυτος ο αλγοριθμος λανθασμενος....

 

Function Find( array , first , last )
  if (last-first == 0) return Α[first];
  mid = floor((first+last)/2);
  for j = first to mid do {
      if (Α[j] < Α[j+mid]) then {
       swap A[j], A[j+1]        
      }
    }
   max = Find(Α, first , mid);
   return max;
}
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Πέρνα στη συνάρτηση ένα πινάκα , και δες την Find.

Μετά ανακάτεψε τα στοιχεία του και δες αν αλλάξει η Find. Αν αλλάξει τότε σίγουρα είναι λάθος. 

 

Αν δεν αλλάζει τότε κάνε πολλές δοκιμές να παρατηρήσεις  τι σου επιστρέφει.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Λοιπον δοκιμασα να λυσω μια ασκηση που λεει οτι υποθετουμε οτι οι ακολουθες μακροεντολές βρισκονται σε ισχυ :

 

 

 

 
#define IDENT(x) PRAGMA(ident #x)
#define PRAGMA(x) _PRAGMA(#x)

    IDENT(foo);

 

 

Λογικά θα πρέπει να πάει ως εξής: Η έκφραση IDENT(foo) θα μετασχηματιστεί σε PRAGMA(ident "foo"). Ό,τι περιείχε το macro δηλαδή απλά με το foo να μπαίνει σε εισαγωγικά λόγω του # τελεστή. Έπειτα η έκφραση PRAGMA θα μετασχηματιστεί σε _PRAGMA με το όρισμα της να μπαίνει σε εισαγωγικά και πάλι λόγο του # τελεστή.

 

Έτσι η τελική έκφραση θα πρέπει να είναι _PRAGMA("ident \"foo\"").

 

Επειδη κοντευω να τρελαθώ...Πειτε μου με σιγουρια αν ειναι αυτος ο αλγοριθμος λανθασμενος....

 

 

Function Find( array , first , last )
  if (last-first == 0) return Α[first];
  mid = floor((first+last)/2);
  for j = first to mid do {
      if (Α[j] < Α[j+mid]) then {
       swap A[j], A[j+1]        
      }
    }
   max = Find(Α, first , mid);
   return max;
}

 

 

Παραβλέποντας το γεγονός ότι ο παραπάνω κώδικας δεν είναι C, για να βοηθήσουμε πρέπει να ξέρουμε τι θέλεις να κάνεις. Αν προσπαθείς να υλοποιήσεις την quicksort, τότε ναι είναι λανθασμένος.

 

Edit: Τώρα διάβασα τα μηνύματα του albNik και είδα ότι θέλεις να βρίσκεις το μέγιστο. Δοκίμασες όπως είπε να πετάξεις διάφορα arrays πάνω να δεις αν παίζει σωστά ? Με ένα πολύ γρήγορο τεστ που έκανα δείχνει να παίζει σωστά και να βρίσκει το μέγιστο. Θα μπορούσες όμως να το κάνεις χωρίς να πειράζεις τον πίνακα.

 

Μόλις άλλαξα λίγο το array δεν μου βρήκε το σωστό μέγιστο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Λογικά θα πρέπει να πάει ως εξής: Η έκφραση IDENT(foo) θα μετασχηματιστεί σε PRAGMA(ident "foo"). Ό,τι περιείχε το macro δηλαδή απλά με το foo να μπαίνει σε εισαγωγικά λόγω του # τελεστή. Έπειτα η έκφραση PRAGMA θα μετασχηματιστεί σε _PRAGMA με το όρισμα της να μπαίνει σε εισαγωγικά και πάλι λόγο του # τελεστή.

 

Έτσι η τελική έκφραση θα πρέπει να είναι _PRAGMA("ident \"foo\"").

 Παραβλέποντας το γεγονός ότι ο παραπάνω κώδικας δεν είναι C, για να βοηθήσουμε πρέπει να ξέρουμε τι θέλεις να κάνεις. Αν προσπαθείς να υλοποιήσεις την quicksort, τότε ναι είναι λανθασμένος.

 

Edit: Τώρα διάβασα τα μηνύματα του albNik και είδα ότι θέλεις να βρίσκεις το μέγιστο. Δοκίμασες όπως είπε να πετάξεις διάφορα arrays πάνω να δεις αν παίζει σωστά ? Με ένα πολύ γρήγορο τεστ που έκανα δείχνει να παίζει σωστά και να βρίσκει το μέγιστο. Θα μπορούσες όμως να το κάνεις χωρίς να πειράζεις τον πίνακα.

 

Μόλις άλλαξα λίγο το array δεν μου βρήκε το σωστό μέγιστο.

 

Δεν θέλω να κάνω κάτι...Απλα μου δίνεται αυτός ο αλγόριθμος και πρέπει να αναλύσω το τι κάνει...Εχω την εντύπωση ότι ειναι όμως λάθος...Για αυτό ρωτάω ...δεν μπορω με τπτ να καταλαβω τι κανει!

 

 

Στα σχόλια αναφέρει ότι επιστέφει το μεγιστο...Και απλα ζητάει περισσοτερη αναλυση!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...