-
函數(shù)返回值類型+(指針變量名)+(函數(shù)傳入的參數(shù))=函數(shù)名
第25行的代碼表示用指針的形式調(diào)用函數(shù)
dowork()回調(diào)函數(shù)的用法
查看全部 -
指針可以指向一個數(shù)組,例如:
#include <stdio.h>
int main(int argc,char **argv)
{
? ?int arr[] = {1, 2, 3, 4};
? ?int * p = arr;
? ?return 0;
}比較特殊的是,數(shù)組名就是一個指針,不過數(shù)組名是一個常量指針,不能做累加或者累減操作。
我們可以通過指針來訪問數(shù)組元素:
*(p + 2)
同樣,這句話等價于:
p[2]
查看全部 -
指針可以指向一個變量,例如:
#include <stdio.h>
int main(int argc,char **argv)
{
? ?int a = 0;
? ?int * p = &a;
? ?return 0;
}如果想要通過指針操作變量,只需要使用解引用就可以了:
*p = 20;
查看全部 -
.與->的不同用法
查看全部 -
arr里面放的是數(shù)組內(nèi)第一個元素的地址,等同于&arr【0】
查看全部 -
#include <stdio.h>
int main()
{
? ?int i = 0x1122;
? ?char * p = (char *)&i;
? ?if (p[0] == 0x22 && p[1] == 0x11) {
? ? ? ?printf("Little Endian\n");
? ?}
? ?else if (p[0] == 0x11 && p[1] == 0x22) {
? ? ? ?printf("Big Endian\n");
? ?}
}判斷電腦是哪種字節(jié)序
查看全部 -
字節(jié)序,就是 大于一個字節(jié)類型的數(shù)據(jù)在內(nèi)存中的存放順序。
計算機(jī)硬件有兩種儲存數(shù)據(jù)的方式:大端字節(jié)序(big endian)和小端字節(jié)序(little endian)。
我們現(xiàn)在有一個整數(shù)是258。用16進(jìn)制表示是0x0102,然后我們把這個整數(shù)拆分成兩個字節(jié),第一個字節(jié)為 0000 0001,第二個字節(jié)為 0000 0010。
如果在一個使用大端字節(jié)序的電腦上,這個整數(shù)會被這樣存放:
如果一個使用小端字節(jié)序的電腦上,這個整數(shù)的高字節(jié)就會存放在高地址上:
現(xiàn)在大部分的機(jī)器,都采用了小端字節(jié)序。但是在 IO 方面,則大部分使用大端字節(jié)序。例如,你要使用網(wǎng)絡(luò)發(fā)送一個 int 類型的變量,要先把 int 轉(zhuǎn)換成大端字節(jié)序,然后通過網(wǎng)絡(luò)發(fā)送。
大端字節(jié)序又被稱之為網(wǎng)絡(luò)細(xì)節(jié)序。
查看全部 -
~ 取反
^ 異或
<< 左移
>> 右移
查看全部 -
浮點數(shù)會有一定的精度范圍,一旦小數(shù)點后面位數(shù)過多,超出范圍,就有可能失去精度。
浮點數(shù)的存放復(fù)雜,運行起來速度也比較慢,如無必要,還是用整數(shù)方便快捷。
查看全部 -
復(fù)制一個員工:賦值構(gòu)造函數(shù)
上一小節(jié)中,我們介紹了構(gòu)造函數(shù)和析構(gòu)函數(shù)。這一小節(jié),我們來介紹一個特殊的構(gòu)造函數(shù)。
先來看一個例程:
int main(int argc,char **argv) { ? ? Staff staffA; ? ? Staff staffB = staffA; ? ? return 0; }
我們先實例化了一個對象 staffA,然后又實例化了一個對象 staffB。希望 staffB 和 staffA 具有相同的內(nèi)容,或者說希望 staffB 是 staffA 的副本,那么我們一般直接在實例化的時候進(jìn)行賦值就可以了。
Staff staffB = staffA;
這樣做了之后,C++ 會自動為我們拷貝 staffA 中的成員變量到 staffB 的成員變量中,但是這種自動拷貝機(jī)制在某些情況下無法完成我們想要的動作,甚至有可能會出錯。我們來具體看一下。
在 Staff 類中添加一些內(nèi)容:
Staff.hpp
#include <string>
class Staff {?
public: ? ??
????Staff(std::string _name, int _age); ? ??
????~Staff();?
public: ? ??
????std::string name; ? ?
????int age; ? ??
????char * mem = nullptr; };
Staff.cpp
#include "Staff.hpp"?
#include <stdio.h>?
Staff::Staff(std::string _name, int _age) { ? ?
?mem = (char *)malloc(20); ? ??
name = _name; ? ?
?age = _age; ? ??
printf("構(gòu)造函數(shù)被調(diào)用\n");?
}?
Staff::~Staff() { ? ?
?if(mem != nullptr){ ? ? ? ? free(mem); ? ? ? ? mem = nullptr; ? ? } ? ??
printf("析構(gòu)函數(shù)被調(diào)用\n");?
}
在上面的代碼中,在類中定義了一個指針,在構(gòu)造函數(shù)中,通過 malloc 函數(shù)分配了一個 20 字節(jié)大小的堆內(nèi)存,然后將這片堆內(nèi)存的首地址賦值給了這個指針。在析構(gòu)函數(shù)中,我們將這片堆內(nèi)存釋放掉。
這個時候,我們再進(jìn)行一開始的操作:
Staff staffB = staffA;
先來看看 staffA 在實例化之后的內(nèi)存布局:
mem 指針指向了一片 20 個字節(jié)大小的堆內(nèi)存。
這個時候,再來看看執(zhí)行了Staff staffB = staffA;之后,staffB 的內(nèi)存布局會怎么樣:
可以看到,在 C++ 默認(rèn)的復(fù)制模式之下,兩個對象中的 mem 指針指向了同一片內(nèi)存。因為 C++ 默認(rèn)的復(fù)制模式只會簡單得把成員的值進(jìn)行復(fù)制,面對這個 mem 指針,他只會把指針的值進(jìn)行拷貝,最后的結(jié)果就是 mem 指針指向了同一片內(nèi)存。
這種拷貝方式,被稱之為淺拷貝。
賦值構(gòu)造函數(shù)
Staff staffB = staffA;
當(dāng)我們使用這種方式實例化對象的時候,并不會調(diào)用普通構(gòu)造函數(shù),而是會調(diào)用一個特殊的構(gòu)造函數(shù),被稱之為賦值構(gòu)造函數(shù)或者拷貝構(gòu)造函數(shù)。如果我們沒有寫,那么就會按照淺拷貝的方式來進(jìn)行復(fù)制。一個拷貝構(gòu)造函數(shù)看起來就像下面這樣:
Staff(const Staff & staff);
這個函數(shù)中只有一個參數(shù) staff,表示要拷貝的對象,在我們的例子中,就是 staffA。(const 和 & 我們在后續(xù)的課程中會具體講解)
那么我們來完整的編寫一下這個函數(shù)
Staff.h
#include <string>?
class Staff {?
public: ? ??
????Staff(std::string _name, int _age); ? ?
?????Staff(const Staff & staff); ? ??
????~Staff();?
public: ? ?
?????std::string name; ? ??
????int age; ? ??
????char * mem = nullptr; };
Staff.cpp
#include "Staff.hpp"?
#include <stdio.h>?
Staff::Staff(std::string _name, int _age) { ? ??
????mem = (char *)malloc(20); ? ??
????name = _name; ? ??
????age = _age; ? ??
????printf("構(gòu)造函數(shù)被調(diào)用\n");?
}?
Staff::Staff(const Staff & staff) { ? ??
????name = staff.name; ? ??
????age = staff.age; ? ??
????mem = (char *)malloc(20); ? ??
????memcpy(mem, staff.mem, 20);?
}?
Staff::~Staff() { ? ??
????if(mem != nullptr){ ? ? ? ? free(mem); ? ? ? ? mem = nullptr; ? ? } ? ??
????printf("析構(gòu)函數(shù)被調(diào)用\n");?
}
查看全部 -
函數(shù)返回一個繩子:函數(shù)返回指針
指針變量其實和普通變量沒有什么區(qū)別,一個函數(shù)也是可以正常返回一個指針的。
char * func() { ? ? char * p = nullptr; ? ? return p; }?
int main(int argc,char **argv) { ? ? return 0; }
但是我們需要思考的是,什么情況下我們要返回一個指針,返回指針的時候需要我們注意些什么?通常情況下,我們是希望為函數(shù)外提供一片內(nèi)存,例如,我們可以給函數(shù)外面提供一個數(shù)組。int * func() { ? ? int arr[] = {1, 2, 3, 4}; ? ? return arr; }
但是這樣寫得話,程序會崩潰掉。原因是,arr 數(shù)組是一個局部變量,在 func 結(jié)束之后,其內(nèi)存就被銷毀掉了。此時在函數(shù)外面對其進(jìn)行操作,自然會出問題。所以,要完成這類操作,我們需要把內(nèi)存分配到堆內(nèi)存上面。int * func() { ? ? int * arr = (int *)malloc(4 * sizeof(int)); ? ? return arr; }
這樣就沒有問題了,當(dāng)然,既然是分配在了堆內(nèi)存上,就要記得手動銷毀。int main(int argc,char **argv) { ? ? int * p = func(); ? ? free(p); ? ? return 0; }
查看全部 -
??吧把v(vv?m筋m哦哦看看那幾句臺詞mmnhhy搞個y
查看全部 -
conat修飾成員函數(shù)類似c#中的static,不能調(diào)用非const函數(shù)、不能修改成員變量
查看全部 -
const表示常量的修飾符,可以修飾定義的變量,表示常量不可改變,修飾指針表示指針只能指向固定的位置,修飾指針指向的變量,表示指針指向變量不可修改(但是指針可以指向其他位置),修飾函數(shù)表示返回的數(shù)據(jù)不能修改;
查看全部 -
多態(tài):即是通過繼承虛函數(shù)來實現(xiàn)不同子類的具體實現(xiàn),基類的析構(gòu)函數(shù)設(shè)置為虛函數(shù)目的是讓子類實現(xiàn),這樣就可以調(diào)用子類的析構(gòu)過程,進(jìn)而釋放內(nèi)存。
查看全部
舉報