portaldacalheta.pt
  • Κύριος
  • Επιστήμη Δεδομένων Και Βάσεις Δεδομένων
  • Κερδοφορία & Αποδοτικότητα
  • Σχεδιασμός Ux
  • Κινητό
Πίσω Μέρος

Κορυφαία 10 πιο συνηθισμένα λάθη C ++ που κάνουν οι προγραμματιστές



Υπάρχουν πολλές παγίδες που α Προγραμματιστής C ++ μπορεί να συναντήσει. Αυτό μπορεί να κάνει τον ποιοτικό προγραμματισμό πολύ σκληρό και η συντήρηση πολύ ακριβή. Η εκμάθηση της σύνταξης γλωσσών και η καλή ικανότητα προγραμματισμού σε παρόμοιες γλώσσες, όπως C # και Java, δεν αρκεί για να αξιοποιήσουμε πλήρως τις δυνατότητες του C ++. Απαιτεί χρόνια εμπειρίας και μεγάλη πειθαρχία για την αποφυγή σφαλμάτων στο C ++. Σε αυτό το άρθρο, θα ρίξουμε μια ματιά σε μερικά από τα κοινά λάθη που γίνονται από προγραμματιστές όλων των επιπέδων εάν δεν είναι αρκετά προσεκτικοί με την ανάπτυξη C ++.

Κοινό λάθος # 1: Λανθασμένη χρήση ζευγαριών 'νέων' και 'διαγραφής'

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



