整型、浮點型的變數可以在定義的同時進行初始化,一般都初始化為0
。
int inum =0;
float fnum =
0.00f
;double dnum =
0.00
;
字元型變數也可在定義的同時進行初始化,一般初始化為'\0'
。
char ch =
'\0'
;
字串初始化的方法比較多,我這裡簡單介紹三種,因為字串本質上是由乙個個字元組成的字元陣列,所以其初始化的最終目的,就是將字元陣列裡面的乙個個字元都初始化為'\0'
。
方法一:使用空的字串""
。
char str[10]
="";
方法二:使用memset
。
char str[10]
;memset
(str,0,
sizeof
(str)
);
方法三:寫乙個迴圈。
char str[10]
;for
(int i =
0; i <
10; i++
)
這裡比較推薦的是第二種初始化方法。也即使用memset
進行初始化。
很多人對memset
這個函式一知半解,只知道它可以初始化很多資料型別的變數,卻不知道其原理是什麼樣的,這裡做一下簡要的說明:memset
是按照位元組進行填充的。先看下面的一段**:
int num;
memset
(&num,0,
sizeof
(int))
;printf
("step1=%d\n"
, num)
;memset
(&num,1,
sizeof
(int))
;printf
("step2=%d\n"
, 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是按照位元組進行填充的。
我們知道,
int
型是4個位元組(每個位元組有8位),按二進位制表示出來就應該是:
00000000 00000000 00000000 00000000
按照按位元組填充的原則,step1 的結果就是將4個位元組全部填充0,所以得到的結果仍然是0:
00000000 00000000 00000000 00000000
而 step2 則是將每個位元組都填充為1 (注意是每個位元組,而不是每個byte位) ,所以相對應的結果就應該是:
00000001 00000001 00000001 00000001
大家可以自己將上面那個二進位制數轉換成十進位制看看,看看是不是字串初始化有乙個小竅門,我們知道字串本質上是字元陣列,因此它具有兩個特性,16843009
。所以嚴格來說,memset函式本身並不具有初始化的功能,而是乙個單純的按位元組填充函式,只是人們在使用的過程中,擴充套件出了初始化的作用。
char year[4+
1];memset
(year,0,
sizeof
(year));
strcpy
(year,
"2018"
);
一般來說,指標都是初始化為null
。
int
*pnum =
null
;int num =0;
pnum =
#
指標是個讓人又愛又恨的東西,一般的整形、字串等,初始化之後就可以直接拿來用了,可指標如果初始化為null
後,沒有給該指標重新分配記憶體,則會出現難以預料的錯誤(最最常見的就是操作空指標引起的段錯誤)。
在動態記憶體管理中,由於變數的記憶體是分配在堆中的,所以一般用malloc
、calloc
等函式申請過動態記憶體,在使用完後需要及時釋放,一般釋放掉動態記憶體後要及時將指標置空,這也是很多人容易忽略的。
char
*p =
null
; p=
(char*)
malloc
(100);
if(null
== p)
else
free
(p);
p =null
;//這一行給指標置空必不可少,否則很可能後面操作了這個野指標而不自知,從而導致出現嚴重的問題
很多人經常會犯的乙個錯誤,我們知道,在指標作為實參進行引數傳遞時,該指標就已經退化成了陣列,所以很多人就想到用memset
來對該指標進行初始化:
void
fun(
char
*pstr)
這種寫法是不正確的。我們姑且不管指標能不能用memset
來進行初始化,指標首先儲存的是乙個4位元組的位址,所以sizeof(pstr)
永遠只能= 4
,這樣的初始化就毫無意義。
結構體的初始化就比較簡單了,基本也都是採用memset
的方式。
typedef
struct student
stu;
stu stu1;
memset((
char*)
&stu1,0,
sizeof
(stu1)
);
關於初始化結構體的長度問題,也即memset
的第三個引數,一般來說,傳入資料型別和變數名效果是一樣的,上例中,下面寫法是等價的效果:
memset((
char*)
&stu1,0,
sizeof
(stu)
);
但是對於結構體陣列的初始化,長度就需要注意一下了,還是以上例來做說明:
stu stus[10]
;memset((
char*)
&stus,0,
sizeof
(stus));
//正確,陣列本身在記憶體裡就是連續的,sizeof取出的就是陣列的位元組長度
memset((
char*)
&stus,0,
sizeof
(stu));
//錯誤,只會初始化第乙個stu結構體,後面還有9個stu元素並未初始化
memset((
char*)
&stus,0,
sizeof
(stu)*10
);//正確,效果與第乙個是一樣的
有些人習慣將memset
的第二個引數寫成以下形式:
memset((
char*)
&stu1,
0x00
,sizeof
(stu1)
);
只要理解了memset
是按位元組進行填充的,就知道這樣寫也是正確的,完全沒有問題。 C 的各種初始化
c 的初始化有很多方式 預設初始化,值初始化,直接初始化,拷貝初始化,列表初始化。這些方式之間有什麼區別與聯絡呢?我們一一來看。1.預設初始化 預設初始化是指定義變數時沒有指定初值時進行的初始化操作。例如int a sales data mydata 等等。這些變數被定義了而不是僅僅被宣告 因為沒有...
c語言變數賦值,初始化
陣列變數為全域性變數,或被部分初始化,均會出現這種情況。c語言中,變數在沒有顯式初始化時,區分變數型別,有如下幾種情況 1 全域性變數,和靜態區域性變數,未初始化時值預設為0.無論是陣列還是變數,都是如此。2 區域性變數,初始值為隨機值。3 陣列類區域性變數,當被部分初始化時,未被初始化部分,值預設...
c語言static變數初始化
程式設計師面試筆試寶典 第123頁,舉了個例子 include void fun int i intmain 書中寫道 程式輸出結果為 0 00作者原意是想表明static int value i 是變數value由於static的修飾,只會定義一次value變數,並且沒有其他對value變數賦值的...