編程思維
1,編程的時候時常想想內(nèi)存大概的模型已經(jīng)劃分的區(qū)域(主要四大區(qū):靜態(tài)存儲區(qū)(數(shù)據(jù)段) 堆 棧 代碼段),[數(shù)據(jù)段可存放靜態(tài)數(shù)據(jù)和自由變量]變量 函數(shù)等在內(nèi)存是在哪個區(qū)域的,加了修飾詞有什么不同;[函數(shù)代碼存放在代碼段。聲明的類如果從未使用,則在編譯時,會優(yōu)化掉,其成員函數(shù)不占代碼段空間。
補充:代碼段、數(shù)據(jù)段、棧是CPU級別的邏輯概念,堆是語言級別的邏輯概念全局變量或靜態(tài)變量,放在數(shù)據(jù)段,]
[數(shù)據(jù)段:數(shù)據(jù)段(data segment)通常是指用來存放程序中已初始化的全局變量的一塊內(nèi)存區(qū)域。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。]
函數(shù)形參存放位置:主函數(shù)的是放在堆里面的,臨時變量都是放在棧里面的;
2,聲明變量去"接住"你獲得的數(shù)據(jù)進行操作;實現(xiàn)你要的功能,不要去管其他東西;會用是一個層次,理解低層實現(xiàn)原理是另外一個層次;
內(nèi)存主要分布:不可訪問區(qū)、代碼段、數(shù)據(jù)段、堆、棧、內(nèi)核
①代碼段:.text:用于存放用戶代碼;.init:用于存儲系統(tǒng)給每一個程序自動添加的"初始化"代碼
②數(shù)據(jù)段:.bass 專門存儲未初始化的靜態(tài)變量,它們的值會被初始化為0,static int i;.data 專門存儲已初始化的靜態(tài)數(shù)據(jù)(靜態(tài)數(shù)據(jù):所有全局變量(全局變量默認初始化為0),及static的局部變量).rodata 存放只讀數(shù)據(jù)(用const修飾),比如字符串、字符常量、整形等 char *p = "helloworld"; //"helloworld"只讀字符串
③堆:一塊自由的內(nèi)存,用戶可以根據(jù)自己需求開辟空間大小,內(nèi)存釋放也是由用戶自己進行釋放(malloc realloc calloc開辟堆空間,釋放free)
④棧:它是從0xC0000000往下增長的部分(后進先出),大概8M,專門存放函數(shù)局部變量(思考:如何判斷棧是往下增長的 //先進入棧的變量在棧底),
??臻g就是指放置程序的局部數(shù)據(jù)(也就是函數(shù)內(nèi)數(shù)據(jù))的內(nèi)存空間;
全局變量:存放.data當中,如果沒有賦值系統(tǒng)默認初始化為0,如果沒有被static修飾其它文件可以調(diào)用的變量

一 內(nèi)存效率相關(guān)(常見關(guān)鍵字)
哪些區(qū)哪些特點 畫圖
①static作用(限制變量/函數(shù)(靜態(tài))的作用域;設(shè)置變量的存儲域(主動分配內(nèi)存在堆))
1.全局變量時存儲在不變區(qū)(靜態(tài)變量區(qū))但限制作用域;不能被模塊外其它函數(shù)訪問(靜態(tài)函數(shù)類似,也可防沖突);
*靜態(tài)函數(shù)會被自動分配在一個一直使用的存儲區(qū),直到退出應(yīng)用程序?qū)嵗?,避免了調(diào)用函數(shù)時壓棧出棧,速度快很多;內(nèi)部函數(shù)又稱靜態(tài)函數(shù)(static修飾,不怕同名)
2.修飾局部變量時變存儲區(qū)域"棧"為靜態(tài)存儲區(qū)(區(qū)別auto),代表該內(nèi)存只被分配一次而且下次調(diào)用時仍維持上次的值;
例:函數(shù)中定義,static int j = 10; //此時作用等同為全局變量,靜態(tài)局部變量只初始化一次?->第二次調(diào)用不執(zhí)行

