******
1.指針變量是 專門存放地址 的變量,所以對它進行賦值時只能賦值 地址;
2.指針的初始化: int* ptr = null; 和 int *ptr = null; 是一樣的,但是隻有ptr 是代表指針變量, *ptr 代表的是指針引用;
3.*ptr 代表是 “ 對指針變量ptr 進行* 運算”
4. int* ptr =&a 合法(對指針變量 ptr 賦值 &a); int* ptr = null ; *ptr =a ; 合法(指針變量ptr 進行* 運算後值爲a)
1.數據類型
類型 | 位 | 範圍 |
---|---|---|
char | 1 個字節 | -128 到 127 或者 0 到 255 |
unsigned char | 1 個字節 | 0 到 255 |
signed char | 1 個字節 | -128 到 127 |
int | 4 個字節 | -2147483648 到 2147483647 |
unsigned int | 4 個字節 | 0 到 4294967295 |
signed int | 4 個字節 | -2147483648 到 2147483647 |
short int | 2 個字節 | -32768 到 32767 |
unsigned short int | 2 個字節 | 0 到 65,535 |
signed short int | 2 個字節 | -32768 到 32767 |
long int | 8 個字節 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
signed long int | 8 個字節 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long int | 8 個字節 | 0 to 18,446,744,073,709,551,615 |
float | 4 個字節 | +/- 3.4e +/- 38 (~7 個數字) |
double | 8 個字節 | +/- 1.7e +/- 308 (~15 個數字) |
long double | 16 個字節 | +/- 1.7e +/- 308 (~15 個數字) |
wchar_t | 2 或 4 個字節 | 1 個寬字符 |
1.typedef 聲明
可以使用 typedef 爲一個已有的類型取一個新的名字:
typedef int feet; ----> feet 是 int 的另一個名稱:
2.枚舉類型
如果一個變量只有幾種可能的值,可以定義爲枚舉(enumeration)類型:
所謂"枚舉"是指將變量的值一一列舉出來,變量的值只能在列舉出來的值的範圍內。
const 關鍵字
1.變量
變量(variable) :當你申明一個變量的時候,計算機會將指定的一塊內存空間和變量名進行綁定;
例: int x = 5 : 將5賦值於名字叫做“x”的內存空間 ---> 叫做“x”的內存空間裏,存儲着的數據是“5”
變量在內存中的操作其實是需要經過2個步驟的:
1)找出與變量名相對應的內存地址。
2)根據找到的地址,取出該地址對應的內存空間裏面的值進行操作。
2,指針的結構和原理
1.指針變量和任何變量一樣,也有變量名,和這個變量名對應的內存空間;
2.指針的特殊之處在於:指針變量相對應的內存空間存儲的值恰好是某個內存地址;
int x = 5;
int *ptr = &x;
3:引用在內存中的結構和原理
reference是一種特殊的pointer
二.對char* 和 char[]區別的一些理解
1.相同點:
1. 這兩種類型都可以對應一個字符串,比如:
char * a=”string1”;
char b[]=”string2”;
其中a是一個指向char變量的指針,b則是一個char數組(字符數組);
2.很多時候二者可以混用,像函數傳參數的時候,實參可以是char*,形參可以是 char[]
void fun1(char b[]){
printf(“%s”,b);
}
int main(){
char *a=“HellowWorld”;
fun1(a);
}
3. char b[]="string" 中,變量b 是“一個char 型數組的名字(被引用時)” ,同時也是“該數組首元素的地址(被賦值時)”
可以直接這樣賦值(char[])b =(char*)a
注: char *a = null;
a=&b;// a 可以賦值爲 &b , 並不代表 a 的類型和&b 相同。可以賦值,不代表2變量類型相同
2.不同點
1.(char*)a 是變量,值可以改變, (char[])b 是常量,值不能改變:
char * a=”string1”;
char b[]=”string2”;
a=b; //OK
a=”string3”; //OK --> ( 與 char* a = "string" 定義相同)
b=a; //報錯!左邊操作數只讀
b=”string3” //報錯!左邊操作數只讀
a是一個char型指針變量,其值(指向)可以改變;b是一個char型數組的名字,也是該數組首元素的地址,是常量,其值不可以改變 。
2.char[]對應的內存區域總是可寫,char*指向的區域有時可寫,有時只讀
char * a=”string1”;
char b[]=”string2”;
gets(a); //試圖將讀入的字符串保存到a指向的區域,運行崩潰!
gets(b) //OK
a指向的是一個字符串常量,即指向的內存區域只讀; b始終指向他所代表的數組在內存中的位置,始終可寫!
char * a=”string1”;
char b[]=”string2”;
a=b; //a,b指向同一個區域,注意這裏改變了a的指向
gets(a) //OK
3.char * 和char[]的初始化操作有着根本區別:
char b[]=”string2”;則是實現了2個操作:
1聲明一個char 的數組,
2爲該數組“賦值”,即將”string2”的每一個字符分別賦值給數組的每一個元素,存儲在棧上。
最終的結果:“數組的值”(注意不是b的值)等於”string2”,而不是b指向一個字符串常量
PS:
實際上, char * a=”string1”; 的寫法是不規範的!
因爲a指向了即字符常量,一旦strcpy(a,”string2”)就糟糕了,試圖向只讀的內存區域寫入,程序會崩潰的!儘管VS下的編譯器不會警告,但如果你使用了語法嚴謹的Linux下的C編譯器GCC,或者在windows下使用MinGW編譯器就會得到警告。
所以,我們還是應當按照”類型相同賦值”的原則來寫代碼: const char * a=”string1”;
保證意外賦值語句不會通過編譯。
小結
對於
const char * a=”string1”
char b[]=”string2”;
1.a是const char 類型, b是char const類型
( 或者理解爲 (const char)xx 和 char (const xx) )
2.a是一個指針變量,a的值(指向)是可以改變的,但a只能指向(字符串)常量,指向的區域的內容不可改變;
3.b是一個指針常量,b的值(指向)不能變;但b指向的目標(數組b在內存中的區域)的內容是可變的
4.作爲函數的聲明的參數的時候,char []是被當做char *來處理的!兩種形參聲明寫法完全等效!