動態內存分配
動態內存需要手動申請,手動歸還,其內存是開辟在堆區。
申請的函數為:
void *malloc(size_t? size) (需包含頭文件#include<stdlib.h>)
size:要分配的內存大小,以字節為單位。申請的空間是連續的,成功時返回指向內存分配的指針(類型為void * 型,通常需要進行強制類型轉換),失敗時返回空指針(NULL)。需手動管理內存,所分配的內存不會自動釋放,必須調用free()避免內存泄漏。返回的指針會適當對齊,適合任何數據類型。如:分配一個整型數組
#include<stdio.h>
#include<stdlib.h>int main(void)
{int n = 5;int *a = (int *)malloc(n * sizeof(int));if(a == NULL){printf("分配內存失敗\n");return 1;}int i = 0;for(i = 0; i < n; ++i){a[i] = i + 1; }for(i = 0; i < n; ++i){printf("%d\n",a[i])}free(a);a = NULL;return 0;
}
釋放內存后未將指針置為NULL稱為懸空指針,可能導致非法訪問。
動態內存重新分配
形式:void *relloc(void *p,size_t? newsize);
參數p:指向之前分配的內存的指針
參數size:所需要新的內存大小
返回值指向新的內存,與原來的p指向的內存可能不同。
特點:數據保留,拷貝原來的內容到新的空間。
eg:如原來申請內存只能容納長度為10的一維整型數組,現在改為可容納長度為20的一維整形數組。
void printArray(int *a,int len)
{int i;for(i < 0 ;i < len;++i){printf("%2d ",*(a + i));}puts("");
}int main(void)
{int n = 10;int *p = malloc(n * sizeof(int));int i;for( i = 0;i < n;++i){*(p + i) = i + 1;}int m = 20;int *q = realloc(p, m * sizeof(int));p = q;for(i = 10;i < m; ++i){*(p + i) = i + 1;}free(p);p = q = NULL;printArray(p,m);return 0;
}
函數指針
它存儲的是函數的地址,而不是數據變量的地址。通過函數指針,可以動態的調用不同的函數,實現回調。
基本語法:
定義函數
int add(int a,int b)
{return a + b
}int sub(int a,int b)
{return a - b;
}
1、定義函數指針:? 返回值類型(*指針變量名)(參數列表)
如回調上述代碼:int (*pfn)(int , int);
2、初始化指針
pfn = &add;
或
pfn = add;
(函數名本身代表函數的入口地址)
即:
int add(int a,int b)
{return a + b
}int sub(int a,int b)
{return a - b;
}int(*pfn)(int,int) = add;
指針便指向了add函數(改為sub,便指向sub)
3、通過函數指針調用函數
int div3(int n)
{return n % 3 == 0;
}int div5(int n)
{return n % 5 == 0;
}int fn(int n)
{return 1;
}void printArray(int *a,int len,int(*pfn)(int))
{int i;for(i = 0;i < len; ++i){if(pfn(*(a + i))){printf("%2d ",*(a + i));}}puts("");}
主函數調用printArray傳參,最后一個傳入回調函數的函數名。
指針數組
指針數組是指一個數組,其元素都是指針,簡單地說,數組中的每一個元素存儲都是一個內存地址,而不是直接存儲數據。
當它作為函數參數,形參是指向指針的指針。
void printStrings(char **p,int len)
{int i;for(i = 0;i < len;++i){puts(p[i]);}
}void reverseStrings(char **p,int len)
{int i;for(i = 0;i < len / 2;++i){char *t;t = p[i];p[i] = p[len - i - 1];p[len - i - 1] = t;}
}char *maxStrings(char **p,int len)
{char *max = p[0];int i;for(i = 1;i < len; ++i){if(strcmp(max,p[i]) < 0){max = p[i];}}return max;
}void sortStrings(char **p,int len)
{int i,j;for(i = 0; i < len - 1;++i){for(j = i + 1;j < len; ++j){if(strcmp(p[i] , p[j]) > 0){char *t;t = p[i];p[i] = p[j];p[j] = t;}}}
}int main(void)
{char *s[3] = {"Hello","World!","China"};int len = sizeof(s) / sizeof(*s);//reverseStrings(s,len);//printStrings(s,len);//printf("%s\n",maxStrings(s,len));sortStrings(s,len);printStrings(s,len);return 0;
}