C++ προσδιοριστικό register

tom1972 | Τρί, 07/17/2012 - 15:14 | 2' | 15

Καλησπέρα σε όλους και πάλι ...
Δοκίμασα στη C++ κάτι που το ήξερα μόνο στη θεωρία ....
Όχι ότι θα έκανε κάποια διαφορά αλλά έτσι για μαγκιά ....
Χρησιμοποίησα το προσδιοριστικό register σε κάποια μεταβλητή i που ελέγχει τους πολλούς βρόχους for που βάζω στα προγράμματά μου....
Δηλ

register int i ;  // Έτσι για να δώ τι κάνει ....

Στους μεταγλωτιστές Qt-creator, devcpp, δεν αναγνωρίζουν καθόλου την λέξη....
Με visual c++ δε θέλω να έχω παρτίδες (αλλά σύμφωνα με το συγγραφέα Herbert Schildt, σε παλιές εκδόσεις visual c++, πάλι δεν το αναγνώριζε) ...

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

Κάποια ιδέα ;;; Ευχαριστώ εκ των προτέρων

Δώσε αστέρια!

MO: 1 (ψήφοι: 2)

Σχόλια

Βασικά το keyword "register" είναι απλώς μια υπόδειξη στον compiler ότι θα ήθελες να καταχωρεί μια μεταβλητή σε έναν hardware καταχωρητή. Η λογική είναι ότι θα το έκανες αυτό για πολύ γρήγορη πρόσβαση σε μια int μεταβλητή.

Ωστόσο, ο compiler δεν το δέχεται υποχρεωτικά - άσε που οι σύγχρονοι compilers κάνουν πολύ καλύτερη διαχείριση καταχωρητών από μόνοι τους. Ένα απλό πρόγραμμα C με χρήση register μπορεί να γίνει compile παρότι ο gcc έχει αγνοήσει την υπόδειξη που του έχεις κάνει.

Στην πραγματικότητα, αυτό που κάνει η λέξη register -και αυτή είναι η κύρια χρήση της- είναι να μην επιτρέπει να εκχωρείς τη διευθυνση μνήμης μιας μεταβλητής σε άλλη μεταβλητή μέσω call by reference. Δηλαδή απαγορεύει κάτι σαν κι αυτό:


register int alpha;
int *beta = α

Με απλά λόγια: αν δεν ξέρεις γιατί το κάνεις, μην την χρησιμοποιείς, δεν κερδίζεις τίποτε.

Δες περισσότερα εδώ

http://www.cprogrammingreference.com/Tutorials/Basic_Tutorials/Ckeywordsindiviusual/register.php

Πρώτε βασικά ξέρω :
1. ότι είναι προτροπή και όχι εντολή
2. Τα βιβλία που έχω διαβάσει λένε ότι αν το δεχθεί ο μεταγλωτιστής, θα αποθηκεύσει το i όχι στη RAM αλλά κατευθείαν σε καταχωρητή (για να γλυτώσεις επιπλέον χαμηλού επιπέδου ενέργειες ... εκεί βαθιά στον πυρήνα)

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

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

Όσο για το : "να μην επιτρέπει να εκχωρείς τη διευθυνση μνήμης μιας μεταβλητής σε άλλη μεταβλητή μέσω call by reference", πρώτη φορά το ακούω μιας και τα βιβλία που έχω διαβάσει δεν τοέχουν αναφέρει ...
Δεν ξέρω αν αυτό είναι καινούργια προσθήκη στην STANDARD C++ (ISO-ANSI) (καλά μπορεί να μελετάω εδώ και καιρό παλιά έκδοση .....). Αλήθεια υπάρχει και νεότερη από αυτή που ανέφερα ;;;
Σίγουρα θα τσεκάρω το σύνδεσμο που μου πρότεινες για να μάθω λεπτομέρειες που δεν γνωρίζω ...

Sorry που σε έχω πυρπολήσει με ερωτήσεις αλλά μπορεί να μελετάω παλιά έκδοση C++ και να μην το ξέρω ...

ΥΓ. Τα κόκκινα είναι οι ερωτήσεις ... Τα σημείωσα για να σε ξεμπερδέψω....

