1.include <> ""區(qū)別
#include <> 是系統(tǒng)的庫
#include “” 是自己的庫
2.懸空指針和野指針
(1)懸空指針:
在內(nèi)存中創(chuàng)建堆空間malloc
釋放堆空間free
此時改指針為懸空指針,因為指向了一個空地址。
所以需要將指針指向為NULL
(2)野指針:
定義一個變量,但是沒給他賦值,這個指針也就沒有地址,不知道指向于誰,所以就成了野指針。
3.靜態(tài)開辟和動態(tài)開辟內(nèi)存區(qū)別
靜態(tài)開辟的內(nèi)存大小是不能修改的,棧區(qū)
動態(tài)開辟空間是可以修改的,堆區(qū)
4.棧和堆區(qū)別
棧區(qū)的內(nèi)存空間比較小,堆區(qū)的內(nèi)存空間比較大,具體大小每個平臺都不一樣
棧區(qū)的內(nèi)存自動回收,堆區(qū)需要手動創(chuàng)建和回收
5.malloc,realloc使用和區(qū)別
//在部分編譯器上需要手動轉型(int *),在clion上不需要
//在堆區(qū)開辟空間
int * arr = (int *)malloc(sizeof(int) * num);
//在堆區(qū)擴大空間 第一個參數(shù):前面開辟的指針 ,第二個參數(shù):總大小
int * new_arr = (int *)realloc(arr,sizeof(int) * (num + new_num));
// arr 和 new_arr 的內(nèi)存地址是一樣的(如果新增的空間不夠了?)
//記得釋放,不要重復free釋放,記得判斷,重復釋放VS會崩潰,CLion不會崩潰
if (new_arr) {
free(new_arr);
new_arr = NULL;
arr = NULL;
} else {
//重新開辟失敗的情況
free(arr);
arr = NULL;
}
6.字符串
char str[] = {'a' , 'b' , 'c' , 'd'};
//此時用pirntf打印會出現(xiàn)亂碼 abcdxxx,xxx為系統(tǒng)值,因為printf遇到\0才會結束,例如
char str2[] = {'a' , 'b' , 'c' , 'd' ,'\0'};
char* str3 = "abcd";//這樣寫會隱士的加上\0
//可以修改,abcd是存在靜態(tài)區(qū)域,然后會復制到??臻g,str2是指向??臻g,在??臻g進行操作不會報錯
str2[2] = 'tt';
//不能修改,會報錯,因為str3指向的是靜態(tài)區(qū)域,系統(tǒng)會拒絕訪問
str3[2] = 'tt';
獲取長度
int getLen(char *arr) {
int num = 0;
while (*arr) { // *arr != '\0'
arr ++;
num ++;
}
return num;
}
獲取長度的錯誤寫法
//C/C++編譯器,數(shù)組作為參數(shù)傳遞,會把數(shù)組優(yōu)化為指針(為了效率)
int getLen2(char arr[]) {
printf("arr = %d\n", sizeof(arr));
printf("char = %d\n", sizeof(char));
return sizeof(arr) / sizeof(int);
}
還有很多寫法是傳地址進來
void getLen(int *count, char *arr) {
int num = 0;
while (*arr) { // *arr != '\0'
arr ++;
num ++;
}
*count = num;
}
7.結構體
struct Person {
char *name;
int age;
char sex
} p1 = {"chenqi", 18, 'G'},
p2,
p3;
//也可以這么寫,cq就是別名
typedef struct {
char *name;
int age;
char sex
} cq;
int main() {
printf("p1 %s %d %c\n",p1.name,p1.age,p1.sex);
return 0;
}