C語言回顧-內存管理和指針函數

1.fgets()函數數組

該函數是一個文件操做相關的函數安全

暫時使用這個函數能夠從鍵盤上接收一個字符串,保存到數組中函數

char str[50];spa

1)scanf("%s",str);//缺點:不能接收空格,也是不安全的指針

2)gets(str);//優勢:能夠接收空格code

        //缺點:會有一個警告,不安全的,好比數組的長度是50,咱們輸入的字符大於等於50的時候,會把50個字符所有放到數組中對象

        //沒有空間存放字符串結束符blog

3)fgets是一個安全的字符串接收函數,好比數組的長度是50,咱們輸入的字符大於等於50的時候,會把前49個字符所有放到數組中,最後一個位置存放\0內存

使用格式:char *fgets(char *s,int n,FILE *fp);字符串

fgets(數組名,數組長度,stdin);

當輸入的字符串的長度小於數組長度的時候,fgets還會接收回車,回車後纔是\0

2.fputs()函數

格式:fputs(數組名,stdout);

不會自動換行,也不能進行格式化輸出

puts有換行

//
// main.c // Fgets //
// Created by fanyafang on 15/11/5. // Copyright © 2015年 itcast. All rights reserved. //  #include <stdio.h> #include <string.h>

int main(int argc, const char * argv[]) { char str[5]; fgets(str,sizeof(str),stdin); //把字符串後面的\n改成\0 //if(str[strlen(str)-1]=='\n') str[strlen(str)-1]='\0';
    printf("---->%s\n",str); puts(str);//有換行
    fputs(str,stdout);//無換行
    return 0; }

3.const類型修飾符

常類型是指使用類型修飾符const說明的類型,常類型的變量或者對象的值是不能被更新的

1)修飾變量可讓變量的值不能改變

2)修飾指針變量,const在*的左側,那麼變量值不能改變;若是在* 的右側,表示指向不能改變;若是在* 的兩側,表示兩個都不能變

//
// main.c // const使用 //
// Created by fanyafang on 15/11/5. // Copyright © 2015年 itcast. All rights reserved. //  #include <stdio.h>

int main(int argc, const char * argv[]) { //1)修飾變量
    const int a=10; printf("%d\n",a); //a=34;報錯,不能修改 //2)用指針強制修改變量
    int *p=&a; *p=100; printf("%d\n",a);//值不同
    printf("%d\n",*p); printf("%p\n",&a);//地址同樣
    printf("%p\n",p); //3)修飾指針變量,指向能夠改變,指向的值不能夠改變
    int b=100; const int *p1=&a; p1=&b; int const *p6=&a; p1=&b; //4)const修飾的指針變量,指針變量指向的變量值能夠變,指向不能變
    int * const p3=&a; *p3=1000;//指向的值能夠變 //ps=&b;報錯,指向不能變 //5)const修飾的指針變量,變量值和指向都不能變
    const int * const p4=&a; //*p4=12000; //p4=&b;
    
    return 0; }

3.內存管理

1)內存分配方式

1))靜態分配,在程序編譯的適合就已經分配好,這塊內存在程序的整個運行期都存在,例如全局變量,static變量

2))在棧上建立,在執行函數時,函數內局部變量的存儲單元,效率很高,容量有限

3))從堆上分配,議程動態內存分配,程序在運行的時候用malloc或new申請任意多少的內存,手動用free或delete釋放內存,靈活

2)內存分區

棧:運行時分配,局部變量

堆:運行時分配

BSS段:編譯時分配,未初始化的全局變量和靜態變量

數據區:編譯時分配,已經初始化的全局變量和靜態變量

代碼段:編譯時分配

3)動態分配內存函數:

1))viod * malloc(unsigned size);

#include <stdlib.h>

從內存的堆區分配大小爲size個字節的聯繫的內存空間,若是內存分配成功,返回內存的首地址,失敗,返回NULL。因此須要判斷是否分配成功

2))calloc分配

calloc(塊數,長度);

3))realloc函數能夠給已經存在的空間擴充大小,返回新的地址

//
// main.c // 分配內存 //
// Created by fanyafang on 15/11/5. // Copyright © 2015年 itcast. All rights reserved. //  #include <stdio.h> #include <stdlib.h>

int main(int argc, const char * argv[]) { //分配空間 //int *p=(int *)malloc(4*sizeof(int)); //使用一個函數給malloc申請的空間進行初始化 //memset(p,'a',16);
    
    int *p=(int *)calloc(4, 4);//能夠自動初始化
 p=realloc(p, 40*sizeof(int)); if(p==NULL){ printf("申請失敗!"); }else{ printf("申請成功!"); printf("%d\n",*p); *p=10; *(p+1)=100; *(p+2)=30; *(p+3)=120; *(p+39)=10000; printf("%d\n",*(p+39)); } return 0; }

4.野指針和內存泄露

int *p=(int *)calloc(4, 4);//p存儲在棧區,p指向的內容在堆區

在p被釋放以前先要釋放堆區中的內容,不然會形成內存泄露,釋放以後要賦值爲NULL,否則仍是能夠訪問

//應該使用free函數釋放內存空間
    free(p);//釋放後p是一個野指針 //p=NULL;
    *p=1000;

5.指針函數:返回值是指針類型的函數

//
// main.c // 指針函數 //
// Created by fanyafang on 15/11/5. // Copyright © 2015年 itcast. All rights reserved. //  #include <stdio.h>

char * printDay(int n){ char * days[]={ "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" }; return n>0&&n<8?days[n-1]:"輸入錯誤"; } int main(int argc, const char * argv[]) { int n=0; printf("請輸入一個數字:\n"); scanf("%d",&n); printf("%s\n",printDay(n)); return 0; }

 6.函數指針

在C語言中,一個函數老是佔用一段連續的內存空間,而函數名就是該函數所佔內存空間區的首地址

定義函數指針:int (*p)(int a , int b );或者:int (*p)(int  , int  );

函數指針的使用:

調用函數,同函數名的使用,能夠任意調用函數

相關文章
相關標籤/搜索