棧區間:在函數內部聲明的變量都存放在棧區間,比如int char 數組 結構體 指針,只管申請,系統會自動幫我們回收,收回的時間是作用域結束之後,遵循的原則是"先進後出"。
int a = 10;
const int m =10;
printf("%p\n", &m);
printf("%p\n", &a);
堆區間:在五大區間中占用比例較大的區間,需要手動申請和手動釋放,遵循的原則 "先進先出",堆區間空間的開辟是無序的,並且沒有名字,所以我們需要一個棧區的指針來指向堆內存的數值。
int *b = malloc(sizeof(int ) *2);
printf("%p\n",b);
free(b);
靜態區:定義在函數體外面的變量。存放全局變量或者靜態變量,生命周期很長,一般到程序結束才釋放,使用static修飾的變量,只初始化一次,默認值為0
static int c= 23;
printf("%p\n", &c);
void test3( ){
static int a =10; 第一次調用函數就賦初值,後面在調用函數這個語句就不會在允許。
a++;
printf("%d\n",a); //輸出10,11,12
}
test3( );
test3( );
test3( );
常量區:我們平時遇到的常量都放到這裡比如"myname",'c',87,87.4
printf("%p\n",&"hello world ");
常量區變量不能被修改:
char *str ="iphone"; //字符指針指向常量區中字符串。
char str1[] ="iphone"; // 將常量區字符串拷貝到棧區的指針名稱為str1的空間中。
str1[0] = 'I'; // 可以修改,編寫代碼的時候不會報錯,但是在編譯的時候就會報錯。
str[0] = 'I'; //會報錯。
所以我們一般這樣寫:const char *str ="...." 這樣寫的好處就是在很大的項目中,我們在修改常量區變量的值的時候會報錯,可以立即處理,而不是在編譯運行之後報錯,才從幾萬行代碼中查找錯誤的源頭。
代碼區:一將源碼編譯成二進制文件,一般是函數。
void func( );
void func( ){
printf(...)'
}
printf("%p\n" , func ); //傳入函數名稱。
分配內存空間函數:
malloc 最後釋放的時候不是真正的"清空",而是標記該空間已經使用完成,裡面存放的值可能還存在。
char *str = malloc( sizeof(char) *30 );
printf("%p\n",str);
free(str);
free(str); //不能重復的釋放,會崩潰,因為已經沒有對應指針名稱的空間給你釋放,為了安全起見,我們常常在free後面添加。
str = NULL;
calloc 開辟內存空間同時將裡面的值清零。如果數據很大的話,效率很低。
char *str1 = calloc( sizeof(char) , 30);
printf("%p\n",str1);
free(str1);
str1 =NULL;
realloc 根據給定的內存地址,重新開辟空間,一般都是開辟更大的空間。
int *num1 = malloc(sizeof(int ) * 10 );
realloc(num1,40); //將10個字節的空間擴大到40個字節。
free(num1);
num1 = NULL;
memset 為剛開辟的空間賦初始值。
char *str3 = malloc(sizeof(char) * 20);
memset(str3,'m',20);
free(str3);
str3 = NULL;
memcpy 拷貝
char *str4 = malloc(sizeof(char) *20);
memcpy(str4,"luoshuailuo",6); // 將luoshuailuo這個字符串拷貝到str4中,只拷貝6個字符。
free(str4);
str4 = NULL;
memcmp 比較q
char *name = malloc(sizeof(char) *100);
char *name1 = malloc(sizeof(char) *100 );
strcpy(name, "LUOSHUAI");
strcpy("name1", "luoshuai");
memcmp(name, name1, 100);
free(name);
free(name1);
name = NULL;
name1 = NULL;
有一個字符串,裡面包含字符和數字,要求提取數字,並動態分配內存保存。
int *str ="iphone6and8Plus23cc84";
int count = 0;
for(int i = 0; i< strlen(str);i++ ){
if(*(str+i) >= '0' && *(str+i) <= '9'){
count++;
}
}
int *num =malloc(sizeof(int) * count );
int count = 0;
for(int i = 0; i< strlen(str);i++ ){
if(*(str+i) >= '0' && *(str+i) <= '9'){
*(num+count) = *(str+i) - 48; //字符轉化為數字 需要減少48
count++;
}
}
for(int i = 0 ; i < count; i++){
printf("%d\n", *(num+i ));
}
free(num);
num = NULL;
自我學習積累篇:
strncpy(destion,source, num ); 該函數的作用是將"source"的第num個長度字符串拷貝到"destion",
如果num < source的長度,則會講source的前面的num個字符串拷貝到source,不會添加\0
如果num = source的長度,則會將source所有字符拷貝到source,不會添加\0
如果num > source的長度,則會將source所有字符拷貝到source,後面會持續添加\0, 少多個個就添加多少個.