1. 程式人生 > >《C專家程式設計》:函式如何返回一個數組(九)

《C專家程式設計》:函式如何返回一個數組(九)

      這節的內容比較少也比較簡單,主要是覺得用的很少,所以單獨提出來加深印象。主要涉及到函式如何返回一個數組的問題。還有關於記憶體的分配和擴充套件基礎知識的複習。

一、如何使用指標從函式返回一個數組。

    前幾節,我們分析了怎麼樣把一個數組當引數傳遞給指標。本小節換個方向討論資料的轉化:從函式返回一個數組。
嚴格的說,函式無法返回一個數組。但是可以讓函式返回一個指向任何資料結構的指標,當然也可以是一個指向陣列的指標,記住,宣告必須在使用前。一個函式宣告的例子如下:
int (*function())[20];

這裡function是一個函式,它返回一個指標,該指標指向的是包含20個int型別元素的陣列。

返回一陣列的具體實現例子如下:

#include <iostream>
#include <stdlib.h>
using namespace std;
int (*function())[20]
{
	int i=0;
	int (*p)[20];//宣告一個指向20個元素的指標;
	p=(int(*)[20])calloc(20,sizeof(int));
	//或者p=(int (*)[20])malloc(sizeof(int)*20);
	if(!p)//記憶體不夠;
	{
		cout<<"the memory is not enough!"<<endl;
		return NULL;
	}
	for(i=0;i<20;i++)
		(*p)[i]=i+5;
	return p;
}
int main()
{
	int (*result)[20];
	result=function();
	if(result)
	{
		cout<<(*result)[3]<<endl;//這樣訪問結果,應該輸出8。
		free(result);
	}
	system("pause");
	return 0;
}

執行結果如下:


或者定義這樣一個結構體:
struct pp
{
 int arr[20];
}x,y;
struct pp function()  //結構體型別,返回一個結構體物件;
{
   return y;
}
x=y;
x=functoin();
如果要訪問一個元素:可以用下面的方法:
x.arr[10]=100;
注意:千萬不要返回一個指向函式的區域性變數的指標。以前在這裡有詳細的講解
函式可以返回的情況有:
(1)返回一個字串常量;
(2)返回一個靜態變數;
(3)返回一個全域性變數;
(4)返回一個堆空間地址;
(5)最常用的就是(4)程式設計師自己申請一個堆區空間儲存要返回的變數,然後返回。
二、使用指標建立和使用動態陣列

    在很多情況下,我們並不知道陣列的長度,而是使用動態陣列。絕大多數的語言都支援在執行時設定陣列的長度。他們允許程式設計師計算需要處理的資料的個數,然後申請剛好大小的陣列能容納這些資料。
    陣列是靜態的,陣列的長度在編譯期間已經確定不變。在這個領域,C語言支援很弱。你甚至不能用下面的形式:
const int number=10;
int array[number];//編譯出錯,期待一個整形常量表達式。
但是這樣的語句在C++中是合法的。
1、現在我們來看一下如何實現動態陣列,比較簡單!
它的基本思路就是使用malloc()庫函式來得到一大塊記憶體的指標。然後,像引用陣列一樣引用這塊記憶體,其機理就是一個數組下標訪問可以改寫一個指標加上偏移量。
具體程式碼實現如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int number;
	int *arr=NULL;
	int i=0;
	printf("please input the number of your array:\n");
	scanf("%d",&number);//根據具體的個數分配動態空間。
	arr=(int *)malloc(sizeof(int)*number);
	for(i=0;i<number;i++)
		arr[i]=i+5;
	for(i=0;i<number;i++)
		printf("%d-",arr[i]);
	printf("\n");
	system("pause");
	return 0;
}

輸入5,執行結果:


     動態陣列對於避免預定義的限制也是非常有用的。這樣既可以避免空間的浪費,也可以避免記憶體不夠用的尷尬。方便了程式設計師,但是一定要記住釋放申請的記憶體,,不然會造成記憶體的洩漏(leak memeory)。

2、記憶體的擴充套件realloc()函式,比較簡單,不要是為了練手,可能有些冗餘,複習的時候可以跳過。

程式碼實現如下:

#include <stdio.h>
#include <stdlib.h>
int current_element=0;
int total_element=3;
char *arr=NULL;
void add_element(char c)
{
	if(current_element==total_element-1)
	{
		total_element*=2;
		arr=(char *)realloc(arr,total_element);
		if(NULL==arr)
		{
			printf("the memory is not enough!\n");
			return ;
		}
		else
		{
			printf("realloc successfully!\n");
		}
	}
	arr[current_element++]=c;
}
int main()
{
	int number;
	int i=0;
	char *add="ky";
	char array[10]="abcdefghi";
	arr=(char *)malloc(total_element);
	while(current_element < total_element-1)
		arr[current_element++]=array[i++];
	add_element(add[0]);
	add_element(add[1]);
	printf("\n");
	i=0;
	while(i<current_element)
		printf("%c-",arr[i++]);
	printf("\n");
	free(arr);
	system("pause");
	return 0;
}
執行結果:      在筆記(八)裡面用到了一個calloc(n,sizeof(value))函式,它和malloc(size)類似,但是它有兩個引數,一個是變數的大小,一個是變數的個數,返回值是n個變數value的大小空間的首地址。主要適合用於陣列指標的申請記憶體空間。 例如:
int (*p)[5];//p指向的是一個有5個int元素的記憶體空間;
p=(int (*)[5])calloc(5,sizeof(int));
................................