τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Στη C/C++, υπάρχει ένας μεγάλος αριθμός μεταβλητών, συναρτήσεων και κλάσεων που θα μάθετε αργότερα. Τα ονόματα αυτών των μεταβλητών, συναρτήσεων και κλάσεων θα υπάρχουν σε όλο τον κόσμο.
Στην τοπική εμβέλεια, μπορεί να προκαλέσει πολλές συγκρούσεις.Ο σκοπός της χρήσης χώρων ονομάτων είναι η τοπική προσαρμογή των ονομάτων των αναγνωριστικών για να αποφευχθεί η ονομασία
Διένεξη ή ρύπανση ονόματος, η λέξη-κλειδί namespac φαίνεται να αντιμετωπίζει αυτό το πρόβλημα.
Οι διενέξεις ονομάτων όπως το παρακάτω πρόγραμμα σε έργα γλώσσας C είναι κοινά προβλήματα που εισάγει το namespac για την καλύτερη επίλυσή τους.
Ένα τέτοιο πρόβλημα: (Το σφάλμα αναφέρεται επειδή η μεταβλητή rand που ορίσαμε έρχεται σε διένεξη με τη συνάρτηση rand στο stdlib.h)
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
printf("%dn", rand);
return 0;
}
1. Για να ορίσετε έναν χώρο ονομάτων, πρέπει να χρησιμοποιήσετε τη λέξη-κλειδί του χώρου ονομάτων, ακολουθούμενη από το όνομα του χώρου ονομάτων και, στη συνέχεια, να συνδέσετε ένα ζεύγος {}, όπου {}
Μέλος δηλαδή του namespace. Μεταβλητές/συναρτήσεις/τύποι, κ.λπ. μπορούν να οριστούν στο χώρο ονομάτων.(Λάβετε υπόψη ότι το {} δεν ακολουθείται από το ";")。
2. Η ουσία του χώρου ονομάτων είναι να ορίσετε έναν τομέα Αυτός ο τομέας είναι ανεξάρτητος από τον καθολικό τομέα
Το ραντ παραπάνω δεν είναι πλέον σε σύγκρουση.
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{
int rand = 0;
}
int main()
{
printf("%dn", rand);
return 0;
}
3. Οι τομείς στη C++ περιλαμβάνουν τη συνάρτηση τοπικό τομέα, καθολικό τομέα, τομέα ονομάτων και τομέα κλάσης, ο τομέας επηρεάζει τη σύνταξη του χρόνου μεταγλώττισης για να βρει μια μεταβλητή/συνάρτηση/.
Η λογική προέλευσης τύπου (δήλωση ή ορισμός), με απομόνωση τομέα, διενέξεις ονόματος επιλύονται.Εκτός από το να επηρεάζει τον τοπικό τομέα και τον παγκόσμιο τομέα
Η μεταγλώττιση της λογικής αναζήτησης θα επηρεάσει επίσης τον κύκλο δήλωσης μεταβλητών Οι τομείς ονομάτων και οι τομείς κλάσεων δεν επηρεάζουν τον κύκλο δήλωσης μεταβλητών.
4. Ο χώρος ονομάτων μπορεί να οριστεί μόνο καθολικά, και φυσικά μπορεί επίσης να είναι ένθετος.
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{
int rand = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
int main()
{
printf("%dn", rand);
return 0;
}
5. Οι χώροι ονομάτων με το ίδιο όνομα που ορίζονται σε πολλά αρχεία στο έργο θα θεωρούνται ως ένας χώρος ονομάτων και δεν θα έρχονται σε διένεξη.
αρχείο test.c
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include"test.h"
namespace tmp
{
int rand = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
int main()
{
printf("%dn", tmp::d);
return 0;
}
αρχείο test.h
#pragma once
namespace tmp
{
int d = 0;
}
Μπορεί να βρεθεί ότι η μεταβλητή d στον χώρο tmp μπορεί να χρησιμοποιηθεί στο αρχείο .c.
6. Η τυπική βιβλιοθήκη C++ τοποθετείται σε έναν χώρο ονομάτων που ονομάζεται std (standard).
7. Εάν θέλουμε να χρησιμοποιήσουμε μεταβλητές στον καθολικό τομέα, μπορούμε να το κάνουμε αυτό:
int a = 3;
int main()
{
int a = 0;
printf("%dn", ::a);
return 0;
}
Με αυτόν τον τρόπο, το printf εκτυπώνει πρώτα 3.
Κατά τη μεταγλώττιση για αναζήτηση της δήλωσης/ορισμού μιας μεταβλητής, από προεπιλογή θα πραγματοποιεί αναζήτηση μόνο τοπικά ή καθολικά, όχι στον χώρο ονομάτων.Έτσι
Το παρακάτω πρόγραμμα θα μεταγλωττίσει και θα αναφέρει ένα σφάλμα.
namespace tmp
{
int d = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
int main()
{
int a = 0;
printf("%dn", d);//未定义标识符d
return 0;
}
Πρέπει λοιπόν να χρησιμοποιήσουμε μεταβλητές/συναρτήσεις που ορίζονται στον χώρο ονομάτων Υπάρχουν τρεις τρόποι:
1. Καθορίστε την πρόσβαση στο χώρο ονομάτων Αυτή η μέθοδος συνιστάται στο έργο.
tmp::d
2. Η χρήση επεκτείνει ένα μέλος του χώρου ονομάτων.Αυτή η προσέγγιση συνιστάται για μέλη του έργου με συχνή πρόσβαση και δεν έχουν διενέξεις.
namespace tmp
{
int d = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
using tmp::d;
int main()
{
int a = 0;
printf("%dn", d);//未定义标识符d
return 0;
}
3. Αναπτύξτε όλα τα μέλη στον χώρο ονομάτων,Το έργο δεν συνιστάται γιατί ο κίνδυνος σύγκρουσης είναι υψηλός Το πρόγραμμα καθημερινής πρακτικής συνιστάται για λόγους ευκολίας.
namespace tmp
{
int d = 0;
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
using namespace tmp;
int main()
{
int a = 0;
printf("%dn", d);//未定义标识符d
return 0;
}
1. Είναι η συντομογραφία του Input Output Stream Είναι μια τυπική βιβλιοθήκη ροής εισόδου και εξόδου που ορίζει την τυπική είσοδο και έξοδο.
έξω αντικείμενο.
2. Το std::cin είναι ένα αντικείμενο της κλάσης istream, το οποίο προσανατολίζεται κυρίως στην τυπική έξοδο στενών χαρακτήρων (τύπου char).
Εισροή.
3. std::cout είναι ένα αντικείμενο της κλάσης ostream, το οποίο είναι κυρίως προσανατολισμένο στην τυπική ροή εξόδου στενών χαρακτήρων.
4. Το std::endl είναι μια συνάρτηση Όταν η ροή εισάγεται στην έξοδο, ισοδυναμεί με την εισαγωγή ενός χαρακτήρα νέας γραμμής και την ανανέωση του buffer.
5. << είναι ο τελεστής εισαγωγής ροής και >> είναι ο τελεστής εξαγωγής ροής. (Η γλώσσα C χρησιμοποιεί επίσης αυτούς τους δύο τελεστές για να εκτελέσει λειτουργίες bitwise, όπως μετατόπιση αριστερά/δεξιά)
6. Είναι πιο βολικό να χρησιμοποιείτε τη C++ για είσοδο και έξοδο Δεν χρειάζεται να προσδιορίσετε με μη αυτόματο τρόπο τη μορφή, όπως το printf/scanf για την είσοδο και την έξοδο C**+.
Η έξοδος μπορεί να αναγνωρίσει αυτόματα τους τύπους μεταβλητών(Ουσιαστικά, αυτό επιτυγχάνεται μέσω της υπερφόρτωσης συναρτήσεων Στην πραγματικότητα, το πιο σημαντικό είναι ότι οι ροές C++ μπορούν να υποστηρίξουν καλύτερα την προσαρμογή).
Πληκτρολογήστε την είσοδο και την έξοδο αντικειμένων.
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{
int a = 0;
double b = 0.0;
char c = '0';
namespace tmp1
{
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
}
using namespace tmp;
using namespace std;
int main()
{
cin >> a >> b >> c;
cout << a << b << c;
return 0;
}
7. cout/cin/endl, κ.λπ. ανήκουν στην τυπική βιβλιοθήκη C++ Η τυπική βιβλιοθήκη C++ τοποθετείται σε έναν χώρο ονομάτων που ονομάζεται std (standard), επομένως είναι απαραίτητο
Χρησιμοποιήστε τα μέσω της χρήσης χώρου ονομάτων.
8、⼼Μπορούμε να χρησιμοποιήσουμε namespace std στη γενική καθημερινή πρακτική, αλλά δεν συνιστάται η χρήση namespace std στην πραγματική ανάπτυξη έργου.
Οι προεπιλεγμένες παράμετροι καθορίζουν μια προεπιλεγμένη τιμή για τις παραμέτρους της συνάρτησης κατά τη δήλωση ή τον ορισμό της συνάρτησης.Κατά την κλήση αυτής της συνάρτησης, εάν δεν έχουν καθοριστεί πραγματικές παράμετροι
Στη συνέχεια χρησιμοποιείται η προεπιλεγμένη τιμή της επίσημης παραμέτρου, διαφορετικά χρησιμοποιείται η καθορισμένη πραγματική παράμετρος. (Σε μερικά μέρη,
Οι προεπιλεγμένες παράμετροι ονομάζονται επίσης προεπιλεγμένες παράμετροι).
Η πλήρης προεπιλογή σημαίνει ότι σε όλες τις τυπικές παραμέτρους δίνονται προεπιλεγμένες τιμές και η ημιπροεπιλογή σημαίνει ότι σε ορισμένες τυπικές παραμέτρους δίνονται προεπιλεγμένες τιμές.Η C++ ορίζει ότι οι ημι-προεπιλεγμένες παράμετροι πρέπει να είναι από τα δεξιά προς τα αριστερά
Συνεχείς προεπιλογές στη σειρά και δεν είναι δυνατή η μετάβαση στην προεπιλεγμένη τιμή κατά διαστήματα.
Για κλήσεις συναρτήσεων με προεπιλεγμένες παραμέτρους, η C++ ορίζει ότι οι πραγματικές παράμετροι πρέπει να δίνονται διαδοχικά από αριστερά προς τα δεξιά και ότι οι πραγματικές παράμετροι δεν μπορούν να παραβλεφθούν.
Όταν η δήλωση και ο ορισμός της συνάρτησης διαχωρίζονται, οι προεπιλεγμένες παράμετροι δεν μπορούν να εμφανιστούν τόσο στη δήλωση όσο και στον ορισμό της συνάρτησης
αξία.
#include <iostream>
using namespace std;
void Func(int a = 0)
{
cout << a << endl;
}
int main()
{
Func(); // 没有传参时,使⽤参数的默认值
Func(10); // 传参时,使⽤指定的实参
return 0;
}
#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
Func1();
Func1(1);
Func1(1, 2);
Func1(1, 2, 3);
Func2(100);
Func2(100, 200);
Func2(100, 200, 300);
return 0;
}
Η ημιπροεπιλογή δεν μπορεί να γραφτεί ως εξής:
void Func2(int a = 10, int b, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
//或者
void Func2(int a = 10, int b, int c)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
Πρέπει να τηρούνται αυστηρά:
Οι ημι-προεπιλεγμένες παράμετροι πρέπει να προκαθορίζονται συνεχώς από τα δεξιά προς τα αριστερά και δεν μπορούν να παραβλεφθούν στις προεπιλεγμένες τιμές κατά διαστήματα.
Πριν μάθουμε τη C++, όταν υλοποιήσαμε την προετοιμασία και την εισαγωγή στοίβας, γράψαμε αυτό:
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
// 栈顶
void STInit(ST* ps, int n)
{
assert(ps);
ps->a = (STDataType*)malloc(n * sizeof(STDataType));
ps->top = 0;
ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
// 满了, 扩容
if (ps->top == ps->capacity)
{
printf("扩容n");
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity
* 2;
STDataType* tmp = (STDataType*)realloc(ps->a,
newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
Αν θέλουμε να εισαγάγουμε 100 δεδομένα, θα χρειαστούμε συνεχή επέκταση και αποτελεσματική απώλεια, αλλά αφού μάθουμε τις προεπιλεγμένες παραμέτρους, μπορούμε να γράψουμε ως εξής:
// 栈顶
void STInit(ST* ps, int n = 4)
{
assert(ps);
ps->a = (STDataType*)malloc(n * sizeof(STDataType));
ps->top = 0;
ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
// 满了, 扩容
if (ps->top == ps->capacity)
{
printf("扩容n");
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity
* 2;
STDataType* tmp = (STDataType*)realloc(ps->a,
newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
int main()
{
ST a;
STInit(&a, 100);//这里不传100也可以,因为规定必须从左到右依次给实参,不能跳跃给实参。刚好和缺省参数确定位置互补
for (int i = 0; i < 100; i++)
{
STPush(&a, i);
}
return 0;
}
Αυτό αποφεύγει αποτελεσματικά το πρόβλημα του επανειλημμένου ανοίγματος χώρου.
Η C++ υποστηρίζει συναρτήσεις με το ίδιο όνομα που εμφανίζονται στο ίδιο εύρος, αλλά απαιτεί οι επίσημες παράμετροι αυτών των συναρτήσεων με το ίδιο όνομα να είναι διαφορετικές. Αυτό μπορεί να είναι διαφορετικός αριθμός παραμέτρων ή
ΔΙΑΦΟΡΕΤΙΚΟΙ ΤΥΠΟΙ. Με αυτόν τον τρόπο, οι κλήσεις συναρτήσεων C++ παρουσιάζουν πολυμορφική συμπεριφορά και είναι πιο ευέλικτες στη χρήση. (Ωστόσο, διαφορετικές τιμές επιστροφής δεν μπορούν να χρησιμοποιηθούν ως συνθήκες υπερφόρτωσης.
Επειδή δεν μπορεί να διακριθεί κατά την κλήση, εάν η τιμή επιστροφής και ο τύπος ή ο αριθμός της παραμέτρου αλλάξουν ταυτόχρονα, είναι επίσης μια κατάσταση υπερφόρτωσης).
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
Συγκεκριμένα, εάν η παραπάνω μέθοδος χρησιμοποιεί προεπιλεγμένες παραμέτρους, θα αναφερθεί ένα σφάλμα κατά την κλήση χωρίς διαβίβαση παραμέτρων Ο μεταγλωττιστής δεν ξέρει ποιον να καλέσει.
// 下⾯两个函数构成重载
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f1()
{
cout << "f()" << endl;
}
void f1(int a = 10)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
int main()
{
Add(10, 20);
Add(10.1, 20.2);
f();
f(10);
f(10, 'a');
f('a', 10);
return 0;
}
`#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
int main()
{
Add(10, 20);
Add(10.1, 20.2);
f();
f(10);
f(10, 'a');
f('a', 10);
return 0;
}``
αποτέλεσμα: