1. 程式人生 > >進擊的小白Day011——基於TCP的Socket程式設計(六)

進擊的小白Day011——基於TCP的Socket程式設計(六)

把Socket程式中一些複雜的部分整合成函式,雖然有些程式碼量比較短沒必要整合,但還是鍛鍊一下這個方法吧。

#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib,"ws2_32.lib")
#define PORT 8888  /*定義埠*/
#define MODE 1  /*定義服務端*/
#define MAXDATA 100  /*定義最大傳輸數量*/
#define T 100
#define MAX_MAIN 10
#define MAX_RUN 10
#define MAX_MESSAGE 100
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

/*定義時間結構體*/
struct Time
{
	long int modeTime;
	long int connectTime;
	long int messageTime;
	long int allowTime[MAX_RUN];
	long int exeTime[MAX_RUN];
	long int calTime[MAX_RUN];
	long int waitTime[MAX_RUN];
	long int runTime[MAX_RUN];
};

/*微秒計時函式*/
int gettimeofday(struct timeval *tp, void *tzp)
{

	time_t clock;
	struct tm tm;
	SYSTEMTIME wtm;
	GetLocalTime(&wtm);
	tm.tm_year = wtm.wYear - 1900;
	tm.tm_mon = wtm.wMonth - 1;
	tm.tm_mday = wtm.wDay;
	tm.tm_hour = wtm.wHour;
	tm.tm_min = wtm.wMinute;
	tm.tm_sec = wtm.wSecond;
	tm.tm_isdst = -1;
	clock = mktime(&tm);
	tp->tv_sec = clock;
	tp->tv_usec = wtm.wMilliseconds * 1000;
	return 0;
}

/*執行演算法*/
int exe(void)
{
	long i = 10000000L;
	while (i--);
	//printf("	This is a program that needs to be executed !\n");
	return 0;
}

/*模式選擇函式*/
int modeChoose(void)
{
	int mode;

	/*選擇服務端或客戶端*/
	printf("Please choose server of client.		1.Server  2.Client\n");
	scanf_s("%d", &mode);
	getchar();
	/*mode = MODE;*/

	return mode;
}

/*建立套接字*/
SOCKET creatSocket(void)
{
	SOCKET Socket = socket(AF_INET, SOCK_STREAM, 0);
	if (Socket == -1)
	{
		printf("Socket error !");
		getchar();
		exit(1);
	}
	return Socket;
}

/*繫結IP埠*/
void bindIP(SOCKET Socket, struct sockaddr_in Socketaddr)
{
	/*繫結IP和埠*/
	Socketaddr.sin_family = AF_INET;  /*定義家族協議*/
	Socketaddr.sin_addr.s_addr = inet_addr("127.0.0.1");  /*定義主機地址*/
	Socketaddr.sin_port = htons(PORT);  /*定義主機埠*/
	if (bind(Socket, (struct sockaddr *)&Socketaddr, sizeof(Socketaddr)) == -1)  /*繫結成功返回0*/
	{
		printf("Bind error !");
		getchar();
		exit(1);
	}
}

/*監聽*/
void listenSocket(SOCKET Socket)
{
	/*開始監聽*/
	if (listen(Socket, 20) == -1)
	{
		printf("Listen error !");
		getchar();
		exit(1);
	}
}

SOCKET acceptSocket(SOCKET Socket_1, struct sockaddr_in Socketaddr_2)
{
	int len = sizeof(struct sockaddr_in);
	SOCKET Socket_2 = accept(Socket_1, (SOCKADDR *)&Socketaddr_2, &len);
	if (Socket_2 == -1)
	{
		printf("Accept error !");
		getchar();
		exit(1);
	}

	return Socket_2;
}

void connentSocket( SOCKET Socket, struct sockaddr_in Socketaddr)
{
	int con;
	/*連線服務端*/
	con = -1;
	while (con == -1)
	{
		con = connect(Socket, (struct sockaddr*)&Socketaddr, sizeof(Socketaddr));
		if (con == -1)
		{
			printf("Connect error!\n");
		}
	}
}

void sendMessage(SOCKET Socket, char *Msg, int len)
{
	/*傳送準備資訊*/
	if (send(Socket, Msg, len, 0) < 0)
	{
		printf("\n\nSend error or connection interruption !\n");
		getchar();
		exit(1);
	}
}

char receiveMessage(SOCKET Socket)
{
	int ret;
	char receiveData[MAXDATA];

	/*接收準備資訊*/
	ret = recv(Socket, receiveData, MAXDATA, 0);
	if (ret > 0)
	{
		receiveData[ret] = 0x00;
		printf("From client: %s\n", receiveData);
	}
	/*接收不到客戶端資料時中斷迴圈*/
	else
	{
		printf("\n\nReceive error or connection interruption !\n");
		getchar();
		exit(1);
	}

	return receiveData;
}

/*字串轉換*/
char charChange(double d)
{
	int dec_1, sign_1, dec_2, sign_2;
	char c;
	_ecvt(d, 10, &dec_1, &sign_1);
	c = _ecvt(d, dec_1, &dec_2, &sign_2);
	return c;
}

int compareTime(int a, int b)
{
	int t;
	if (a >= b)
	{
		t = a;
	}
	else
	{
		t = b;
	}

	return t;
}

struct Time run(void)
{
	/*各種定義宣告*/
	SOCKET server;
	SOCKET client;
	struct sockaddr_in serveraddr;
	struct sockaddr_in clientaddr;
	WSADATA wsaData;
	struct Time allTime;

	int len = sizeof(struct sockaddr_in);
	int exeTime, serverTime_i, clientTime_i, ret, ret_time_server, ret_time_client;
	int t = T, waitTime;
	int mode, i;
	char receiveData[MAXDATA];
	char runData[MAXDATA];
	char byeData[MAXDATA];
	char serverTime_c[MAXDATA], *serverTime_c_server, clientTime_c[MAXDATA], *clientTime_c_client;
	double serverTime_d, clientTime_d;
	clock_t startTime, endTime;  /*定義計時變數*/
	struct timeval start, end, allowstart, allowend, waitstart, waitend, exestart, exeend, calstart, calend;
	long int allowSum = 0, exeSum = 0, calSum = 0, waitSum = 0, runSum = 0;
	int waitTime_0[MAX_RUN];

	/*微妙計時開始*/
	gettimeofday(&start, NULL);

	mode = modeChoose();

