基本數(shù)據(jù)類型
* 和java類似,不做記錄
* sizeof(int)->獲取int數(shù)據(jù)類型所占大小->其他已此類推
可變參數(shù)
/**
* 可變參數(shù)
* @param count
* @param ...
* @return
*/
int sum(int count, ...) {
va_list varList;
int sumNum = 0;
//指向第一個(gè)可選參數(shù),第二個(gè)參數(shù)應(yīng)該傳遞可變參數(shù)的前面一個(gè)參數(shù),目的是定位知道可變參數(shù)在哪里
va_start(varList, count);
for (int i = 0; i < count; ++i) {
sumNum += va_arg(varList, int);
printf("sumNum is:%d\n", sumNum);
}
//清空varList指針
va_end(varList);
}
宏定義
#define LOG_I(FORMAT,...) printf(FORMAT,__VA_ARGS__);
`__VA_ARGS__`為固定寫法
調(diào)用:LOG_I("%s","這是一個(gè)宏定義");
宏定義相當(dāng)于是一個(gè)替換
LOG_I("%s","這是一個(gè)宏定義")替換后printf("%s","這是一個(gè)宏定義")
結(jié)構(gòu)體
定義:
struct Man {
char *name;
int age;
};
使用:
int main() {
struct Man man;
man.name = "tsimeon";
man.age = 1;
LOG_I("%s %d",man.name,man.age);
return 0;
}
變量使用:
struct Man {
char *name;
int age;
} simeon;
int main() {
simeon.name = "my name is simeon";
simeon.age = 18;
LOG_I("%s %d",simeon.name,simeon.age);
return 0;
}
結(jié)構(gòu)體大小:注意字節(jié)對(duì)齊褐隆,不指定按照默認(rèn)的對(duì)齊
* 自然對(duì)齊,定義的時(shí)候盡量將小數(shù)據(jù)定在前面
1、某個(gè)變量存放的起始位置相對(duì)于結(jié)構(gòu)的起始位置的偏移量是該變量字節(jié)數(shù)的整數(shù)倍员舵;
2工扎、結(jié)構(gòu)所占用的總字節(jié)數(shù)是結(jié)構(gòu)中字節(jié)數(shù)最長(zhǎng)的變量的字節(jié)數(shù)的整數(shù)倍泪酱。
自然對(duì)齊舉例:
struct Struct1
{
short a;
int b;
short c;
};
結(jié)果:
short = 2 補(bǔ) 2
int = 4
short = 2 補(bǔ) 2
sizeof(Struct1) = 12
struct Struct2
{
short a;
short c;
int b;
};
結(jié)果:
2個(gè)short在一起組成一個(gè) 4
sizeof(Struct2) = 8
* 指定對(duì)齊
#pragma pack(2) //指定以2字節(jié)對(duì)齊
struct Struct1
{
short a;
int b;
short c;
};
sizeof(Struct1) = 8
* 取消對(duì)齊
#pragma pack()
struct Struct1
{
short a;
int b;
short c;
};
sizeof(Struct1) = 12
合理的利用字節(jié)可以有效地節(jié)省存儲(chǔ)空間
不合理的則會(huì)浪費(fèi)空間钓觉、降低效率甚至還會(huì)引發(fā)錯(cuò)誤茴肥。(對(duì)于部分系統(tǒng)從奇地址訪問(wèn)int、short等數(shù)據(jù)會(huì)導(dǎo)致錯(cuò)誤)
聯(lián)合體[和結(jié)構(gòu)體類似,成員共占一塊空間,數(shù)據(jù)大小根據(jù)最大的數(shù)據(jù)類型確定]
union Value {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} value;
上面這份代碼復(fù)制的jni.h的jvalue的定義
使用:
value.f = 3.1415926;
value.j = 10000;
LOG_I("f的值:%f j的值:%d",value.f,value.j);
結(jié)果:
f的值:0.000000 j的值:10000
解釋:因?yàn)楣靡粔K空間,所以f的值被j覆蓋所以輸出為0
指針
基本理解:指向內(nèi)存中的一塊地址,操作就是移動(dòng)指針
int i=0;
//輸出的是i的地址,#x表示用16進(jìn)制輸出
LOG_I("%#x\n",i);
//輸出的是i的值0,*表示取指針的內(nèi)容
LOG_I("%#x\n",*i);
//&表示取地址符,將i的地址賦值給指針p
int *p = &i;
數(shù)組指針:
int main() {
//二維數(shù)組
int array[2][3] = {{1, 2, 3},
{4, 5, 6}};
//數(shù)組指針
int (*arr)[3] = array;
//獲取數(shù)組的最后一個(gè)元素,解釋第一步取第二個(gè)數(shù)組內(nèi)容[*(array + 1)]指針指向4,然后+2移動(dòng)到最后取內(nèi)容
int lastEle = *(*(array + 1) + 2);
printf("%d", lastEle);
return 0;
}
指針數(shù)組:
int i = 0;
int *p[] = {&i, &i, &i};
說(shuō)明:指針數(shù)組和數(shù)組指針不要弄混淆,一個(gè)是數(shù)組一個(gè)是指針
* 函數(shù)指針:
/**
*
* 參數(shù)列表代表一個(gè)函數(shù)指針
* void 代表返回值
* (*mp)是一個(gè)參數(shù)變量
* (char *)代表方法參數(shù)
* @param mp
*/
void proxyPrint(void (*mp)(char *)) {
printf("%s", "這是一個(gè)函數(shù)指針的掉用");
}
int main() {
void (*mp)(char *) = printf("來(lái)打印數(shù)據(jù)吧");
proxyPrint(mp);
return 0;
}
動(dòng)態(tài)分配內(nèi)存
1.使用malloc
int main() {
int *data = malloc(sizeof(int) * 5);
//初始化所有數(shù)據(jù)為0,防止臟數(shù)據(jù)出現(xiàn)
memset(data, 0, sizeof(data));
for (int i = 0; i < 5; ++i) {
*data = i;
LOG_I("%d\n",*data);
data++;
}
//釋放指針
free(data);
return 0;
}
2.使用calloc->calloc默認(rèn)將元素初始化了所以不需要再次初始化荡灾,不會(huì)讀取到臟數(shù)據(jù)
int main() {
int *data = calloc(5, sizeof(int));
for (int i = 0; i < 5; ++i) {
*data = i;
LOG_I("%d\n", *data);
data++;
}
//釋放指針
free(data);
retrun 0;
}
常量
const 和 java final類似
//從右往左讀 const修飾哪個(gè)哪個(gè)就不能改變
char *str = "apple";
//情況一
const char *p = str;//這里不能修改char
所以:
p[0]='A';//錯(cuò)誤
p = "banana";//正確
//情況二[情況二和情況一是一樣的瓤狐,因?yàn)閏onst不能作用于*所以往前就作用于char]
char const *p = str;
//情況三
char * const p = str;
p2[0] = 'A'; //正確
p2 = "12345"; //錯(cuò)誤
//情況四 都不能修改
const char * constp= str;
預(yù)處理器
- 預(yù)處理器不是編譯器,但是它是編譯過(guò)程中一個(gè)單獨(dú)的步驟批幌。
- 預(yù)處理器是一個(gè)文本替換工具
- 所有的預(yù)處理器命令都是以井號(hào)(#)開(kāi)頭
常用預(yù)處理器
預(yù)處理器 |
說(shuō)明 |
#include |
導(dǎo)入頭文件 |
#if |
if |
#elif |
else if |
#else |
else |
#endif |
結(jié)束 if |
#define |
宏定義 |
#ifdef |
如果定義了宏 |
#ifndef |
如果未定義宏 |
#undef |
取消宏定義 |
使用:
#define DEBUG
#ifdef DEBUG
#include <strings.h>
#endif
todo 其他使用用的時(shí)候補(bǔ)充查文檔,多看標(biāo)準(zhǔn)庫(kù)函數(shù)