函數(shù)調(diào)用不能這么用,第36行。C標(biāo)準(zhǔn)里面返回值是不能直接返回一個(gè)數(shù)組的,只能返回?cái)?shù)組的首地址。輸出學(xué)生成績(jī)和每科成績(jī)那個(gè)函數(shù),你可以定義一個(gè)全局變量數(shù)組,還有求平均值最好用float 或者double,用int會(huì)造成精度流失。幫你調(diào)試了一下,大概就這樣吧
府谷網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、自適應(yīng)網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)成立于2013年到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
在子函數(shù)申請(qǐng)二維數(shù)組,主函數(shù)使用,可以用動(dòng)態(tài)申請(qǐng)。
方法不止一種,我這里用指針的指針實(shí)現(xiàn)二維數(shù)組。
二維數(shù)組除了行列,本身地址也是連續(xù)的,從第一行第一列的元素地址++,可以取出所有元素。所以我這里先申請(qǐng)了完整的連續(xù)地址。
#includestdio.h
#includemalloc.h
int?**?sr(void)
{
int?i,j;
int?*memory=(int?*)malloc(sizeof(int)*9);//申請(qǐng)完整的連續(xù)內(nèi)存地址3*3
int?**arr=(int?**)malloc(sizeof(int*)*3);//申請(qǐng)二維數(shù)組行指針數(shù)組(也就是二維數(shù)組)
if(!memory?||?!arr){
printf("內(nèi)存申請(qǐng)錯(cuò)誤!\n");return?NULL;}
for(i=0,j=0;i9;i+=3)//將連續(xù)地址按列數(shù),取出每行首地址,賦值給二維數(shù)組元素
arr[j++]=memory[i];
for(i=0;i3;i++)
for(j=0;j3;j++)
scanf("%d",arr[i][j]);
return?arr;
}
int?main(void)
{
int?i,j,**arr=sr();
if(!arr)
return?1;
printf("---主函數(shù)調(diào)用子函數(shù)定義的二維數(shù)組---\n");
for(i=0;i3;i++,printf("\n"))
for(j=0;j3;j++)
printf("%d?",arr[i][j]);
printf("\n---實(shí)現(xiàn)二維數(shù)組地址連續(xù)性---\n");
int?*p=arr[0][0];
while(p=arr[2][2])
printf("%d?",*p++);
return?0;
}
正如樓下所言
int
**p
,定義的p是一個(gè)指向int*型的指針
int
(*p)[10]是一個(gè)指向數(shù)組的指針
數(shù)組長(zhǎng)度為10
假如定義成
deal(int
**p),傳參數(shù)時(shí)要加強(qiáng)制類型轉(zhuǎn)換:
deal((int**)a);
并且使用p時(shí)不能用下標(biāo),p[2][3]是錯(cuò)誤的,因?yàn)椴恢纏指向的int*型的長(zhǎng)度,無(wú)法編譯成*(p+2*10+3)
必須自己寫成*(p+2*10+3)來(lái)調(diào)用
假如定義成
deal(int
(*p)[10])就不一樣了,編譯器就能知道p是一個(gè)指向長(zhǎng)度為10的數(shù)組的指針
那么p[2][3]就能編譯成*(p+2*10+3)了
總之,c語(yǔ)言是很靈活的,不同的定義方式配上不同的用法,都是能得到正確的結(jié)果的
不知道這么說(shuō)樓主明白了沒(méi)?
同樣的還有多維數(shù)組對(duì)多維指針的問(wèn)題,樓主可以自己類推一下
C語(yǔ)言編程的過(guò)程中,不可避免的會(huì)碰到二維或二維以上的數(shù)組作為函數(shù)的形參的情況,在以前的編程過(guò)程中,習(xí)慣了動(dòng)態(tài)數(shù)組的應(yīng)用,很是使用直接定義高維數(shù)組。最近在編程的過(guò)程中就碰到了這個(gè)問(wèn)題:有如下的測(cè)試程序:
voidtest(double??**x,int?Row,int?Col);
voidtest(double??**x)
{
for(int?i=0;iRow;i++)
for(int?k=0;kCol;k++)
x[i][k]?+=?100.0;
}
intmain(int?argc,?char?*argv[])
{
/*
double?**x;
x?=?new?double?*[3];
for(int?i=0;i3;i++)
x[i]?=?new?double[3];
*/
double?x[3][3];
for(int?i=0;i3;i++)
for(int?k=0;k3;k++)
x[i][k]?=?i*k;
test(x,3,3);
for(int?i=0;i3;i++)
for(int?k=0;k3;k++)
printf("x[%d][%d]=?%e\n",i,k,x[i][k]);
getch();
return?0;
}
編譯時(shí)提示Cannot?convert?'double?[*][3]'?to?double?**'。
將調(diào)用方式強(qiáng)制進(jìn)行類型轉(zhuǎn)換:test((double?**)x),編譯通過(guò),運(yùn)行出錯(cuò),提示非法越界。
據(jù)傳:因?yàn)闂I戏峙涞臄?shù)組和堆上分配的數(shù)組在內(nèi)存排列上可能不相同,直接定義的數(shù)組是存儲(chǔ)在程序的堆棧區(qū),數(shù)據(jù)占用連續(xù)的區(qū)間;而動(dòng)態(tài)申請(qǐng)的數(shù)組是在系統(tǒng)的遠(yuǎn)堆上(far?heap),除最后一維的元素是連續(xù)存放的外,其他維上的元素有可能不是在一塊連續(xù)的內(nèi)存區(qū)域里。
//棧上:?
int???ia[2][2]???=?{2,3,4,5};????//4個(gè)元素是連續(xù)排列的內(nèi)存段?
//堆上:?
int???**p??=??new??int*[2];???//只有每行內(nèi)是連續(xù)排列,各行并不一定連續(xù)排列?
for?(?int??i??=?0;??i???2;?i++?)?
{?
p[i]???=??new??int[2];?
}?
for?(?int??i??=??0;??i????2;??i++?)?
{?
for?(?int??j??=??0;??j????2;??j++?)?
{?
p[i][j]???=???ia[i][j];?
}?
}?
所以對(duì)棧上的數(shù)組用int??**p指向首地址,因?yàn)閕nt??**p一次解引用為地址指針,而非堆上的指向數(shù)組的指針,所以二次解引用會(huì)出錯(cuò)。?
如果找一個(gè)通用方程只能用:?
void???f(?int??*p,?int??row,??int??col?)?????//給出數(shù)組的行和列,對(duì)堆上的數(shù)組不合適???
{?
for?(?int??i?=??0;??i????row;??i++)?
{?
for?(?int??j??=??0;??j???col;??j++?)?
{?
cout???p[i?*?row?+?j]???"???";????????????????????????
}?
cout???endl;?
}?
}?
int???main(){?
//.........?
int???ia[2][2]???=??{2,3,4,5};?
f(?(int*)ia,?2,?2?);?
}
采用上面的通用辦法還是比較麻煩,這無(wú)形中對(duì)編程增加了難度,為了避免這個(gè)麻煩可以采用動(dòng)態(tài)數(shù)組的形式,將原來(lái)采用直接定義的數(shù)組全部換成動(dòng)態(tài)數(shù)組,類似開(kāi)頭例子中被注釋掉的那部分代碼,當(dāng)然這樣也有后續(xù)的麻煩,動(dòng)態(tài)數(shù)組的生命周期完成后必須釋放內(nèi)存空間,這也有點(diǎn)羅嗦,但是畢竟可以直接使用數(shù)組的形式,比上面的通用方式還是要簡(jiǎn)單一點(diǎn)。
如果執(zhí)意要使用直接定義的數(shù)組該怎么辦呢?有如下幾種方法:
方法一:
voidtest(double??(*x)[3],?int?Row,?int?Col);
調(diào)用方式:test(x,Row,Col);
調(diào)用用方式?test(x,Row,Col);
方法二:
voidtest(double??x[][3],?int?Row,int?Col);
調(diào)用方式?test(x,Row,Col);
對(duì)于多維數(shù)組作為參數(shù),除第一維之外的其它維必須指定維數(shù),否則是肯定編譯不過(guò)去的。
從上面的對(duì)直接定義的數(shù)組的引用情況看,直接定義的數(shù)組的使用比較麻煩,一旦直接定義數(shù)組的維數(shù)發(fā)生變換,函數(shù)的定義必須相應(yīng)的修改,否則程序就會(huì)出錯(cuò),這也增加了程序進(jìn)一步開(kāi)發(fā)的麻煩,為了一勞永逸的解決這個(gè)問(wèn)題,建議還是使用動(dòng)態(tài)數(shù)組的方法,雖然需要手工釋放內(nèi)存,但是除卻了后續(xù)的麻煩。