	/*服務端*/
	if (mode == 1)
	{
		/*微妙計時結束,計算連線時間*/
		gettimeofday(&end, NULL);
		allTime.modeTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;

		/*微妙計時開始*/
		gettimeofday(&start, NULL);

		/*啟動windows的socket服務,初始化WSA*/
		WSAStartup(0x101, &wsaData);

		/*建立服務端,初始化服務端地址*/
		memset((void*)&serveraddr, 0, sizeof(serveraddr));

		server = creatSocket();

		bindIP(server, serveraddr);

		listenSocket(server);

		//printf("Waiting for connection...\n\n");
		client = acceptSocket(server, serveraddr);
		//printf("Receive a connection: %s \r\n\n", inet_ntoa(clientaddr.sin_addr));

		/*微妙計時結束,計算連線時間*/
		gettimeofday(&end, NULL);
		allTime.connectTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;

		/*微妙計時開始*/
		gettimeofday(&start, NULL);

		for (i = 0; i < MAX_MESSAGE; i++)
		{
			sendMessage(client, "I'm ready !", 11);
			receiveMessage(client);
		}

		/*微妙計時結束,計算訊息時間*/
		gettimeofday(&end, NULL);
		allTime.messageTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;

		for (i = 0; i < MAX_RUN; i++)
		{
			/*微妙計時開始*/
			gettimeofday(&start, NULL);

			/*微妙計時開始*/
			gettimeofday(&allowstart, NULL);

			/*發:第一次握手*/
			sendMessage(client, "First:Run !", 11);

			/*收:第二次握手*/
			runData[MAXDATA] = receiveMessage(client);
			
			if (strcmp(runData, "Second:Run !") == 0)
			{
				/*發:第三次握手*/
				sendMessage(client, "Third:Run !", 11);

				/*微妙計時結束,計算執行時間*/
				gettimeofday(&allowend, NULL);
				allTime.allowTime[i] = 1000000 * (allowend.tv_sec - allowstart.tv_sec) + allowend.tv_usec - allowstart.tv_usec;
				allowSum = allowSum + allTime.allowTime[i];

				/*執行時間大於週期時間,則直接執行執行*/
				if (t >= T)
				{
					/*微妙計時開始*/
					gettimeofday(&exestart, NULL);

					/*計時開始*/
					startTime = clock();

					exe();

					/*計時結束*/
					endTime = clock();

					/*微妙計時結束,計算執行時間*/
					gettimeofday(&exeend, NULL);
					allTime.exeTime[i] = 1000000 * (exeend.tv_sec - exestart.tv_sec) + exeend.tv_usec - exestart.tv_usec;
					exeSum = exeSum + allTime.exeTime[i];

					/*微妙計時開始*/
					gettimeofday(&calstart, NULL);

					/*服務端執行用時*/
					serverTime_d = (double)(endTime - startTime);
					//printf("serverTime_d=%ld\n", serverTime_d);
					//printf("exeTime=%ld\n", allTime.exeTime[i] / 1000);

					serverTime_c_server = charChange(serverTime_d);
		
					sendMessage(client, serverTime_c_server, strlen(serverTime_c_server));

					clientTime_c[MAXDATA] = receiveMessage(client);

					/*字串轉整形*/
					serverTime_i = atoi(serverTime_c_server);
					//printf("Server's operation time is %d\n", serverTime_i);
					clientTime_i = atoi(clientTime_c);
					//printf("Client's operation time is %d\n", clientTime_i);

					t = compareTime(serverTime_i, clientTime_i);
					//printf("The whole system's operation time is %d\n\n", t);

					/*微妙計時結束,計算執行時間*/
					gettimeofday(&calend, NULL);
					allTime.calTime[i] = 1000000 * (calend.tv_sec - calstart.tv_sec) + calend.tv_usec - calstart.tv_usec;
					calSum = calSum + allTime.calTime[i];

					/*執行總時長小於週期時間,掛起*/
					if (t <= T)
					{
						waitTime_0[i] = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000;

						Sleep(waitTime_0[i]);
						t = T;

						allTime.waitTime[i] = waitTime_0[i] * 1000;
						waitSum = waitSum + allTime.waitTime[i];

						/*gettimeofday(&waitstart, NULL);
						waitTime = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000;
						Sleep(waitTime);
						t = T;
						gettimeofday(&waitend, NULL);
						allTime.waitTime[i] = 1000000 * (waitend.tv_sec - waitstart.tv_sec) + waitend.tv_usec - waitstart.tv_usec;
						waitSum = waitSum + allTime.waitTime[i];*/

					}
					else
					{
						allTime.waitTime[i] = 0;
					}
				}
			}

			/*微妙計時結束,計算執行時間*/
			gettimeofday(&end, NULL);
			allTime.runTime[i] = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
			runSum = runSum + allTime.runTime[i];
		}

		closesocket(server);
		WSACleanup();

		printf("modeTime=%ld, connectTime=%ld, messageTime=%ld\n", allTime.modeTime, allTime.connectTime, allTime.messageTime);
		printf("allowTime=%ld, exeTime=%ld, calTime=%ld, waitTime=%ld\n\n", allowSum / MAX_RUN, exeSum / MAX_RUN, calSum / MAX_RUN, waitSum / MAX_RUN);
		//printf("runTime=%ld\n\n", runSum / MAX_RUN);

	}