Α!! Και κάτι που ξέχασα να αναφέρω ...
Χρησιμοποίσησα το
register int i;
διότι έκανα κάτι δοκιμές στην κλάση vector, και χρησιμοποίησα καμιά 30αριά φορές το:
for(i=0; i<="κάτι", i++){ }
Σκέφτηκα να μην τρέλαθει ο compiler στο
"Γράψε i από τη RAM στον register και ξανά πίσω", κι αυτό καμιά 30αριά φορές ...

Πάντα εννοείται ότι έδωσα ΣΥΜΒΟΥΛΗ στον compiler και ουχί ΔΙΑΤΑΓΗ .....
Που να τολμήσω ο καημένος να διατάξω το μαύρο κουτί που λέγεται compiler και για μένα είναι κάτι μαγικό ...
Να κάνω κι ένα αστείο να ξεπεράσω τον πόνο μου ..... (ξέρεις σου έχω αναφέρει σε μήνυμα ...)

@ dimitris

Φίλε κοίτα τι κατάλαβα .....
Ο STROUSTUP έβγαλε ένα καινούργιο βιβλίο το
Programming: Principles and Practice Using C++
Αυτό το βιβλίο το έξέδωσε το "Publication Date: December 25, 2008"
Δηλαδή είναι σύγχρονο, την σήμερον ημέρα όπου τα μηχανήματα είναι "σκυλιά" και σε μνήμη και σε επεξεργαστική ισχύ (καταχωρητές - cache - ταχύτητα ....)

Έψαξα στο pdf του βιβλίου (μη ρωτήσεις που το βρήκα), για τη λέξη register, και την είχε μόνο στη λίστα δεσμευμένων λέξεων της C++ ...
Δεν ανέφερε τίποτε για τις register μεταβλητές .... ίσως (δεν είμαι σίγουρος - φαντάζομαι) επειδή οι νέοι μεταγλωτιστές ούτε καν χρειάζονται αυτή τη λέξη, αφού τα μηχανήματα είναι σκυλιά όπως ανέφερα ....

Είναι λογικό την παλιά εποχή ο RITCHIE να την συμπεριλάβει στη C, αφού τότε και οι μνήμες και οι επεξεργαστές ήταν για τα "μπάζα" ... και σε συστήμστα ..... ήταν (????) 16bit τότε για πιο κάτω ....
Αντί λοιπόν να αναγκαζεις το σύστημα να βάλε-βγάλε την μεταβλητή από RAM σε καταχωρητή, του ΠΡΟΤΕΙΝΕΣ να την τοποθετήσει (αν μπορούσε να γίνει κάτι τέτοιο - διότι οι καταχωρητες τότε ήταν το πολύ 16), σε ένα καταχωρητή ώστε να γλυτώνει ο επεξεργαστής χρόνο-κόπο ....

Στη σήμερον ημέρα μάλλον δεν χρειάζεται και οι κατασκευαστές των σημερινών μεταγλωτιστών την άφησαν .... Σκέψου ότι και οι ίδιοι γλύτωσαν να ενσωματώσουν στον compiler τους κώδικα για μια τέτοια (ίσως) παρωχημένη δυνατότητα ....
Τι λες κι εσύ ;;;

