C語言系列 : 產生多筆亂序的二進位及文字檔資料

由於之後要複習插入排序法(Insertion Sort)、循序搜尋法(Linear Search)、選擇排序法(Selection Sort)等諸多排序法,因此會需要先寫程式用於產生多筆亂序的資料。

C語言的動態記憶體宣告及配置

編譯式程式語言可分為三種時期,分別為編譯期(Compile Time)、連結期(Link Time)、執行期(Run Time),而記憶體宣告可以分成兩種,分別為靜態記憶體宣告及動態記憶體宣告。

靜態記憶體宣告

靜態記憶體宣告是指編譯時期就配置好記憶體,通常程式設計師在寫程式碼時就需要先決定要配置記憶體的大小,而在C語言的靜態變數宣告,如 :

int moon=10;
float a[10]={};

動態記憶體宣告

由於靜態變數需要在編譯時期就先決定好配置記憶體的大小,且程式在記憶體可以配置的大小有限制,因此當需要配置足夠大的記憶體時 或 在執行程式時期才決定給變數配置多少大小的記憶體時,我們就會選擇使用動態記憶體宣告。動態記憶體宣告是指,變數無須再編譯期就決定大小,可以等到執行期時才決定要配置多少的記憶體,這樣的好處是可以依據資料輸入的大小去宣告不會過少或過多的記憶體空間去存放,程式設計師無需考慮對輸入單位有過多的限制。

在C語言的動態變數宣告,如本程式中的片段 :

int *arr = (int*)malloc(sizeof(int)*arr_num);
//此為一維陣列宣告,記憶體配置的大小為
//儲存一單位整數所需的byte 乘上 使用者所決定列數的大小

而在C++語言的動態變數宣告,如筆者另一個程式中的片段 :

unsigned __int16 ***A_Shell = new unsigned __int16**[M];  
	for (i = 0; i < M; i++)
	{
		A_Shell[i] = new unsigned __int16*[N];
		for (j = 0; j < N; j++)
		{
			A_Shell[i][j] = new unsigned __int16[K];
		}
	}
//三維動態陣列宣告

程式碼的示意圖如下 :


完整程式碼 :

#include "pch.h"
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <iostream>
void rand_value(int*, int, int, int); // 給定左端及右端範圍,給出num個變數
void verification_binary(char *, int, int, int); // verificate 輸出的binary檔案是否正確及輸出
int main()
{
	int total_data = 1, max_range = 1, min_range = 1, arr_num = 1, chose = 1,verti = 1;
	//產生一組不規則大小的變數矩陣,並存入binary及txt檔案中
	printf("請輸入要輸出檔案的數量:");
	scanf("%d", &total_data);
	printf("請輸入每個檔案的亂數數量:");
	scanf("%d", &arr_num);
	printf("請輸入變數範圍:max is ");
	scanf("%d", &max_range);
	printf("請輸入變數範圍:min is ");
	scanf("%d", &min_range);
	printf("請選擇輸出類型(1.binary 2.txt):");
	scanf("%d", &chose);
	if (chose == 1) {
		printf("請選擇是否開啟驗證功能(1.開啟 2.不開啟):");
		scanf("%d", &verti);
	}

	int *arr = (int*)malloc(sizeof(int)*arr_num);
	int *ver = (int*)malloc(sizeof(int)*arr_num);
	FILE *add_data;
	char name[500];
	srand(time(NULL));

	for (int i = 1; i <= total_data; i++) {
		if (chose == 1) {
			sprintf(name, "D:/檔案存放區/想變強嗎人類/那就來寫程式吧/binary資料產生/data_bin/total_value_%d_%d.bin", arr_num, i);
			add_data = fopen(name, "wb+");
			rand_value(arr, min_range, max_range, arr_num);
			fwrite(arr, sizeof(int), arr_num, add_data);
			fclose(add_data);
			if (verti == 1) {
				printf("原始第%d個檔案為:", i);
				for (int j = 0; j < arr_num; j++) {
					printf("%d ", *(arr + j));
				}
				printf("\n");
			}
			verification_binary(name, arr_num, verti,i);
		}
		else if (chose == 2) {
			sprintf(name, "D:/檔案存放區/想變強嗎人類/那就來寫程式吧/binary資料產生/data_txt/total_value_%d_%d.txt", arr_num, i);
			add_data = fopen(name, "w+");
			rand_value(arr, min_range, max_range, arr_num);
			for (int j = 0; j < arr_num;j++) {
				fprintf(add_data, "%d ", *(arr + j));
			}
			fclose(add_data);
		}
		else printf("Error!\n");
	}
	free(arr); //釋放記憶體
	free(ver); //釋放記憶體
}

void rand_value(int *array, int range_left, int range_right, int num) // 給定左端及右端範圍,給出num個變數
{
	int rand_value = 0;
	for (int i = 0; i < num; i++) {
		rand_value = rand() % (range_right - range_left + 1) + range_left;
		*(array + i) = rand_value;
		//printf("%d ", *(array + i));
	}
	return;
}

void verification_binary(char *nam, int arr_nu, int verti,int i) {
	//nam 為完整路徑, arr_nu為一個檔案內存多少變數, verti為是否開啟驗證功能 ,
	//驗證
	FILE *verificate;
	int *ver = (int*)malloc(sizeof(int)*arr_nu);
	if (verti == 1) {
		printf("讀出第%d個檔案為:",i);
		verificate = fopen(nam, "rb");
		fread(ver, sizeof(int), arr_nu, verificate);
		for (int j = 0; j < arr_nu; j++) {
			printf("%d ", *(ver + j));
		}
		fclose(verificate);
		printf("\n");
		//讀入已存入的資料
	}
	else {
		printf("關閉驗證功能。\n");
	}
	
}

程式執行結果 : 

_______________________________________________

我們透過閱讀,拼湊出真實世界的面貌,
並在反覆的探索及思維中,打破由自我無知與偏見所建立的籓籬。