一.
記憶體儲存區的劃分:
1.棧區:棧區主要存放函式內部定義的變數,陣列.函式呼叫時,開闢空間,函式執行完畢,**空間,空間的開闢與**有系統管理.
2.堆區:堆區最大的特點:空間的開闢與釋放有開發人員手動管理.
3.全域性區靜態區:主要存放函式外部定義的全域性變數以及靜態變數,空間一旦開闢,就不會**.直到應用程式執行結束.
4.常量區:儲存常量.1.整形常量.2.浮點型常量.3,字串常量.4.字串常量.
5.**區:存放程式編譯之後生成的cpu指令.
二.malloc,在堆區開闢空間.
//在堆區開闢空間.
//void * 泛型:可以代表所有的指標型別.
//如果要儲存兩個整數,用int * ,儲存8個字元,用char * ,儲存4個人整數,用short *.
//malloc 在堆區開闢n個位元組大小的空間,返回空間的首位址.
char *p = malloc(8);
//儲存iphone
strcpy(p, "iphome");
printf("%s\n",p);//iphome
//釋放空間
//刪除只是標記刪除,不會清楚空間上的內容.
free(p); p = null;
三.堆區空間問題.
1.野指標問題:訪問沒有所有權的空間.
2.過度釋放:一塊空間釋放多次,程式會立即crash.
3.記憶體洩露:空間沒有釋放,造成記憶體堆積.不會造成立即crash,安全隱患.
處理方法 : p = null;
使用指標必備條件: 1.指標要由明確的指向.
2.指向乙個可以控制的區域
四.malloc應用
1.乙個有5個元素的陣列空間.儲存5個整數.
int *p = malloc(sizeof(int)*5);
for (int i = 0; i < 5; i++)
printf("\n");
//排序
for (int i = 0; i < 5 - 1; i++) }}
for (int i = 0; i < 5; i++)
free(p);
p = null;
2.有乙個字串
,其中包含數字
,提取其中的數字
,要求動態分配記憶體儲存
.
printf("請輸入一段字串:\n");
char str = ;
scanf("%s",str);
int i = 0;
int num = 0;
while (str[i] != '\0')
i++;
}char *q = malloc(sizeof(char)*(num+1));//根據長度生成空間 num + 1 字串隱藏\0
int m = 0,n = 0;
for (int i = 0; i < num; i++)
m++;}}
q[n] = '\0';//多出來的儲存\0
printf("\n");
for (int i = 0; i < num; i++)
free(q);
q = null;
3.輸入3個學員的姓名,動態分配記憶體儲存學員姓名,並在最後輸出.
char *names[3] = ; //儲存在堆區開闢的空間的首位址.
char temp[255] = ;//儲存從控制台輸入的字串
for (int i = 0; i < 3; i++)
for (int i = 0; i < 3; i++)
(2)calloc用法
1.void * calloc(unsigned n, unsigned size);
分配n個size大小的空間.並且把該記憶體上的所有位元組清零.
int *p = calloc(5, 4);//分配5塊大小為4位元組的空間,並且做清零操作.
free(p);
p = null;
(3)realloc 用法
void *realloc(void *p,unsigned newsize);
int *p = malloc(10);
printf("%p\n",p);
int *q = realloc(p, 40);//重新分配乙個大小為100 的空間.
//realloc 返回當前空間的首位址.如果當前空間不夠,則在另一塊申請20個位元組的空間,此時返回新的空間的位址.
printf("%p\n",q);
free(q);
q = null;
p = null;//不需要釋放.
(4)memcpy用法
void *memcpy (void *dest, const void *source, size_t n);
//從source指向記憶體開始拷貝到dest中n個位元組.
char *p1 = malloc(8);
char *p2 = malloc(8);
strcpy(p2, "frank");
printf("%s\n", p2);
//memcpy(p1, p2, 6);
memcpy(p1, p2, 4);
memcpy(p1, p2 + 2, 4);//ank
p1[4] = '\0';
printf("%s\n", p1);//fran
(5)memset用法
4. void * memset(void *s, int c, size_t n);
//從s指向的記憶體開始初始化n個位元組的內容為c
char *p1 = malloc(8);
memset(p1,0,8);
五.練習
定義兩個整型指標,分別用malloc、calloc對其分配空間儲存3個元素,malloc分配的空間用memset清零,隨機對陣列進行賦值隨機範圍1-3,賦值後用memcmp比較兩個陣列。如果相同列印good!否則列印failed..
int *p = malloc(sizeof(int) * 3);
int *q = calloc(3, sizeof(int));
memset(p, 0, sizeof(int) * 3);
for (int i = 0;i < 3;i++)
//比較buf1和buf2指向的記憶體是否相同,比較count個位元組
if(memcmp(p , q , sizeof(int) * 3) == 0) else
free(p);
free(q);
p = null;
q = null;
六.巨集
定義巨集: 三部分:1.#define 2.巨集名 3. 替換的內容
巨集的作用: 只做替換.
巨集名的命名規範: 1.全部大寫 2. k+駝峰
無參巨集 #define karraynumber5 #define n 10
有參巨集 #define mul(a,b) ((a) * (b))
巨集應該注意的幾個問題.
1.巨集名大寫
2.引數一定要加小括號.
3.巨集替換的內容不要加分號.
4.對於有參巨集,巨集名一與引數之間不要加空格.
七.列舉
定義列舉
列舉的作用:羅列出所有的可能性
列舉是將人能夠識別的標示符和計算機能夠識別的數字結合在一起.
例子:
//定義列舉
typedef enum button button;
如果想寶貝多個列舉值,按位或即可,前提是列舉值通過左移符號對應值.
bool b = close | max | min; //001 010 100 = 111
printf("%d\n", b);
八.條件編譯
以#開頭的叫做預編譯指令
預編譯指令做一些文字以及**的替換工作.
形式1:
#define a
#ifdef a
int a = 10;//條件編譯(根據條件編譯不同的**)
#else
int a = 20;
#endif
printf("%d ", a);//10
形式2:
#define a
#ifndef a //如果沒有定義
int a = 10;//條件編譯(根據條件編譯不同的**)
#else
int a = 20;
#endif
printf("%d\n",a);//20
形式3:
# if 10 //非0即為真,執行if,否則為假,執行else
int a = 10;
#else
int b = 20;
#endif
printf("%d\n", a); //10
九.
面試題 #include
與 #import
的區別#import 相比 #include 能夠防止重複匯入,引起交叉編譯.
#import " " 匯入自定義的標頭檔案
#impoer <> 匯入系統的標頭檔案
C 自由儲存區記憶體分配
c c 定義了4個記憶體區間 區,全域性變數與靜態變數區,區域性變數區即棧區,動態儲存區,即堆 heap 區或自由儲存區 free store 1 堆的概念 通常定義變數 或物件 編譯器在編譯時都可以根據該變數 或物件 的型別知道所需記憶體空間的大小,從而系統在適當的時候為他們分配確定的儲存空間。這...
學習ios之路 C語言 If迴圈的應用的練習
1.求三個數中的最大值 方法1 先找到兩個數的最大值,然後用最大值和第三個進行比較.int n1 0,n2 0 n3 0 printf 請輸入三個數 n scanf d d d n1,n2,n3 int max 0 定義乙個最大值,初始值為0 if n1 n2 else 用條件表示式替換 為 max...
學習ios之路 C語言 迴圈方面試題
1.列印出如下所示圖形 如下 for int i 0 i 3 i for int k 0 k i 1 k printf n 2.列印出如下圖形 如下 for int i 0 i 5 i for int k 0 k i 1 k printf n else for int k 0 k 5 i k pri...