	/*客戶端*/
	else
	{
		/*微妙計時結束,計算連線時間*/
		gettimeofday(&end, NULL);
		allTime.modeTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;

		/*微妙計時開始*/
		gettimeofday(&start, NULL);

		/*啟動windows的socket服務,初始化WSA*/
		WSAStartup(0x101, &wsaData);

		/*建立客戶端,初始化客戶端地址*/
		memset((void*)&clientaddr, 0, sizeof(clientaddr));

		client = creatSocket();

		/*繫結IP和埠*/
		clientaddr.sin_family = AF_INET;  /*定義家族協議*/
		clientaddr.sin_addr.s_addr = inet_addr("127.0.0.1");  /*定義主機地址*/
		clientaddr.sin_port = htons(PORT);  /*定義主機埠*/

		connentSocket(client, clientaddr);

		/*微妙計時結束,計算連線時間*/
		gettimeofday(&end, NULL);
		allTime.connectTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;

		/*微妙計時開始*/
		gettimeofday(&start, NULL);

		for (i = 0; i < MAX_MESSAGE; i++)
		{
			receiveMessage(client);
			sendMessage(client, "I'm ready too !", 15);
		}

		/*微妙計時結束,計算訊息時間*/
		gettimeofday(&end, NULL);
		allTime.messageTime = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;

		/*檢驗執行許可指令並開始執行*/

		for (i = 0; i < MAX_RUN; i++)  /*改*/
		{
			/*微妙計時開始*/
			gettimeofday(&start, NULL);

			/*微妙計時開始*/
			gettimeofday(&allowstart, NULL);

			/*收:第一次握手*/
			runData[MAXDATA] = receiveMessage(client);

			if (strcmp(runData, "First:Run !") == 0)
			{
				/*發:第二次握手*/
				sendMessage(client, "Second:Run !", 12);
			}

			/*收:第三次握手*/
			runData[MAXDATA] = receiveMessage(client);

			/*微妙計時結束,計算執行時間*/
			gettimeofday(&allowend, NULL);
			allTime.allowTime[i] = 1000000 * (allowend.tv_sec - allowstart.tv_sec) + allowend.tv_usec - allowstart.tv_usec;
			allowSum = allowSum + allTime.allowTime[i];

			if (strcmp(runData, "Third:Run !") == 0)
			{
				/*執行時間大於週期時間,則直接執行執行*/
				if (t >= T)
				{
					/*微妙計時開始*/
					gettimeofday(&exestart, NULL);

					/*計時開始*/
					startTime = clock();

					exe();

					/*計時結束*/
					endTime = clock();

					/*微妙計時結束,計算執行時間*/
					gettimeofday(&exeend, NULL);
					allTime.exeTime[i] = 1000000 * (exeend.tv_sec - exestart.tv_sec) + exeend.tv_usec - exestart.tv_usec;
					exeSum = exeSum + allTime.exeTime[i];

					/*微妙計時開始*/
					gettimeofday(&calstart, NULL);

					/*客戶端執行用時*/
					clientTime_d = (double)(endTime - startTime);

					clientTime_c_client = charChange(clientTime_d);

					sendMessage(client, clientTime_c_client, strlen(clientTime_c_client));

					serverTime_c[MAXDATA] = receiveMessage(client);

					/*字串轉整形*/
					serverTime_i = atoi(serverTime_c);
					//printf("Server's operation time is %d\n", serverTime_i);
					clientTime_i = atoi(clientTime_c_client);
					//printf("Client's operation time is %d\n", clientTime_i);

					t = compareTime(serverTime_i, clientTime_i);
					//printf("The whole system's operation time is %d\n\n", t);

					/*微妙計時結束,計算執行時間*/
					gettimeofday(&calend, NULL);
					allTime.calTime[i] = 1000000 * (calend.tv_sec - calstart.tv_sec) + calend.tv_usec - calstart.tv_usec;
					calSum = calSum + allTime.calTime[i];

					/*執行總時長小於週期時間,掛起*/
					if (t <= T)
					{
						waitTime_0[i] = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000;

						Sleep(waitTime_0[i]);
						t = T;

						allTime.waitTime[i] = waitTime_0[i] * 1000;
						waitSum = waitSum + allTime.waitTime[i];

						/*gettimeofday(&waitstart, NULL);
						waitTime = T - t - (allTime.calTime[i] + allTime.allowTime[i]) / 1000;
						Sleep(waitTime);
						t = T;
						gettimeofday(&waitend, NULL);
						allTime.waitTime[i] = 1000000 * (waitend.tv_sec - waitstart.tv_sec) + waitend.tv_usec - waitstart.tv_usec;
						waitSum = waitSum + allTime.waitTime[i];*/

					}
					else
					{
						allTime.waitTime[i] = 0;
					}
				}
			}
			/*微妙計時結束,計算執行時間*/
			gettimeofday(&end, NULL);
			allTime.runTime[i] = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
			runSum = runSum + allTime.runTime[i];
		}

		closesocket(client);
		WSACleanup();

		printf("modeTime=%ld, connectTime=%ld, messageTime=%ld\n", allTime.modeTime, allTime.connectTime, allTime.messageTime);
		printf("allowTime=%ld, exeTime=%ld, calTime=%ld, waitTime=%ld\n\n", allowSum / MAX_RUN, exeSum / MAX_RUN, calSum / MAX_RUN, waitSum / MAX_RUN);
		//printf("runTime=%ld\n\n", runSum / MAX_RUN);
	}
	return allTime;

}

