靜態(tài)一維數(shù)組
指針和一維數(shù)組有什么關(guān)系?
- 一維數(shù)組數(shù)組名是一個(gè)指針常量惯豆,存放著一維數(shù)組中第一個(gè)元素的地址
- 數(shù)組的下標(biāo)和指針的關(guān)系:如果
p
是一個(gè)指針變量,那么:
p[i] ? *(p+i)
#include<stdio.h>
void output(int * pArr, int len);
void f(int * pArr, int len);
int main(void)
{
int a[5] = {1,2,3,4,5};
int b[3] = {10,20,30};
output(a, 5);
printf("b[3] = %d, ", b[2]);
f(b, 3);
printf("b[3] = %d\n", b[2]);
return 0;
}
void output(int * pArr, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%d ", *(pArr+i));
//*(pArr+i) ? pArr[i] ? a[i] ? *(a+i)
}
printf("/n");
}
void f(int * pArr, int len)
{
pArr[2] = 10086;
}
函數(shù)想要處理一個(gè)一維數(shù)組敞峭,需要接受哪些參數(shù)攻柠?
- 通過(guò)數(shù)組名球订,可以找到數(shù)組的第一個(gè)元素,因?yàn)閿?shù)組名是一個(gè)指向數(shù)組第一個(gè)元素的指針瑰钮,所以函數(shù)要接受的第一個(gè)參數(shù)是一個(gè)指向數(shù)組頭的指針
- 由于當(dāng)數(shù)組定義下來(lái)之后冒滩,就是開(kāi)辟了一片連續(xù)的內(nèi)存空間,所以現(xiàn)在已經(jīng)確定了數(shù)組的開(kāi)頭在哪里浪谴,但是還不知道數(shù)組在哪里結(jié)束开睡。所以還需要接受數(shù)組的長(zhǎng)度作為第二個(gè)參數(shù)
關(guān)于函數(shù)f
- 在
main
函數(shù)里,在調(diào)用函數(shù)f
的前后分別打印了b[2]的值苟耻,其打印結(jié)果為:b[2] = 30, b[2] = 10086
- 上面提到過(guò)篇恒,
p[i] ? *(p+i)
。因?yàn)?code>p實(shí)際上是一個(gè)指向b[0]
的指針凶杖,所以*pArr
其實(shí)就是b[0]
胁艰。pArr[2]
實(shí)際上就是*(pArr+2)
,即向后移動(dòng)兩個(gè)單元智蝠,因此pArr[2]
就是b[2]
腾么。pArr[2]
進(jìn)行了一次賦值,因此調(diào)用了函數(shù)f
之后b[2]
的值發(fā)生了改變 - 其實(shí)在函數(shù)
f
里操作pArr[2]
和在主函數(shù)里操作b[2]
是一樣的
動(dòng)態(tài)內(nèi)存分配
傳統(tǒng)數(shù)組(靜態(tài)數(shù)組)的缺陷
1 .數(shù)組長(zhǎng)度必須實(shí)現(xiàn)定義下來(lái)杈湾,而且只能是常整數(shù)解虱,不能是變量
2 .傳統(tǒng)形式定義的數(shù)組,該數(shù)組的內(nèi)存程序員無(wú)法通過(guò)編程將其手動(dòng)釋放出來(lái)漆撞,系統(tǒng)為該數(shù)組分配的存儲(chǔ)空間會(huì)一直存在殴泰。除非該數(shù)組所在的函數(shù)中止,系統(tǒng)自己將這段存儲(chǔ)空間釋放
3 .數(shù)組的長(zhǎng)度不能在函數(shù)運(yùn)行時(shí)動(dòng)態(tài)的擴(kuò)充或者減小
4 .在函數(shù)內(nèi)定義的數(shù)組在該函數(shù)運(yùn)行期間可以被其他函數(shù)使用浮驳,但是當(dāng)該函數(shù)運(yùn)行完畢后悍汛,該數(shù)組將無(wú)法被其他函數(shù)使用
使用動(dòng)態(tài)數(shù)組就可以很好的解決靜態(tài)數(shù)組上述的幾個(gè)缺陷
構(gòu)造動(dòng)態(tài)數(shù)組(ANSI C標(biāo)準(zhǔn))
代碼1:
#include<stdio.h>
#include<malloc.h>
int main(void)
{
int i = 10086;
int * p = (int *)malloc(4);
free(p);
//釋放了p所指向的動(dòng)態(tài)分配的內(nèi)存,但是p本身的靜態(tài)內(nèi)存無(wú)法手動(dòng)釋放
return 0;
}
分析一下代碼1:
1 . 要使用malloc
函數(shù)抹恳,必須添加malloc.h
頭文件
2 . malloc
函數(shù)只有一個(gè)形參员凝,形參是整數(shù)類(lèi)型
3 . 4表示請(qǐng)求系統(tǒng)為本程序分配4個(gè)字節(jié)
4 . malloc
函數(shù)只能返回第一個(gè)字節(jié)的地址
5 . 該行分配了8個(gè)字節(jié),指針變量p
占4個(gè)字節(jié)奋献,p
所指向的內(nèi)存也占4個(gè)字節(jié)
6 . p
本身所占的內(nèi)存是靜態(tài)分配的健霹,p
所指向的內(nèi)存是動(dòng)態(tài)分配的,所以free(p)
只能釋放p
所指的那4字節(jié)的動(dòng)態(tài)內(nèi)存瓶蚂,而不能釋放p
自身占用的4個(gè)字節(jié)
代碼2:在另一個(gè)函數(shù)里操作動(dòng)態(tài)內(nèi)存
#include<stdio.h>
#include<malloc.h>
void f(int * q);
int main(void)
{
int * p = (int *)malloc(sizeof(int));
*p = 10;
printf("%d\n", *p);
f(p);
printf("%d\n", *p);
return 0;
}
void f(int * q)
{
*q = 200;
free(q);
}
分析一下代碼2:
1 .函數(shù)f
接收的參數(shù)是一個(gè)int *
類(lèi)型的指針糖埋,main
里面函數(shù)f
的實(shí)參是p
,但是在函數(shù)f
內(nèi)被操作的是int * q
窃这,此時(shí)q
可以被認(rèn)為是p
的一份拷貝
2 .在調(diào)用函數(shù)f
前后分別使用了兩次printf
命令瞳别,第一次的結(jié)果是10,第二次的無(wú)論結(jié)果是多少,這樣的寫(xiě)法都是錯(cuò)誤的(盡管編譯不一定會(huì)報(bào)錯(cuò))祟敛。由于函數(shù)f
在對(duì)*q
賦值之后執(zhí)行了free(q)
命令疤坝,這段p
指向的動(dòng)態(tài)內(nèi)存已經(jīng)還給系統(tǒng)了,main
函數(shù)也不再對(duì)這片內(nèi)存空間有任何讀寫(xiě)的權(quán)限了馆铁,所以對(duì)已經(jīng)不存在的一片內(nèi)存空間進(jìn)行打印操作是沒(méi)有意義的
代碼3:構(gòu)造一維動(dòng)態(tài)數(shù)組