?
審核編輯:湯梓紅
在敲代碼的時候,我們會給變量一個初始值,以防止因為編譯器的原因造成變量初始值的不確定性。對于數(shù)值類型的變量往往初始化為0,但對于其他類型的變量,如字符型、指針型等變量等該如何初始化呢?
數(shù)值類變量初始化
整型、浮點型的變量可以在定義的同時進行初始化,一般都初始化為0。
1int????inum??=?0;
2float??fnum?=?0.00f;
3double?dnum?=?0.00;
字符型變量初始化
字符型變量也可在定義的同時進行初始化,一般初始化為''。
1char?ch?=?'';?
字符串初始化
字符串初始化的方法比較多,我這里簡單介紹三種,因為字符串本質上是由一個個字符組成的字符數(shù)組,所以其初始化的最終目的,就是將字符數(shù)組里面的一個個字符都初始化為''。
方法一:使用空的字符串""。
char str[10] = "";
方法二:使用memset。
char str[10]; memset(str, 0, sizeof(str));
方法三:寫一個循環(huán)。
char str[10]; for(int i = 0; i < 10; i++) { str[i] = ''; } 這里比較推薦的是第二種初始化方法。也即使用
memset進行初始化。很多人對memset這個函數(shù)一知半解,只知道它可以初始化很多數(shù)據類型的變量,卻不知道其原理是什么樣的,這里做一下簡要的說明:memset是按照字節(jié)進行填充的。 先看下面的一段代碼:
int num; memset(&num, 0, sizeof(int)); printf("step1=%d ", num); memset(&num, 1, sizeof(int)); printf("step2=%d ", num);
在討論之前,我們先看一下運行結果
chenyc@DESKTOP-IU8FEL6:~/src$ gcc -o memset memset.c -g chenyc@DESKTOP-IU8FEL6:~/src$ ./memset step1 = 0 step2 = 16843009 chenyc@DESKTOP-IU8FEL6:~/src$
看到這個運行結果,是不是和你想象中的不一樣呢?step1 = 0?相信大家都好理解,可?step2 = 16843009?很多人就不能理解了。按照一般的慣性思維,不是應該?= 1?才對么? 這就是我要說的,memset是按照字節(jié)進行填充的。 我們知道,int?型是4個字節(jié)(每個字節(jié)有8位),按二進制表示出來就應該是:
00000000 00000000 00000000 00000000
按照按字節(jié)填充的原則,step1 的結果就是將4個字節(jié)全部填充0,所以得到的結果仍然是0:
00000000 00000000 00000000 00000000
而 step2 則是將每個字節(jié)都填充為1?(注意是每個字節(jié),而不是每個byte位)?,所以相對應的結果就應該是:
00000001 00000001 00000001 00000001
大家可以自己將上面那個二進制數(shù)轉換成十進制看看,看看是不是16843009。 所以嚴格來說,memset函數(shù)本身并不具有初始化的功能,而是一個單純的按字節(jié)填充函數(shù),只是人們在使用的過程中,擴展出了初始化的作用。
字符串初始化有一個小竅門,我們知道字符串本質上是字符數(shù)組,因此它具有兩個特性,- 字符串在內存里是連續(xù)的,
-
字符串遇
''結束。 所以我們在初始化的時候,總是愿意給字符串本身長度加1的長度的內存進行初始化。
char year[4+1]; memset(year, 0, sizeof(year)); strcpy(year,"2018");
指針初始化
一般來說,指針都是初始化為NULL。int *pnum = NULL; int num = 0; pnum = # 指針是個讓人又愛又恨的東西,一般的整形、字符串等,初始化之后就可以直接拿來用了,可指針如果初始化為
NULL后,沒有給該指針重新分配內存,則會出現(xiàn)難以預料的錯誤(最最常見的就是操作空指針引起的段錯誤)。在動態(tài)內存管理中,由于變量的內存是分配在堆中的,所以一般用malloc、calloc等函數(shù)申請過動態(tài)內存,在使用完后需要及時釋放,一般釋放掉動態(tài)內存后要及時將指針置空,這也是很多人容易忽略的。char *p = NULL; p=(char *)malloc(100); if(NULL == p) { printf("Memory Allocated at: %x ",p); } else { printf("Not Enough Memory! "); } free(p); p = NULL; //這一行給指針置空必不可少,否則很可能后面操作了這個野指針而不自知,從而導致出現(xiàn)嚴重的問題 很多人經常會犯的一個錯誤,我們知道,在指針作為實參進行參數(shù)傳遞時,該指針就已經退化成了數(shù)組,所以很多人就想到用
memset來對該指針進行初始化:void fun(char *pstr) { memset(pstr, 0, sizeof(pstr)); ... } 這種寫法是不正確的。我們姑且不管指針能不能用
memset來進行初始化,指針首先保存的是一個4字節(jié)的地址,所以sizeof(pstr)永遠只能?= 4,這樣的初始化就毫無意義。結構體初始化
結構體的初始化就比較簡單了,基本也都是采用memset的方式。typedef struct student { int id; char name[20]; char sex; }STU; STU stu1; memset((char *)&stu1, 0, sizeof(stu1)); 關于初始化結構體的長度問題,也即
memset的第三個參數(shù),一般來說,傳入數(shù)據類型和變量名效果是一樣的,上例中,下面寫法是等價的效果:memset((char *)&stu1, 0, sizeof(STU)); 但是對于結構體數(shù)組的初始化,長度就需要注意一下了,還是以上例來做說明:
STU stus[10]; memset((char *)&stus, 0, sizeof(stus)); //正確,數(shù)組本身在內存里就是連續(xù)的,sizeof取出的就是數(shù)組的字節(jié)長度 memset((char *)&stus, 0, sizeof(STU)); //錯誤,只會初始化第一個STU結構體,后面還有9個STU元素并未初始化 memset((char *)&stus, 0, sizeof(STU)*10); //正確,效果與第一個是一樣的 有些人習慣將
memset的第二個參數(shù)寫成以下形式:memset((char *)&stu1, 0x00, sizeof(stu1)); 只要理解了
memset是按字節(jié)進行填充的,就知道這樣寫也是正確的,完全沒有問題。審核編輯:湯梓紅
?
電子發(fā)燒友App



























評論