C++入門基礎筆記
1、C++第一個程序
程序中\n
與endl
相同,endl表示結束流,在流中起做用!
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!" << endl;
return 0;
}
2、註釋
可以通過#if 0
與#endif
來註釋語句通過更改0與1來確定是否使用語句塊
3、數據類型
- 修飾符:
signed
有符號unsigned
無符號short
短的long
長的 - 類型:
bool
布爾型char
int
整型float
浮點型double
雙浮點void
無wchar_t
寬字符型 - 值範圍:
float
單精度其地址為1位符號,8位指數,23位小數。
double
雙精度是1位符號,11位指數,52位小數。char
八位字節
typedef 聲明
extern
聲明變量應放在main()前面,
extern
可以置於變量或者函數前,以標示變量或者函數的定義在別的文件中,提示編譯器遇到此變量和函數時在其他模塊中尋找其定義。另外,extern
也可用來進行鏈接指定。
extern int c;
enumeration 枚舉型
enum color { red, green, blue } c; c = blue;
默認情況下red的值為0,green為1,以此類推但當:
enum color { red, green=5, blue };
這個情況下時red的值為0,green為5,blue為6.
4、全局變量
全局變量放在mian()前面,所以程序都可以訪問,在程序中,局部變量和全局變量的名稱可以相同,但是在函數內,局部變量的值會覆蓋全局變量的值。局部變量被定義時,系統不會對其初始化,您必須自行對其初始化.全局會自動初始化
int
0 char
"\0" float
0 double
0 pointer
NULL
常量
整數常量可以帶一個後綴,後綴是 U 和 L 的組合,U 表示無符號整數(unsigned),L 表示長整數(long)。
浮點常量當使用指數形式表示時, 必須包含小數點、指數,或同時包含兩者。帶符號的指數是用 e 或 E 引入的。通過使用後綴 f 或 l常量可以分別指定為 float 或 long double
18.46e0 // 18.46 18.46e1 // 184.6
字符常量
`\` 轉義符 `\a` 警報鈴聲 `\b` 退格鍵 `\f` 換頁符 `\n` 換行符 `\r` 回車 `\t` 水平制表符 `\v` 垂直制表符 `\ooo` 一到三位的八進制數 `\xhh...` 一個或多個數字的十六進制數
定義常量
#define 預處理器
\#define LENGTH 10
const前綴聲明指定類型的常量
常量不能更新
const int LENGTH = 10;
修飾符類型
explicit
構造函數用於防止隱式調用!
存儲類
register
存儲類 用於定義存儲在寄存器中而不是 RAM 中的局部變量。不能對它應用&
static
存儲類 指示編譯器在程序的生命周期內保持局部變量的存在.
即在函數中static int i = 5;
局部靜態變量 重復調用函數時還能再訪問iextern
存儲類 在子文件中聲明已存在一個已定義的變量或函數的引用mutable
存儲類 後面講解thread_local
存儲類 聲明的變量僅可在它在其上創建的線程上訪問.變量在創建線程時創建,並在銷毀線程時銷毀。 每個線程都有其自己的變量副本。可以與 static 或 extern 合並。僅應用於數據聲明和定義,不能用於函數聲明或定義。thread_local int x; class X { static thread_local std::string s; }; static thread_local std::string X::s; void foo() { thread_local std::vector<int> v; }
運算符
算術運算符
% 取余運算
- 關系運算符
邏輯運算符
&& 與(並且) 邏輯與 AND
||(或) 邏輯或 OR
!(非)位運算符
A = 0011 1100 B = 0000 1101
& 二邊為真才為真 ,A&B = 0000 1100 位與 AND
| 有一個為真即真 ,A|B = 0011 1101 位或 OR
^ 二邊不一樣的真 ,A^B = 0011 0001 位異或 XOR
~ 取反相, ~A = 1100 0011賦值運算符
C += A//相當於 C = C + A C -= A//相當於 C = C - A C *= A//相當於 C = C * A C /= A//相當於 C = C / A C %= A//相當於 C = C % A C <<= 2//等同於 C = C << 2 C >>= 2//等同於 C = C >> 2 C &= 2//等同於 C = C & 2 C ^= 2//等同於 C = C ^ 2 C |= 2//等同於 C = C | 2
雜項運算符
sizeof 返回變量的大小,字節數如sizeof(int),返回4
x = (y < 10) ? 30 : 40; 當Y=10時,X取40 相當於if語句
.
點運算符與->
箭頭運算符 箭頭操作符是結構體 或者 對象 指針用來訪問其對象 或者 對象成員時用的符號比如struct aaa{int a,int b;};class bb{int a;int b‘;void test()};當我們定義一個結構體變量的時候比如 aaa t; bb t;往往是通過.符號來獲得或者訪問其中的成員變量 或者函數如 t.a t.b t.test()但是 如果我們定義的是一個結構體指針aaa t;bb t那麽就需要用箭頭符號來訪問了t->a t->b t->test()這麽講你明白了嗎強制轉換運算符 把一種數據類型轉換為另一種數據類型。
int(2.2000) 將返回 2。指針運算符 & 返回變量的地址。例如 &a; 將給出變量的實際地址。
指針運算符 * 指向一個變量。例如,*var; 將指向變量 var。
循環
循環類型
- while(表達式){};
- for(初始化,表達式,i++){};
do{...}while(表達式);
循環控制
- break跳出(中斷)循環體
- continue跳出本次循環(不中斷)
goto轉移到被標記,(不建議使用)
函數
函數參數
- 傳值調用--
oid swap(int x, int y)
調用時swap(a, b);
- 指針調用--
void swap(int *x, int *y)
調用時swap(&a, &b);
引用調用--
swap(int &x, int &y)
調用時swap(a, b);
數字
數學運算
double cos(double);
該函數返回弧度角(double 型)的余弦。double sin(double);
該函數返回弧度角(double 型)的正弦。double tan(double);
該函數返回弧度角(double 型)的正切。double log(double);
該函數返回參數的自然對數。double pow(double, double);
假設第一個參數為 x,第二個參數為 y,則該函數返回 x 的 y 次方。double hypot(double, double);
該函數返回兩個參數的平方總和的平方根,也就是說,參數為一個直角三角形的兩個直角邊,函數會返回斜邊的長度。double sqrt(double);
該函數返回參數的平方根。int abs(int);
該函數返回整數的絕對值。double fabs(double);
該函數返回任意一個十進制數的絕對值。double floor(double);
該函數返回一個小於或等於傳入參數的最大整數。數組
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0}; double salary = balance[9]; int a[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};//多維數組
指向數組的指針
double *p; double balance[10]; p = balance;
使用數組名作為常量指針是合法的,反之亦然。因此,
*(balance + 4)
是一種訪問balance[4]
數據的合法方式。一旦您把第一個元素的地址存儲在p
中,您就可以使用*p
、*(p+1)
、*(p+2)
等來訪問數組元素。傳遞數組給函數
從函數返回數組
C++ 不允許返回一個完整的數組作為函數的參數。但是,您可以通過指定不帶索引的數組名來返回一個指向數組的指針。如果您想要從函數返回一個一維數組,您必須聲明一個返回指針的函數,如下:
\#include <iostream>
\#include <cstdlib>
\#include <ctime>
using namespace std;
// 要生成和返回隨機數的函數
int * getRandom( )
{
static int r[10];
// 設置種子
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// 要調用上面定義函數的主函數
int main ()
{
// 一個指向整數的指針
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}
字符串
字符
char greeting[6] = {‘H‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘, ‘\0‘};//字符組
cout << greeting << endl; //輸出
strcpy(s1, s2);
復制字符串 s2 到字符串 s1。strcat(s1, s2);
連接字符串 s2 到字符串 s1 的末尾。strlen(s1);
返回字符串 s1 的長度。strcmp(s1, s2);
如果 s1 和 s2 是相同的,則返回 0;如果 s1strchr(s1, ch);
返回一個指針,指向字符串 s1 中字符 ch 的第一次出現的位置。strstr(s1, s2);
返回一個指針,指向字符串 s1 中字符串 s2 的第一次出現的位置。
String類
string str1 = "Hello";
str1.size();//返回長度
指針
指針可以理解為是一個變量,但這變量只存儲地址信息,地址
int var = 20;// 實際變量的聲明
int *ip;// 指針變量的聲明
ip = &var;// 在指針變量中存儲 var 的地址
空指針
int *ptr = NULL;
空指針,其地址值為0,空指針中不允許訪問地址為 0 的內存,
所以cout <<"ptr的值" <<*ptr;
會報錯,應先if(ptr)
判斷
指針數組
\#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr[MAX]; //指針數組
for (int i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; // 賦值為整數的地址
}
for (int i = 0; i < MAX; i++)
{
cout << "Value of var[" << i << "] = ";
cout << *ptr[i] << endl;
}
return 0;
}
指向指針的指針(多級間接尋址)
int var;
int *ptr;
int **pptr;
var = 3000;
ptr = &var;// 獲取 var 的地址
pptr = &ptr;// 使用運算符 & 獲取 ptr 的地址
傳遞指針給函數
getSeconds( &sec );//調用時
void getSeconds(unsigned long *par)
{
// 獲取當前的秒數
*par = time( NULL );
return;
}
getAverage( balance, 5 );
double getAverage(int *arr, int size)
{
//...
}
從函數返回指針
C++ 不支持在函數外返回局部變量的地址,除非定義局部變量為 static 變量。
int * myFunction()
{
}
//調用
int *p;
p = getRandom();
引用
其與直接使用參數的區別在於,不用開辟一塊內存,進行賦值拷貝動作。(可以理解這是一個另名)
把引用作為參數
void swap(int& x, int& y);
int main ()
{
int a = 100;
int b = 200;
swap(a, b);// 調用函數來交換值
return 0;
}
void swap(int& x, int& y)
{
int temp;
temp = x; /* 保存地址 x 的值 */
x = y; /* 把 y 賦值給 x */
y = temp; /* 把 x 賦值給 y */
return;
}
把引用作為返回值
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{
return vals[i]; // 返回第 i 個元素的引用
}
int main ()
{
setValues(1) = 20.23; // 改變第 2 個元素
setValues(3) = 70.8; // 改變第 4 個元素
}
註意:1.不能返回局部變量的引用。2.不能返回函數內部new分配的內存的引用 3.可以返回類成員的引用,但最好是const。
日期與時間
程序中引用 <ctime>
頭文件。
struct tm { //結構體
int tm_sec; // 秒,正常範圍從 0 到 59,但允許至 61
int tm_min; // 分,範圍從 0 到 59
int tm_hour; // 小時,範圍從 0 到 23
int tm_mday; // 一月中的第幾天,範圍從 1 到 31
int tm_mon; // 月,範圍從 0 到 11
int tm_year; // 自 1900 年起的年數
int tm_wday; // 一周中的第幾天,範圍從 0 到 6,從星期日算起
int tm_yday; // 一年中的第幾天,範圍從 0 到 365,從 1 月 1 日算起
int tm_isdst; // 夏令時
}
示例
\#include <stdio.h>
\#include <time.h>
int main ()
{
clock_t start_t, end_t;
double total_t;
start_t = clock();//clock_t clock(void)返回程序執行起(一般為程序的開頭)處理器時鐘所使用的時間
time_t rawtime;
struct tm *info; //結構體tm
char buffer[80];
time( &rawtime );//返回系統的當前自 1970 年 1 月 1 日以來經過的秒數
info = localtime( &rawtime );//使用 timer 的值來填充 tm 結構
printf("當前的本地時間和日期:%s", asctime(info));
end_t = clock();
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;//CLOCKS_PER_SEC是標準c的time.h頭函數中宏定義的一個常數,表示一秒鐘內CPU運行的時鐘周期數,用於將clock()函數的結果轉化為以秒為單位的量
printf("CPU 占用的總時間:%f\n", total_t );
return(0);
}
基本輸入輸出
- cout 輸出 cout <<"test"<<endl;
- cin 輸入 cin >> name;
- cerr 錯誤流 cerr << "test" << endl;
- clog 日誌流 clog << "test" << endl;
數據結構
strcpy(str1,str2);把str2的字符串數據復制到str1中!
指向結構的指針
printBook( &Book1 );//main調用
void printBook( struct Books *book )
{
cout << "書標題 : " << book->title <<endl;
cout << "書作者 : " << book->author <<endl;
cout << "書類目 : " << book->subject <<endl;
cout << "書 ID : " << book->book_id <<endl;
}
類&對象
類定義
\#include <iostream>
using namespace std;
class Box
{
public:
double length; // 盒子的長度
double breadth; // 盒子的寬度
double height; // 盒子的高度
double getVolume(void);// 返回體積
};
double Box::getVolume(void) //範圍解析運算符::定義該函數
{
return length * breadth * height;
}
int main()
{
Box Box1;
double volume = 0.0;// 用於存儲體積
Box1.length=6;
Box1.breadth=7;
Box1.height=5;
volume = Box1.getVolume();
cout << "Box1 的體積:" << volume <<endl;
return 0;
}
}
繼承
格式
class Rectangle: public Shape{}
Shape為基類
多繼承
class <派生類名>:<繼承方式1><基類名1>,<繼承方式2><基類名2>,…{<派生類類體>};
虛繼承
格式:class 類名: virtual 繼承方式 父類名
- 舉例來說:假如類A和類B是由類X繼承而來(非虛繼承且假設類X包含一些成員),且類C同時繼承了類A和B,那麽C就會擁有兩套和X相關的成員(可分別獨立訪問,一般要用適當的消歧義修飾符)。但是如果類A虛繼承自類X,那麽C將會只包含一組類X的成員數據。
重載運算符和重載函數
重載函數
class printData
{
public:
void print(int i) {
cout << "整數為: " << i << endl;
}
void print(double f) {
cout << "浮點數為: " << f << endl;
}
};
運算符重載
// 重載 + 運算符,用於把兩個 Box 對象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
return box; //返回box
}
// 重載小於運算符( < )
bool operator <(const Distance& d)
{
if(feet < d.feet)
{
return true;
}
if(feet == d.feet && inches < d.inches)
{
return true;
}
return false;
}
//重載輸出
friend ostream &operator<<( ostream &output,
const Distance &D )
{
output << "F : " << D.feet << " I : " << D.inches;
return output;
}
//重載輸入
friend istream &operator>>( istream &input, Distance &D )
{
input >> D.feet >> D.inches;
return input;
}
其它重載請查看 菜鳥教程
C++入門基礎筆記