數組:數組是用於存儲同壹類型的多個數據的集合。
指針:指針相當於變量,但它與不同的變量是不同的。它在內存中存儲其他變量的地址。
第二,賦值、存儲模式、sizeof、初始化等
1.分配
相同類型的指針變量可以相互賦值,但數組不能。它們只能壹個壹個地分配或復制。
2.存儲模式
數組:數組連續存儲在內存中,從而創建壹個連續的內存空間。數組是根據數組的上下文訪問的,多維數組是根據壹維數組存儲在內存中的,但在邏輯上它們是多維的。
數組的存儲空間要麽在靜態區域,要麽在堆棧上。
指針:指針是靈活的,它可以指向任何類型的數據。指針的類型表示它所指向的地址空間中的內存。
指針:因為指針本身是壹個變量,它存儲的也是壹個變量,所以指針的存儲空間無法確定。
尋找sizeof
數組:
數組占用的內存:sizeof(數組名)
Sizeof數組:sizeof(數組名)/sizeof(數據類型)
指針:
在32位平臺上,指針的大小為4;在64位平臺上,指針的大小為8。
我在以前的博客中寫過如何用指針和數組查找sizeof,現在我將發布連接:
/cherry dream sover/文章/詳細信息/81589838
初始化
數組:
(1)char a【】= {“Hello“};//由字符串初始化,大小為6。(2)char b【】= {‘H‘,‘e‘,‘l‘,‘l‘};//按字符初始化(錯誤,沒有終止符輸出將亂碼)(3)char c【】= {‘h‘,‘e‘,‘l‘,‘l‘,‘o‘,‘\ 0‘};//通過字符初始化1234。
這裏我們補充壹個誤解,這是關於數組的創建和銷毀,尤其是多維數組的創建和銷毀。
(1)壹維數組:
int * arr = new int【n】;//創建壹維數組
刪除【】arr//銷毀
②二維數組:
int * * arr = new int *【row】;//這相當於創建壹個包含多少行的數組。
for(int I = 0;我& lt排;i++)
{
arr【I】= new int【col】;//這裏是創作。
}
//釋放
for(int I = 0;我& lt排;i++)
{
delete【】arr【I】;
}
刪除【】arr
指針:
//(1)指向對象的指針:()中的值是初始化值)int * p = new int(0);刪除p;//(2)指向數組的指針:(n表示數組的大小,該值不需要在編譯時確定,但可以在運行時確定)int * p = new int【n】;刪除【】p;//(3)指向類的指針:(如果構造函數有參數,則new Class後有參數;否則調用默認構造函數,delete調用析構函數)Class * p = new Class?刪除p;//(4)指針的指針:(二級指針)int * * PP = new(int *)【1】;
PP【0】= new int【6】;刪除【】PP【0】;12345678910
這裏我們區分兩個重要的概念:指針數組和數組指針。
(1)指針數組:它實際上是壹個數組,數組的每個元素存儲壹個指針類型的元素。
int * arr【8】;//優先級問題:【】的優先級高於*//它表示arr是壹個數組,int*是數組的內容//這句話表示arr是壹個包含8和int* 1234的數組。
請點擊輸入圖片說明。
(2)數組指針:它實際上是壹個指向數組的指針。
int(* arr)【8】;//因為【】的優先級高於*,所以在寫數組指針時必須用括號將*arr括起來。//arr與* first組合在壹起,這意味著P是壹個指針變量。//這句話的意思是指針arr指向壹個大小為8個整數的數組。1234
請點擊輸入圖片說明。
第三,傳遞參考
數組:
當數組傳遞參數時,它將退化為指針,所以我們首先來看看什麽是退化!
(1)退化的意義:C語言只以值復制的形式傳遞參數。在傳遞參數時,如果只復制整個數組,效率會大大降低,並且當參數在堆棧上時,過大的數組復制會導致堆棧溢出。
(2)因此,C語言簡化了數組的傳遞參數。當整個數組被復制到函數中時,數組名稱被視為const指針,並且傳遞數組的第壹個元素的地址。
1.傳遞壹維數組的參數
# include & ltstdio.h & gt//正確傳遞參數//以數組的形式傳遞參數,並且不需要指定參數的大小,因為在壹維數組中傳遞參數時,形參實際上不會創建數組,而只是傳遞數組第壹個元素的地址。(如果傳遞了變量值,則形參是實參的副本)void test(int arr【】)
{ }//傳遞參數的方式是正確的//不能傳遞任何參數,當然參數也可以作為void test(int arr【10】)傳遞。
{ }//傳遞參數的方式是正確的。//壹維數組傳遞了退化的參數,它是通過指針接收的,該指針通過了數組第壹個元素的地址void測試(int *arr)。
{ }//參數傳遞正確/* ARR【20】為指針數組,傳遞數組名void test2(int * ARR【20】)。
{ }//參數傳遞正確//它是指針數組的數組名,表示第壹個元素的地址。第壹個元素是指向數組的指針,然後獲取地址,這意味著二級指針,二級指針接收void test 2(int * * arr)。
{}int main()
{ int arr【10】= { 0 };int * arr 2【20】= { 0 };
測試(arr);
test 2(arr 2);
}
2.傳遞二維數組的參數
//正確傳遞參數//指示二維數組的大小,帶有三行五列void test(int arr【3】【5】)。
{ }//傳遞的參數不正確//二維數組的兩個方括號不能全部為空,第二個也不能為空,只有第壹個可以為空void test(int arr【】【】)。
{ }//參數被正確傳遞//可以這樣寫,但不能寫成Intarr【3】【】void test(Intarr【】【5】)。
{ }//不正確的參數傳遞//arr是壹級指針,可以傳遞給二維數組,但無法正確讀取void test(int * arr)。
{ }//不正確的參數傳遞//這裏的參數是壹個指針數組,是壹維的,可以傳遞,但是讀取的數據是不正確的void test(int * arr【5】)。
{ }//正確傳遞參數//傳遞二維數組的數組名,即數組第壹個元素的地址,即第壹行的地址,也是壹個數組,用數組指針接收void test(int(* arr)【5】)。
{ }//不正確的參數傳遞//可以傳遞參數,但讀取void test(int * * arr)時會出現不同程度的問題。
{}int main()
{ int arr【3】【5】= { 0 };
測試(arr);
}
指針:
1.壹級指針傳遞參數
當函數參數部分是壹階指針時,可以接受哪些參數?例如test(int * p)。
(1)可以是整數指針。
②可以是整數變量地址。
(3)可以是壹維整數數組的數組名。
# include & ltstdio.h & gtvoid print(int * p,int sz)
{ int I = 0;for(I = 0;我& ltSZ;i++)
{ printf(“% d \ n“,*(p+I));
}
}int main()
{ int arr【10】= { 1,2,3,4,5,6,7,8,9 };int * p = arrint SZ = sizeof(arr)/sizeof(arr【0】);//壹級指針p傳遞給函數print(p,SZ);返回0;
}
2.二級指針傳輸參數
即當函數參數部分為二級指針時,可以接受哪些參數,如:test(int * * p)。
(1)輔助指針變量
(2)第壹指針變量地址
(3)壹維指針數組的數組名
# include & ltstdio.h & gt無效測試(內部**指針)
{ printf(“num = % d \ n“,* * ptr);
}int main()
{ int num = 10;int * p = & ampnumint * * pp = & ampp;
測試(PP);
測試(& ampp);返回0;
}
四、函數指針、函數指針數組、函數指針數組指針
1.功能指針
無效測試()
{printf(“呵呵\ n“);
}//pfun可以存儲測試函數的地址void(* pfun)();
函數指針的形式:類型(*),例如:int(* p)()。它可以存儲函數的地址,在普通應用程序中也很常見。
2.函數指針數組
形式:例如int(* p【10】)();
因為p首先與【】組合在壹起,這意味著p是壹個數組,數組的內容是壹個int(*)指針。
函數指針數組廣泛應用於轉換表中。
3.函數指針數組的指針
指向函數指針數組的指針,即指針指向其元素都是函數指針的數組。
void測試(const char* str)
{ printf(“% s \ n“,str);
}int main()
{//函數指針pfun void(* pfun)(const char *)= test;//函數指針pfunarrvoid(* pfunarr【5】)的數組(const char * str);
pfunArr【0】= test;//指針pfunArrvoid(*(* ppfunarr)【10】)(const char *)= &;pfunArr返回0;
}