char* stackValue(void){
char str[20] = {'A'};
return str;
}
void stackChange(void){
char str[20] = {'B'};
}
int main(int argc, char * argv[]) {
int result_i = 0;
unsigned long result_ul = 0;
int num_i = 0;
/*- ','逗號(hào)運(yùn)算符 -*/
//賦值運(yùn)算符的優(yōu)先級(jí)別高于逗號(hào)運(yùn)算符董栽,逗號(hào)運(yùn)算符是所有運(yùn)算符中級(jí)別最低的
result_ul = 2, 3; //值為2
result_ul = (2, 3); //值為3
/*- 符號(hào)的貪婪操作瞭稼,從左往右匹配到最多的符號(hào),后置運(yùn)算與編譯器相關(guān) -*/
num_i = 3;
result_ul = num_i+++num_i;
//num_i值為3; result_ul值為7 編譯器相關(guān)
num_i = 3;
result_ul = (++num_i) * (++num_i) * (++num_i);
//num_i值為6; result_ul值為120 = 4*5*6
num_i = 3;
result_ul = (num_i++) * (num_i++) * (num_i++);
//num_i值為6; result_ul值為60 = 3*4*5 編譯器相關(guān)
/*- 返回棧地址 危險(xiǎn)操作-*/
char* stackRet = stackValue();
char old_c = stackRet[0]; //'A'
stackChange();
char change_c = stackRet[0]; //'B'
//數(shù)據(jù)由‘A’變?yōu)椤瓸’绘面,地址對(duì)應(yīng)的椇缃空間數(shù)據(jù)被修改
/* '*' 和 '[]'的優(yōu)先級(jí), 數(shù)組指針, 指針數(shù)組 */
int * ary[10] = {}; //'[]'的優(yōu)先級(jí)高,這里是數(shù)組飒货,存在的是‘int *’
int (*ary_p) [10] = NULL; //指針魄衅,指向儲(chǔ)存’Int‘的數(shù)組
/* 指針加一 數(shù)組變量加一 首元素加一 */
char num_ary[5]={'A','B','C','D','E'};
//&num_ary值為數(shù)組的地址,類型為'char (*) [5]'塘辅,
//加一地址為數(shù)組結(jié)束后的地址
char* c_p = (char*)(&num_ary + 1);
char c_1 = *(c_p - 1); //值為'E'
//指針類型強(qiáng)轉(zhuǎn)為'char *'晃虫,減一變?yōu)閿?shù)組最后一個(gè)元素的地址
//num_ary與&num_ary[0]值相等為第一個(gè)元素地址且類型一致為’char*‘
char c_2 = *(num_ary + 1); //值為'B'
char c_3 = *(&num_ary[0] + 1); //值為'B'
/* 數(shù)組初始化指定位置 */
int new_ary[] = {
['A'] = 9,
};
//將創(chuàng)建儲(chǔ)存66個(gè)Int的數(shù)組,由于‘A’的char值為65扣墩,new_ary[65] = 9哲银;
/* sizeof 為關(guān)鍵字不是函數(shù) */
int test[10];
result_ul = sizeof(test); //sizeof(int) * 100
result_ul = sizeof(test[11]);
result_ul = sizeof(&test);
result_ul = sizeof(&test[11]);
//sizeof在編譯階段進(jìn)行處理獲取值,運(yùn)行階段是不會(huì)執(zhí)行‘test[11]’越界訪問
/* const 修飾呻惕,去掉類型觀看*/
int const * con_p1 = &num_i; //修飾指針對(duì)應(yīng)的內(nèi)容
int * const con_p2 = &num_i; //修飾指針
const int * con_p3 = &num_i; //去掉類型‘int’觀看荆责,同con_p1;
//*con_p1 = 7; //編譯失敗
//con_p2 = &result_i; //編譯失敗
/* 預(yù)處理的 #define #undef */
#define X 1
#define Y X*2
#undef X
//result_i = Y; //編譯失敗:‘X’未定義
/* volatile 關(guān)鍵字: 易失的亚脆;易變的*/
//http://www.cnblogs.com/god-of-death/p/7852394.html
/* register 關(guān)鍵字 */
register int num_reg = 1;
//int* num_reg_p = &num_reg; //編譯錯(cuò)誤做院,寄存器無法獲取地址
/* enum 內(nèi)存大小 */
/*enum變量占用的空間與編譯器相關(guān)。
C標(biāo)準(zhǔn):“枚舉型尺寸是能夠容納最大枚舉子值的整數(shù)尺寸”濒持,
“枚舉類型中枚舉子的值必須要能用一個(gè)int型表述”键耕。
也就是說,枚舉型的尺寸不能超過int型柑营,但不必等于int型屈雄,
只要能容納最大枚舉子就行。
gcc也有類似選項(xiàng)-fshort-enums官套,設(shè)置后就選用節(jié)省內(nèi)存的enum長(zhǎng)度酒奶。*/
enum Color{
Color_a = CHAR_MAX,
Color_b = CHAR_MIN,
} Color;
result_ul = sizeof(Color);
result_ul = sizeof(Color_a);
/* union 內(nèi)存大小 */
/*1.聯(lián)合就是一個(gè)結(jié)構(gòu);
2.它的所有成員相對(duì)于基地址的偏移量都為0奶赔;
3.此結(jié)構(gòu)空間要大到足夠容納最“寬”的成員惋嚎;
4.其對(duì)齊方式要適合于聯(lián)合中所有類型的成員。 */
union U1{
char s[9];
char n;
};
union U2{
char s[9];
int n;
};
union U3{
char s[9];
double n;
};
result_ul = sizeof(union U1); //9
result_ul = sizeof(union U2); //12
result_ul = sizeof(union U3); //16
/* struct 內(nèi)存大小 */
/*1.結(jié)構(gòu)體的對(duì)齊最大單位:使用了‘pack’宏則用指定的值纺阔,
沒有指定則使用結(jié)構(gòu)體成員類型的最大值
(成員為數(shù)組取存儲(chǔ)元素的類型大小用于判斷瘸彤,
成員為結(jié)構(gòu)體取它的對(duì)齊最大單元用于判斷),
2.成員的偏移量:如果其類型大小小于對(duì)齊最大單位笛钝,
那么前面占用空間必須為其類型大小的整數(shù)倍质况;
如果其類型大于對(duì)齊最大單位,
那么前面占用空間必須為對(duì)齊最大單位的整數(shù)倍玻靡。
(所以‘pack’宏的值只能是基礎(chǔ)類型對(duì)應(yīng)值:‘0结榄,1,2囤捻,4臼朗,8,16’)*/
struct empty_struct {
}empty_struct;
result_ul = sizeof(empty_struct); //0
#pragma pack(2)
typedef struct{
char c1[3]; //0
char* c2; //4
}T_U1;
#pragma pack(0)
#pragma pack(4)// -> pack(1)
typedef struct{ //默認(rèn)對(duì)齊大小最大值為4(i成員類型值最大4蝎土,uu為2)
char c1; //0 -> 0
short s; //2 -> 1
char c2; //4 -> 3
int i; //8 -> 4
char cc[20]; //12 -> 8
T_U1 uu; //32 -> 28
}T_Struct;
#pragma pack()
T_Struct one;
result_ul = sizeof(one); //44 -> 40
unsigned int start_addr = (unsigned int)(void*)&one;
result_ul = (unsigned int)(void*)&one.c1 - start_addr;
result_ul = (unsigned int)(void*)&one.s - start_addr;
result_ul = (unsigned int)(void*)&one.c2 - start_addr;
result_ul = (unsigned int)(void*)&one.i - start_addr;
result_ul = (unsigned int)(void*)&one.uu - start_addr;
}
Demo覆蓋的內(nèi)容:
- 返回棧地址
-
‘,’
號(hào)運(yùn)算符 -
struct
大小 設(shè)置對(duì)齊大小 空結(jié)構(gòu)圖 -
enum
大小 空 有值 - 符號(hào)的貪婪操作
-
‘*’
和‘[]’
的優(yōu)先級(jí) 數(shù)組指針 指正數(shù)組 - 指針加一 數(shù)組變量加一 首元素加一
- 預(yù)處理的
define undefine
-
volatile
關(guān)鍵字 - 數(shù)組初始化指定位置
-
sizeof
關(guān)鍵字不是函數(shù) -
const
修飾 -
union
大小
看下面的Refs比上面的好看多了^_^
Refs:
《C語(yǔ)言深度剖析》