void SomeMethod() { ClassA *a = new ClassA; SomeOtherMethod(); // it can throw an exception delete a; }

Εάν δημιουργηθεί μια εξαίρεση, το αντικείμενο 'a' δεν διαγράφεται ποτέ. Το ακόλουθο παράδειγμα δείχνει έναν ασφαλέστερο και συντομότερο τρόπο για να το κάνετε αυτό. Χρησιμοποιεί το auto_ptr το οποίο έχει καταργηθεί στο C ++ 11, αλλά το παλιό πρότυπο εξακολουθεί να χρησιμοποιείται ευρέως. Μπορεί να αντικατασταθεί με C ++ 11 unique_ptr ή scoped_ptr από το Boost εάν είναι δυνατόν.



void SomeMethod() { std::auto_ptr a(new ClassA); // deprecated, please check the text SomeOtherMethod(); // it can throw an exception }

Ανεξάρτητα από το τι συμβαίνει, μετά τη δημιουργία του αντικειμένου 'a' θα διαγραφεί μόλις η εκτέλεση του προγράμματος βγει από το πεδίο εφαρμογής.



Ωστόσο, αυτό ήταν μόνο το απλούστερο παράδειγμα αυτού του προβλήματος C ++. Υπάρχουν πολλά παραδείγματα όταν η διαγραφή πρέπει να γίνει σε κάποιο άλλο μέρος, ίσως σε εξωτερική λειτουργία ή σε άλλο νήμα. Αυτός είναι ο λόγος για τον οποίο η χρήση νέου / διαγραφής σε ζεύγη θα πρέπει να αποφεύγεται εντελώς και θα πρέπει να χρησιμοποιούνται κατάλληλοι έξυπνοι δείκτες.

Κοινό λάθος # 2: Ξεχασμένος εικονικός καταστροφέας

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



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

Ένα επιπλέον σημείο για το θέμα είναι τάξεις / πρότυπα από την τυπική βιβλιοθήκη. Δεν προορίζονται για κληρονομιά και δεν έχουν εικονικό καταστροφέα. Εάν, για παράδειγμα, δημιουργήσουμε μια νέα βελτιωμένη κλάση συμβολοσειράς που κληρονομεί δημόσια από το std :: string υπάρχει πιθανότητα κάποιος να το χρησιμοποιήσει εσφαλμένα με ένα δείκτη ή μια αναφορά στο std :: string και να προκαλέσει διαρροή μνήμης.



class MyString : public std::string { ~MyString() { // ... } }; int main() { std::string *s = new MyString(); delete s; // May not invoke the destructor defined in MyString }

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

Κοινό λάθος # 3: Διαγραφή μιας σειράς με 'διαγραφή' ή χρήση ενός έξυπνου δείκτη

Κοινό λάθος # 3

c corporation έναντι s corporation

Η δημιουργία προσωρινών συστοιχιών δυναμικού μεγέθους είναι συχνά απαραίτητη. Αφού δεν απαιτούνται πια, είναι σημαντικό να ελευθερώσετε την εκχωρημένη μνήμη. Το μεγάλο πρόβλημα εδώ είναι ότι το C ++ απαιτεί ειδικό τελεστή διαγραφής με αγκύλες [], κάτι που ξεχνά πολύ εύκολα. Ο τελεστής διαγραφής [] δεν θα διαγράψει μόνο τη μνήμη που έχει εκχωρηθεί για έναν πίνακα, αλλά θα καλέσει πρώτα τους καταστροφείς όλων των αντικειμένων από έναν πίνακα. Είναι επίσης λανθασμένο να χρησιμοποιείτε τον τελεστή διαγραφής χωρίς αγκύλες [] για πρωτόγονους τύπους, παρόλο που δεν υπάρχει καταστροφέας για αυτούς τους τύπους. Δεν υπάρχει καμία εγγύηση για κάθε μεταγλωττιστή ότι ένας δείκτης σε έναν πίνακα θα δείξει το πρώτο στοιχείο του πίνακα, οπότε η χρήση αγκυλών διαγραφής χωρίς [] μπορεί να οδηγήσει και σε απροσδιόριστη συμπεριφορά.

Η χρήση έξυπνων δεικτών, όπως auto_ptr, unique_ptr, shared_ptr, με πίνακες είναι επίσης λανθασμένη. Όταν ένας τέτοιος έξυπνος δείκτης βγαίνει από ένα εύρος, θα καλέσει έναν τελεστή διαγραφής χωρίς αγκύλες [] που έχει ως αποτέλεσμα τα ίδια ζητήματα που περιγράφονται παραπάνω. Εάν απαιτείται χρήση ενός έξυπνου δείκτη για έναν πίνακα, είναι δυνατή η χρήση scoped_array ή shared_array από το Boost ή μια μοναδική εξειδίκευση_ptr.

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

Κοινό λάθος # 4: Επιστροφή τοπικού αντικειμένου με αναφορά

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

Complex& SumComplex(const Complex& a, const Complex& b) { Complex result; ….. return result; } Complex& sum = SumComplex(a, b);

Το αντικείμενο 'άθροισμα' θα δείξει τώρα το τοπικό αντικείμενο 'αποτέλεσμα'. Αλλά πού βρίσκεται το αντικείμενο 'αποτέλεσμα' μετά την εκτέλεση της συνάρτησης SumComplex; Πουθενά. Βρίσκεται στη στοίβα, αλλά μετά την επιστροφή της συνάρτησης, η στοίβα ξετυλίχθηκε και όλα τα τοπικά αντικείμενα από τη συνάρτηση καταστράφηκαν. Αυτό τελικά θα οδηγήσει σε μια απροσδιόριστη συμπεριφορά, ακόμη και για πρωτόγονους τύπους. Για την αποφυγή προβλημάτων απόδοσης, μερικές φορές είναι δυνατή η χρήση βελτιστοποίησης αξίας επιστροφής:

Complex SumComplex(const Complex& a, const Complex& b) { return Complex(a.real + b.real, a.imaginar + b.imaginar); } Complex sum = SumComplex(a, b);

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

Αρχείο .cc έναντι .cpp

Κοινό λάθος # 5: Χρήση αναφοράς σε διαγραμμένο πόρο

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

Νήμα 1:

Connection& connection= connections.GetConnection(connectionId); // ...

Νήμα 2:

connections.DeleteConnection(connectionId); // …

Νήμα 1:

connection.send(data);

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

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

Κοινό λάθος # 6: Επιτρέποντας εξαιρέσεις για να αφήσετε τους καταστροφείς

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

class A { public: A(){} ~A() { writeToLog(); // could cause an exception to be thrown } }; // … try { A a1; A a2; } catch (std::exception& e) { std::cout << 'exception caught'; }

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

Επομένως, ο γενικός κανόνας είναι: μην επιτρέπετε ποτέ εξαιρέσεις να αφήνουν καταστροφείς. Ακόμα κι αν είναι άσχημο, πιθανή εξαίρεση πρέπει να προστατεύεται ως εξής:

πώς να προγραμματίσετε το c++
try { writeToLog(); // could cause an exception to be thrown } catch (...) {}

Κοινό λάθος # 7: Χρήση του 'auto_ptr' (εσφαλμένα)

Το πρότυπο auto_ptr καταργήθηκε από το C ++ 11 για διάφορους λόγους. Χρησιμοποιείται ακόμη ευρέως, καθώς τα περισσότερα έργα βρίσκονται ακόμη υπό ανάπτυξη στο C ++ 98. Έχει ένα συγκεκριμένο χαρακτηριστικό που πιθανώς δεν είναι γνωστό σε όλους τους προγραμματιστές C ++ και θα μπορούσε να προκαλέσει σοβαρά προβλήματα σε κάποιον που δεν είναι προσεκτικός. Η αντιγραφή του αντικειμένου auto_ptr θα μεταβιβάσει μια ιδιοκτησία από το ένα αντικείμενο στο άλλο. Για παράδειγμα, ο ακόλουθος κωδικός:

auto_ptr a(new ClassA); // deprecated, please check the text auto_ptr b = a; a->SomeMethod(); // will result in access violation error

… Θα οδηγήσει σε σφάλμα παραβίασης πρόσβασης. Μόνο το αντικείμενο 'b' θα περιέχει ένα δείκτη στο αντικείμενο της κλάσης Α, ενώ το 'a' θα είναι κενό. Η προσπάθεια πρόσβασης σε μέλος κλάσης του αντικειμένου 'a' θα έχει ως αποτέλεσμα σφάλμα παραβίασης πρόσβασης. Υπάρχουν πολλοί τρόποι λανθασμένης χρήσης του auto_ptr. Τέσσερα πολύ κρίσιμα πράγματα που πρέπει να θυμάστε είναι:

  1. Ποτέ μην χρησιμοποιείτε το auto_ptr μέσα σε κοντέινερ STL. Η αντιγραφή των κοντέινερ θα αφήσει τα κοντέινερ προέλευσης με μη έγκυρα δεδομένα. Ορισμένοι αλγόριθμοι STL μπορούν επίσης να οδηγήσουν σε ακύρωση του 'auto_ptr' s.

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

  3. Εάν το auto_ptr χρησιμοποιείται για μέλη δεδομένων μιας κλάσης, φροντίστε να δημιουργήσετε ένα κατάλληλο αντίγραφο μέσα σε έναν κατασκευαστή αντιγράφων και έναν χειριστή ανάθεσης ή να μην επιτρέπετε αυτές τις λειτουργίες καθιστώντας τις ιδιωτικές.

  4. Όποτε είναι δυνατόν, χρησιμοποιήστε κάποιον άλλο σύγχρονο έξυπνο δείκτη αντί του auto_ptr.

Κοινό λάθος # 8: Χρήση μη επικυρωμένων επαναληπτών και αναφορών

Θα ήταν δυνατό να γράψετε ένα ολόκληρο βιβλίο για αυτό το θέμα. Κάθε κοντέινερ STL έχει κάποιες συγκεκριμένες προϋποθέσεις υπό τις οποίες ακυρώνει επαναληπτικούς και αναφορές. Είναι σημαντικό να γνωρίζετε αυτές τις λεπτομέρειες ενώ χρησιμοποιείτε οποιαδήποτε λειτουργία. Ακριβώς όπως το προηγούμενο πρόβλημα C ++, αυτό μπορεί επίσης να συμβεί πολύ συχνά σε περιβάλλοντα πολλαπλών νημάτων, οπότε απαιτείται να χρησιμοποιήσετε μηχανισμούς συγχρονισμού για να το αποφύγετε. Ας δούμε τον ακόλουθο διαδοχικό κώδικα ως παράδειγμα:

vector v; v.push_back(“string1”); string& s1 = v[0]; // assign a reference to the 1st element vector::iterator iter = v.begin(); // assign an iterator to the 1st element v.push_back(“string2”); cout << s1; // access to a reference of the 1st element cout << *iter; // access to an iterator of the 1st element

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

Κοινό λάθος # 9: Διαβίβαση ενός αντικειμένου με τιμή

Κοινό λάθος # 9

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

class A { public: virtual std::string GetName() const {return 'A';} … }; class B: public A { public: virtual std::string GetName() const {return 'B';} ... }; void func1(A a) { std::string name = a.GetName(); ... } B b; func1(b);

Αυτός ο κωδικός θα μεταγλωττιστεί. Η κλήση της συνάρτησης 'func1' θα δημιουργήσει ένα μερικό αντίγραφο του αντικειμένου 'b', δηλαδή θα αντιγράψει μόνο το τμήμα της κλάσης 'A' του αντικειμένου 'b' στο αντικείμενο 'a' ('πρόβλημα τεμαχισμού'). Έτσι μέσα στη συνάρτηση θα καλέσει επίσης μια μέθοδο από την τάξη «Α» αντί για μια μέθοδο από την τάξη «Β» η οποία πιθανότατα δεν είναι αυτό που αναμένεται από κάποιον που καλεί τη συνάρτηση.

Παρόμοια προβλήματα προκύπτουν όταν επιχειρείτε να πιάσετε εξαιρέσεις. Για παράδειγμα:

class ExceptionA: public std::exception; class ExceptionB: public ExceptionA; try { func2(); // can throw an ExceptionB exception } catch (ExceptionA ex) { writeToLog(ex.GetDescription()); throw; }

Όταν μια εξαίρεση του τύπου ExceptionB ρίχνεται από τη συνάρτηση 'func2' θα πιάσει το μπλοκ catch, αλλά λόγω του προβλήματος τεμαχισμού θα αντιγραφεί μόνο ένα μέρος από την κατηγορία ExceptionA, θα κληθεί λανθασμένη μέθοδος και επίσης θα γίνει εκ νέου ρίψη θα ρίξει μια λανθασμένη εξαίρεση σε ένα εξωτερικό μπλοκ try-catch.

πώς να δημιουργήσετε ένα διακριτικό erc20

Συνοψίζοντας, μεταφέρετε πάντα αντικείμενα με αναφορά και όχι από τιμή.

Κοινό λάθος # 10: Χρήση μετατροπών που καθορίζονται από το χρήστη από κατασκευαστές κατασκευαστών και μετατροπών

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

class String { public: String(int n); String(const char *s); …. }

Η πρώτη μέθοδος προορίζεται να δημιουργήσει μια συμβολοσειρά μήκους n και η δεύτερη προορίζεται να δημιουργήσει μια συμβολοσειρά που περιέχει τους δεδομένους χαρακτήρες. Αλλά το πρόβλημα ξεκινά μόλις έχετε κάτι τέτοιο:

String s1 = 123; String s2 = ‘abc’;

Στο παραπάνω παράδειγμα, το s1 θα γίνει συμβολοσειρά μεγέθους 123, όχι συμβολοσειρά που περιέχει τους χαρακτήρες '123'. Το δεύτερο παράδειγμα περιέχει μεμονωμένα εισαγωγικά αντί για διπλά εισαγωγικά (τα οποία μπορεί να συμβούν κατά λάθος) που θα οδηγήσουν επίσης στην κλήση του πρώτου κατασκευαστή και στη δημιουργία μιας συμβολοσειράς με πολύ μεγάλο μέγεθος. Αυτά είναι πραγματικά απλά παραδείγματα και υπάρχουν πολύ πιο περίπλοκες περιπτώσεις που οδηγούν σε σύγχυση και απρόβλεπτες μετατροπές που είναι πολύ δύσκολο να βρεθούν. Υπάρχουν 2 γενικοί κανόνες για την αποφυγή τέτοιων προβλημάτων:

  1. Ορίστε έναν κατασκευαστή με ρητή λέξη-κλειδί για την απαγόρευση των έμμεσων μετατροπών.

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

συμπέρασμα

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

Σχετίζεται με: Πώς να μάθετε τις γλώσσες C και C ++: Η απόλυτη λίστα

Το ApeeScape ανακοινώνει νικητές υποτροφιών γυναικών από την Αμερική και την Ευρώπη

Αλλα

Το ApeeScape ανακοινώνει νικητές υποτροφιών γυναικών από την Αμερική και την Ευρώπη
Angular vs. React: Ποιο είναι καλύτερο για την ανάπτυξη Ιστού;

Angular vs. React: Ποιο είναι καλύτερο για την ανάπτυξη Ιστού;

Διεπαφή Ιστού

Δημοφιλείς Αναρτήσεις
Senior Full-stack Engineer, Talent Post-hire Team
Senior Full-stack Engineer, Talent Post-hire Team
Εισαγωγή στην επεξεργασία εικόνων Python στην Υπολογιστική Φωτογραφία
Εισαγωγή στην επεξεργασία εικόνων Python στην Υπολογιστική Φωτογραφία
Λειτουργίες παραθύρου εισαγωγής στο SQL
Λειτουργίες παραθύρου εισαγωγής στο SQL
Εγκατάσταση του Django στο IIS: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Εγκατάσταση του Django στο IIS: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Φαίνεται ενθουσιασμό - Μέσα στην αναπτυσσόμενη βιομηχανία ομορφιάς
Φαίνεται ενθουσιασμό - Μέσα στην αναπτυσσόμενη βιομηχανία ομορφιάς
 
Αρχιτεκτονική προσανατολισμένη στην υπηρεσία με AWS Lambda: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Αρχιτεκτονική προσανατολισμένη στην υπηρεσία με AWS Lambda: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Σχεδιασμός παρουσίασης και τέχνη της οπτικής αφήγησης
Σχεδιασμός παρουσίασης και τέχνη της οπτικής αφήγησης
Μια βαθιά ματιά στο JSON εναντίον XML, Μέρος 3: XML και το μέλλον του JSON
Μια βαθιά ματιά στο JSON εναντίον XML, Μέρος 3: XML και το μέλλον του JSON
5 Ερωτήσεις που πρέπει να υποβάλει ένα Master Scrum πριν εγγραφείτε σε μια εκκίνηση
5 Ερωτήσεις που πρέπει να υποβάλει ένα Master Scrum πριν εγγραφείτε σε μια εκκίνηση
Τρεις αρχές ανάπτυξης δεδομένων αποθήκης
Τρεις αρχές ανάπτυξης δεδομένων αποθήκης
Δημοφιλείς Αναρτήσεις
  • πώς οργανώνεται το ανεκτέλεστο προϊόν
  • γιατί η Ελλάδα χρωστάει
  • είναι η llc an s ή c corp μου
  • πώς να γράψετε ελεγχόμενο κώδικα
  • λάβετε χρόνο σε χιλιοστά του δευτερολέπτου javascript
Κατηγορίες
  • Επιστήμη Δεδομένων Και Βάσεις Δεδομένων
  • Κερδοφορία & Αποδοτικότητα
  • Σχεδιασμός Ux
  • Κινητό
  • © 2022 | Ολα Τα Δικαιώματα Διατηρούνται

    portaldacalheta.pt