int main(void)
{
	/*各種定義*/
	struct Time pTime[MAX_MAIN];
	int i, j, k, l;
	long int modeTimeMax, connectTimeMax, messageTimeMax, allowTimeMax, exeTimeMax, calTimeMax, waitTimeMax, runTimeMax;
	long int modeTimeSum, connectTimeSum, messageTimeSum, allowTimeSum, exeTimeSum, calTimeSum, waitTimeSum, runTimeSum;
	long int modeTimeAve, connectTimeAve, messageTimeAve, allowTimeAve, exeTimeAve, calTimeAve, waitTimeAve, runTimeAve;

	/*執行程式*/
	for (i = 0; i < MAX_MAIN; i++)
	{
		pTime[i] = run();
	}

	/*計算選擇模式的最大時間*/
	for (j = 0, modeTimeMax = 0; j < MAX_MAIN; j++)
	{
		if (modeTimeMax < pTime[j].modeTime)
		{
			modeTimeMax = pTime[j].modeTime;
		}
	}

	/*計算連線的最大時間*/
	for (j = 0, connectTimeMax = 0; j < MAX_MAIN; j++)
	{
		if (connectTimeMax < pTime[j].connectTime)
		{
			connectTimeMax = pTime[j].connectTime;
		}
	}

	/*計算髮送接收訊息的最大時間*/
	for (j = 0, messageTimeMax = 0; j < MAX_MAIN; j++)
	{
		if (messageTimeMax < pTime[j].messageTime)
		{
			messageTimeMax = pTime[j].messageTime;
		}
	}

	/*計算三次握手的最大時間*/
	for (k = 0, allowTimeMax = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			if (allowTimeMax < pTime[k].allowTime[l])
			{
				allowTimeMax = pTime[k].allowTime[l];
			}
		}
	}

	/*計算執行演算法的最大時間*/
	for (k = 0, exeTimeMax = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			if (exeTimeMax < pTime[k].exeTime[l])
			{
				exeTimeMax = pTime[k].exeTime[l];
			}
		}
	}

	/*計算時間彙總的最大時間*/
	for (k = 0, calTimeMax = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			if (calTimeMax < pTime[k].calTime[l])
			{
				calTimeMax = pTime[k].calTime[l];
			}
		}
	}

	/*計算等待的最大時間*/
	for (k = 0, waitTimeMax = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			if (waitTimeMax < pTime[k].waitTime[l])
			{
				waitTimeMax = pTime[k].waitTime[l];
			}
		}
	}

	/*計算迴圈的最大時間*/
	for (k = 0, runTimeMax = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			if (runTimeMax < pTime[k].runTime[l])
			{
				runTimeMax = pTime[k].runTime[l];
			}
		}
	}

	/*計算選擇模式的平均時間*/
	for (j = 0, modeTimeSum = 0; j < MAX_MAIN; j++)
	{
		modeTimeSum += pTime[j].modeTime;
	}
	modeTimeAve = modeTimeSum / MAX_MAIN;

	/*計算連線的平均時間*/
	for (j = 0, connectTimeSum = 0; j < MAX_MAIN; j++)
	{
		connectTimeSum += pTime[j].connectTime;
	}
	connectTimeAve = connectTimeSum / MAX_MAIN;

	/*計算髮送接收訊息的平均時間*/
	for (j = 0, messageTimeSum = 0; j < MAX_MAIN; j++)
	{
		messageTimeSum += pTime[j].messageTime;
	}
	messageTimeAve = messageTimeSum / MAX_MAIN;

	/*計算執行演算法的平均時間*/
	for (k = 0, allowTimeSum = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			allowTimeSum += pTime[k].allowTime[l];
		}
	}
	allowTimeAve = allowTimeSum / (MAX_MAIN * MAX_RUN);

	/*計算執行演算法的平均時間*/
	for (k = 0, exeTimeSum = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			exeTimeSum += pTime[k].exeTime[l];
		}
	}
	exeTimeAve = exeTimeSum / (MAX_MAIN * MAX_RUN);

	/*計算時間彙總的平均時間*/
	for (k = 0, calTimeSum = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			calTimeSum += pTime[k].calTime[l];
		}
	}
	calTimeAve = calTimeSum / (MAX_MAIN * MAX_RUN);

	/*計算等待的平均時間*/
	for (k = 0, waitTimeSum = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			waitTimeSum += pTime[k].waitTime[l];
		}
	}
	waitTimeAve = waitTimeSum / (MAX_MAIN * MAX_RUN);

	/*計算迴圈的平均時間*/
	for (k = 0, runTimeSum = 0; k < MAX_MAIN; k++)
	{
		for (l = 0; l < MAX_RUN; l++)
		{
			runTimeSum += pTime[k].runTime[l];
		}
	}
	runTimeAve = runTimeSum / (MAX_MAIN * MAX_RUN);

	/*輸出結果*/
	printf("modeTimeMax=%ld, modeTimeAve=%ld\n", modeTimeMax, modeTimeAve);
	printf("connectTimeMax=%ld, connectTimeAve=%ld\n", connectTimeMax, connectTimeAve);
	printf("messageTimeMax=%ld, messageTimeAve=%ld\n", messageTimeMax, messageTimeAve);
	printf("allowTimeMax=%ld, allowTimeAve=%ld\n", allowTimeMax, allowTimeAve);
	printf("exeTimeMax=%ld, exeTimeAve=%ld\n", exeTimeMax, exeTimeAve);
	printf("calTimeMax=%ld, calTimeAve=%ld\n", calTimeMax, calTimeAve);
	printf("waitTimeMax=%ld, waitTimeAve=%ld\n", waitTimeMax, waitTimeAve);
	//printf("runTimeMax=%ld, runTimeAve=%ld\n", runTimeMax, runTimeAve);

	Sleep(10000000000);

	return 0;
}

收穫:

  1. 模式控制可以用BOOL來實現,比如
BOOL hasMsg = FALSE;
statement1
if (!hasMsg)
{
	statement2
}
  1. “error LNK2019: 無法解析的外部符號”這個錯誤有可能是不同版本的vs之間不相容造成的,在當前版本的vs下重建一個專案,然後把程式碼複製過去,就可以解決這個問題
  2. 所有陣列,只有在定義時才能初始化,其他時候的初始化都是錯的