static總結(jié) http://blog.csdn.net/damon_hoo/article/details/38903041
1.靜態(tài)局部變量:靜態(tài)局部變量始終存在,生存期為整個源程序,作用域和局部變量是一樣的,靜態(tài)局部變量會被自動的初始化為0.
2.靜態(tài)全局變量:靜態(tài)全局變量只能在一個文件中使用
3.靜態(tài)數(shù)據(jù)成員變量:描述整個類的特征,是整個類的成員,而不是一個對象的成員
static int i;
初始化靜態(tài)數(shù)據(jù)成員在類體外進行,而且前面不加static,以免和一般靜態(tài)變量混淆
一般在cpp里面初始化,格式
int CStudent::num = 0;
4.靜態(tài)成員函數(shù):屬于整個類的成員函數(shù),是整個類的成員,而不是一個對象的成員,它的調(diào)用形式可以用對象來調(diào)用它,也可以用類的名字來調(diào)用它,靜態(tài)成員函數(shù)可以有類名通過::直接調(diào)用,但是非靜態(tài)成員函數(shù)只能通過對象名來調(diào)用。
靜態(tài)成員函數(shù)沒有this指針,可以直接訪問該類的靜態(tài)成員和靜態(tài)成員函數(shù),而不能直接操作非靜態(tài)的成員變量和非靜態(tài)成員函數(shù),如果靜態(tài)成員函數(shù)中要引用非靜態(tài)成員,則可以通過對象來引用,
②extern 修飾的變量(這里的變量給外部使用)或者函數(shù)不僅本文使用,外部文件也可以使用?
溫工:extern引用其他文件的函數(shù)
③register 數(shù)據(jù)類型 變量名;//聲明寄存器變量
register int i; //i就是一個寄存器變量
1、用register修飾的變量告訴編譯器不要優(yōu)化,運行效率高
2、不一定能100%分配變量為寄存器變量
④C中的宏與C++中的inline關(guān)鍵字聲明頻繁使用的小函數(shù)
①②對應(yīng)靜態(tài)存儲期:static聲明的局部變量具有靜態(tài)存儲持續(xù)期(static storage duration),或靜態(tài)范圍(static extent).雖然他的值在函數(shù)調(diào)用之間保持有效,但是其名字的可視性仍限制在其局部域內(nèi)。靜態(tài)局部對象在程序執(zhí)行到該對象的聲明處時被首次初始化;
③對應(yīng)自動存儲期(auto):變量在進入聲明該變量的程序塊時被建立,它在該程序塊活動時存在,退出該程序塊時撤銷
⑤synchronized
volatile三種作用:防止編譯器優(yōu)化;不會阻塞線程;解決變量在多個線程之間的可見性
1.與該變量有關(guān)的運算,不要進行編譯優(yōu)化,以免出錯
⑥inline內(nèi)聯(lián)函數(shù) http://www.cnblogs.com/li-hao/archive/2013/03/15/2961713.html
二 數(shù)組與指針
void型指針不能解引用(目標類型未定),解引用前必須轉(zhuǎn)化為某種具體的指針類型
④const修飾內(nèi)容不能做任何改變
例子:int *const p = &test1; //保護的是p里的內(nèi)容,只能在定義里賦值
//p = &test2; p為常量,不能再賦值
const char p == char const p(修改p)
(1)常量指針,不能通過這個指針改變變量的值,但是還是可以通過其他指針的引用或者變量來改變里面的值
(2)常量指針指向的值不能改變,但是這并不意味著指針不能改變,指針可以指向其它變量的
int test1 = 100;
const int p;
int pp;
p = &test1; //指針與變量關(guān)聯(lián)
pp = &test1;
test1 = 200; //通過變量改變里面的值
pp = 70; //通過其他未用const指針來修改里面的值
//p = 25; //error: assignment of read-only location ‘p’
printf("p = %d\n",p);
printf("test1 = %d\n",test1);
char *const p:
(1)指針常量:指針本身是一個常量,不能再指向別的地址
(2) 指針常量里面的地址不能改變,但是地址中保存的值是可以改變的
int test1 = 100;
int test2 = 25;
int const p = &test1; //保護的是p里的內(nèi)容,只能在定義里賦值
//p = &test2; p為常量,不能再賦值
test1 =45;
p = 70;
printf("p = %d\n",p);
printf("test1 = %d\n",test1);
const int const p:指向常量的常指針。p里面的內(nèi)容不可以改變,同時也不能通過p改變地址指向的內(nèi)存
⑤數(shù)組初始化 數(shù)組求長-\n也算
bzero menset 定義剛好的數(shù)組
char buf[50]={0};//50個都為0
char buf[50]={1};//只有第一個為1
特殊定義:
void func1(void);
void func2(void (p)(void));
typedef void(fi)(void (*f2)(void));
f1 a ;
意思:上面是一個指針(函數(shù)指針),指向返回類型為void,參數(shù)是一個函數(shù)指針的指針;


long在32位編譯器下是4個字節(jié)
?引用傳參的效率
⑥typedef重命名
typedef char *p;
p a="hello";//等價于char *a="hello";
⑨inline 必須是在函數(shù)定義時修飾函數(shù)才有效,如果只是單純的在聲明時加了inline關(guān)鍵字,而在定義時未加則等于沒有適用inline關(guān)鍵字
1.使用場景:https://www.cnblogs.com/fnlingnzb-learner/p/6423917.html
//inline提高效率 函數(shù)需要短小精悍 看編譯器優(yōu)化處理 編譯時替換
inline int add(int x,int y,int z){
return x + y + z;
}//類似template
三 分配優(yōu)化與安全溢出
⑦泄露與溢出
堆棧溢出一般是循環(huán)的遞歸調(diào)用導致(或者大數(shù)據(jù)結(jié)構(gòu)的局部變量)
⑧虛擬機溢出標志-can not write
四 內(nèi)存映射函數(shù)
/*#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
addr ----- > 我們所申請的內(nèi)存空間的起始地址
NULL ----》系統(tǒng)自動分配
length---- >內(nèi)存空間的大小
port ------>操作權(quán)限
PROT_READ 可讀
PROT_WRITE 可寫
flags------> 共享屬性
MAP_SHARED 可以共享
MAP_PRIVATE 私有
fd--------> 硬件設(shè)備的文件描述符
offset----》光標偏移量
int munmap(void addr, size_t length);/
五 編譯&優(yōu)化等級
http://blog.chinaunix.net/uid-25768133-id-3485479.html
attribute ((packed))告訴編譯器取消結(jié)構(gòu)在編譯過程中的優(yōu)化對齊,按照實際占用字節(jié)數(shù)進行對齊,是GCC特有的語法。這個功能是跟操作系統(tǒng)沒關(guān)系,跟編譯器有關(guān),gcc編譯器不是緊湊模式的,我在windows下,用vc的編譯器也不是緊湊的,用tc的編譯器就是緊湊的
六 程序啟動/運行流程
1.問題:程序開機自啟(程序需要root權(quán)限才能啟動)
!/bin/bash
sh /home/hwjc/RSA/release2017-02-23/release2017-02-23/install.sh
sh /etc/init.d/mqtt.sh
ifconfig
更改 vi /etc/profile
加至末尾:echo yhn!#!%!^ | sudo -S /home/hwjc/RSA/release2017-02-23/release2017-02-23/init.sh
改完保存退出
輸入命令:source /etc/profile 即可