Η register είναι μία δεσμευμένη λέξη της C αλλά πλέον δεν χρησιμοποιείται λόγω του ότι οι σημερινοί compilers είναι πιο "έξυπνοι". Δηλαδή, θα κάνουν την δουλειά μόνοι τους (όπως ακριβώς είπε και ο Δημήτρης). Γενικά η σωστή τακτική είναι να αξιοποιείς την μνήμη όσο καλύτερα μπορείς ανεξάρτητα από το πόσο μεγάλη μνήμη μπορεί να έχουν οι υπολογιστές σήμερα (γι' αυτό χρησιμοποιούμε και καταστροφείς). Για την ερώτηση που έκανες πιο πάνω η απάντηση (αν την καταλαβαίνω καλά Tongue out) είναι ότι η τωρινή έκδοση της C++ είναι η 11.

Επίσης καλό είναι να διαβάσεις και αυτό γιατί νομίζω είναι πολύ χρήσιμο επειδή κατάλαβα ότι σε ενδιαφέρει η απόδοση του προγράμματός σου:
http://stackoverflow.com/questions/3289726/in-c-any-general-guidelines-for-handling-memory-allocation-deletion

Δεν είμαι σίγουρος αν σε βοήθησα καθόλου αλλά αν θες κάτι άλλο που να μπορώ να βοηθήσω εδώ θα 'μαι!!! Smile

Φίλε ευχαριστώ πολύ για την απάντηση ...
έχω διαβάσει από 2 βιβλία :
"H γλώσσα C++ σε βάθος - Κλειδάριθμος - Νίκος Χατζηγιαννάκης"
"Μάθετε τη C++ από το μηδέν - Herbert Schildt - 3η αμερικαν έκδοση"
Προφανώς είναι παλαιότερης έκδοσης... πως καταλαβαίνω ποιας έκδοσης C++ είναι αυτά ?
Πως το καταλαβαίνω ?

Που θα βρω τις αλλαγές για την νέα έκδοση ?? Κάποιος οδηγός ??

Στο κεντικό site
http://www2.research.att.com/~bs/homepage.html
γράφει για την "C++0x" πάνω-πάνω αυτή είναι η παλιά εκδοση ??

Στο κεντικό site
http://www.cplusplus.com/
που γράφει τη νέα έκδοση ???

Καλά τόσο ηλ@?#ος είΜαι και βρίσκομαι στην παλαιολιθική περίοδο ? Ενημέρωσέ με ΠΡΩΤΕ !!!!

Ευχαριστώ πάντως που μου άνοιξες τα μάτια ... (και το έπαιζα και γνώστης ....)

Φίλε στην έκδοση C++ 11, που μου είπες υπάρχει ακόμα το πρότυπο
STANDARD C++ (ISO-ANSI) ???

Πάντως το πρώτο βιβλίο που λες φίλε μου επειδή το έχω διαβάσει μου φαίνεται αρκετά για αρχάριους, οπότε δεν ξέρω αν θα σου φανεί χρήσιμο, διάβασε καλύτερα από το δεύτερο που λένε ότι είναι εξαιρετικός συγγραφέας! Όντως το C++0x είναι η παλιά έκδοση της γλώσσας.

Και τα 2 τα έχω διαβάσει σε ένα 85-90%...
Ξέρω C++ αρκετά καλά, απλά κυνηγάω λεπτομέρειες οι οποίες είναι προχωρημένες....
Tην μόνη συνάρτηση που δε θα χρησιμοποιήσω ποτέ είναι η asm(), μιας και δεν ξέρω καθόλου assembly...
(Δες τι έχω γράψει παραπάνω για το μαύρο κουτί .....)
Πρέπει να χάνω στο κεφάλι μου.... γνωρίζοντας ότι όλες οι γλώσσες έχουν νέες εκδόσεις, αλλά ... ουπς ... η C και η C++ θα παρέμεναν οι ίδιες ....
Ευχαριστώ πάντως για την ενημέρωση.

Αν θελήσω κάτι θα σας ειδοποιήσω ... ! Ευχαριστώ για όλα ...

tom δεν μπορώ να ξέρω γιατί δεν δέχεται ο compiler σου το keyword. Σε ένα project Qt/C++ που έχω το δέχεται μια χαρά

for (register int i=0; i< vert ; i++) {
 int x=10+rand() %640;
 int y=10+rand() %480;
 qDebug("Graph: createRandomNetErdos, new node i=%i, 
    at x=%i, y=%i", i+1, x,y);
 createVertex (i+1, initVertexSize, initVertexColor,
  initVertexNumberColor, initVertexNumberSize, QString::number (i+1),
  initVertexLabelColor, initVertexLabelSize, QPoint(x, y),
  initVertexShape, false ); 
 progressCounter++;
 emit updateProgressDialog( progressCounter );
}

 

Ίσως όμως, επειδή χρησιμοποιώ makefile να περνάει κάποια παράμετρο στον compiler που να του λέει να την αγνοήσει... 
 

Πρώτε πρόσεξε γιατί δεν μου λειτουργούσε ....
Είχα βάλει εκτός της main το register ... και δεν το αναγνώριζε ... (δεν ξέρω γιατί το κάνει αυτό)
register int i;
int main()
{
.....
}

Αν όμως μπει μέσα τότε μεταγλωτίζει μια χαρά ... (έκανα αυτό το πείραμα ...)
int main()

{

register int i;

.....


}

Παράξενο εε;;;; Αν έχεις εξήγηση πες .... Πάντως στα βιβλία δεν ανέφερε τίποτε για μέσα ή έξω ...
Απλά έξω το i θα είναι καθολική μεταβλητή.
Δε συνηθίζω να βάζω καθολικά στη C++, αλλά το πρόγραμμα που έγραφα ήταν μη αντικειμενοστραφές - δοκίμαζα τη βιβλιοθήκη <vector>. Απλά επειδή εξασκούμουνα στη vector, είχα γράψει το πρόγραμμα σε στιλ κανόνων ...
Είπα να τογράψω απ'έξω μόνο για να μη μπερδευτεί μέσα γιατί είχα γράψει πολλά στη main (έτσι για να είναι αναγνώσιμα...)

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

Προσπαθούσα 2 μέρες να το κάνω και δεν μπορούσα πως να σκεφτώ την κλάση.

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

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

Προσοχή στο linux θα τη δώσω δωρεάν, αλλά στη microsoft, θα την πουλήσω 1,000,000 dolarsLaughing

Να ο κώδικας

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;

class data_base
{
    class record
    {
    public:
        int id;
        char fname[20];
        char lname[35];
        char phone[10];
       
        record();
        record *nxt;   
    }; 
   
    record *head;
public:
    data_base(){head = NULL;}
    void insert_front();
    void show_rec(record *rec);
    void show_database(); 
};

data_base::record::record()
{
    cout << "Dear user, please insert your personal data" << endl;
    cout << "===========================================" << endl;
    int n;
    char fn[20], ln[35], phn[10];
    cout << "Insert the id number    : ";
    cin >> n;
    id = n;
    cout << "Insert the first name   : ";
    cin >> fn;
    strcpy(fname, fn);
    cout << "Insert the last name    : ";
    cin >> ln;
    strcpy(lname, ln);
    cout << "Insert the phone number : ";
    cin >> phn;
    strcpy(phone, phn);
    cout << endl << "Thanks for your cooperation !!" << endl << endl;
}

void data_base::insert_front()
{
    record *newrecord = new(nothrow) record;
        if(newrecord == NULL)
        {
            cout << "The program cannot allocate memory,"
                 << " to store your data !!" << endl;
            exit(1);
        }
    newrecord->nxt = head;
    head = newrecord;
}

void data_base::show_rec(record *rec)
{
    cout << endl;
    cout << "========== RECORD " << rec->id << "   =============" << endl;
    cout << "Id is        : " << rec->id << endl;
    cout << "First name   : ";  puts(rec->fname);
    cout << "Last name    : ";  puts(rec->lname);
    cout << "Pnone number : ";  puts(rec->phone);
    cout << "===================================" << endl;
}

void data_base::show_database()
{     
    record *tmp = head;
   
    while(tmp != NULL)
    {
    show_rec(tmp);
    tmp = tmp->nxt;
    }
}

int main()
{
    register int i; // αυτό το έβαλα αργότερα γιανα δοκιμάσω αυτά που λέγαμε πριν
    cout << endl;
   
    data_base db;
   
    for(i=1; i<=3; i++)     
        db.insert_front();
   
    db.show_database();
   
    cout << endl;
    return 0; 
}

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

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

Πριν από 5 χρόνια είχα προσπαθήσει να δώσω κατατακτήριες για τη σχολή
ΜΗΧΑΝΙΚΩΝ Η/Υ ΤΗΛΕΠΙΚΟΙΝΩΝΙΩΝ ΚΑΙ ΔΥΚΤΙΩΝ, στο Βόλο... (δεν κατάφερα να μπω ...)
Κάποιος φοιτήτής που μου είχε δώσει σημειώσεις τότε, μου είχε μιλήσει για το UBUNTU, και έτσι άρχισα ...
Στη σχολή αυτή χρησιμοποιούν LINUX κατά κόρων (μιας και είναι δίκτυα .....)

Αναγκαστικά τα είχα διαβάσει από τη C, αλλά είπα να τα μεταφέρω και στη C++.

Απλά τα ανέφερα για την ιστορία ...