iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 28
0
自我挑戰組

30 Days 如何把 C 語言偽裝成高階語言 OWO /系列 第 29

Day 28: 例外處理系列:研究結束中 :finally() 、進行封裝、巨集優化

▌第一次閱讀本系列的,可以先看:

本系列的大綱 傳送門


▌第一次閱讀例外處理系列,可以先看:

例外處理系列 開始第一篇 傳送門


本例外處理系列為【實驗性質】,研究結束中......。
啊啊啊啊,沒辦法把 try 改成不需要返回點的形式,
然後就可以去掉 catch_end ......我想不到啊!!
__COUNTER__ 不能 reset 啊啊aaaaaa ヽ(#`Д´)ノ
我做不到跨區域的相同巨集定義啊, (╯‵□′)╯︵┴─┴ (崩潰

  • 增加了 finally()clear_throw() 巨集函數。
  • 刪除了被 error_code 代替的 isItError
  • error_place 改名為 back_point
  • back_pointerror_code 改為靜態變數,並進行封裝
    • 增加了對應的儲存用函數、getter、setter。
  • 巨集優化, catch_end 的參數上限增加為十個,
    • 並且具有較好的可擴展性(較容易增加上限)。

以下打包核心代碼,製成標頭檔載入:

#pragma once

#include <string.h>

/*back_point 's connecter, getter, setter*/
char **connect_back_point() {
	static char *back_point;
	return &back_point;
}
char *getter_back_point() {
	return *connect_back_point();
}
void setter_back_point(char *set_back_point) {
	*connect_back_point() = set_back_point;
}

#define connect_back_point() printf("For encapsulation, please don't use this function.");

/*error_code 's connecter, getter, setter*/
char **connect_error_code() {
	static char *error_code = "";
	return &error_code;
}
char *getter_error_code() {
	return *connect_error_code();
}
void setter_error_code(char *set_error_code) {
	*connect_error_code() = set_error_code;
}

#define connect_error_code() printf("For encapsulation, please don't use this function.");


/*throw*/
#define throw(ex_name, ...) \
\
setter_error_code(#ex_name); \
return __VA_ARGS__;

/*clear_throw*/
#define clear_throw() \
\
setter_error_code("");

/*check*/
#define check(...) \
\
if(strcmp(getter_error_code(), "")){ \
	return __VA_ARGS__; \
}

/*try$*/
#define try$(back_point, args) \
\
if(strcmp(getter_error_code(), "")){ \
	setter_back_point(#back_point); \
	if(strcmp(args, "")) \
		setter_error_code(args); \
	goto catch_start;\
} \
back_point:

/*try*/
#define try(back_point, ...) try$(back_point, "" #__VA_ARGS__)

/*catch_start*/
#define catch_start(...) \
\
catch_start: \
if(!strcmp(getter_error_code(), "")) return __VA_ARGS__;

/*catch*/
#define catch(ex_name) \
\
if(!strcmp(getter_error_code(), #ex_name))

/*finally*/
#define finally() 

/*back*/
#define back(back_point) \
\
if(!strcmp(getter_back_point(), #back_point)){ \
	goto back_point; \
}

/*get_11th_arg*/
#define get_11th_arg(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, arg11, ...) arg11

/*magic_bracket*/
#define magic_bracket(...) (__VA_ARGS__)
#define magic_left_bracket(...) (__VA_ARGS__

/*back2 - 10*/
#define back2(arg2, arg1) back(arg2) back(arg1) printf("[Error] 沒有透過 try 進入 catch / 找不到相應的返回點");
#define back3(arg3, ...) back(arg3) back2 magic_bracket(__VA_ARGS__)
#define back4(arg4, ...) back(arg4) back3 magic_bracket(__VA_ARGS__)
#define back5(arg5, ...) back(arg5) back4 magic_bracket(__VA_ARGS__)
#define back6(arg6, ...) back(arg6) back5 magic_bracket(__VA_ARGS__)
#define back7(arg7, ...) back(arg7) back6 magic_bracket(__VA_ARGS__)
#define back8(arg8, ...) back(arg8) back7 magic_bracket(__VA_ARGS__)
#define back9(arg9, ...) back(arg9) back8 magic_bracket(__VA_ARGS__)
#define back10(arg10, ...) back(arg10) back9 magic_bracket(__VA_ARGS__)

/*back_list 10-1*/
#define back_list back10, back9, back8, back7, back6, back5, back4, back3, back2, back

/*catch_end*/
#define catch_end(...) \
\
setter_error_code(""); \
get_11th_arg magic_left_bracket(__VA_ARGS__), back_list) (__VA_ARGS__)

怕可移植性不夠的話, #pragma once 當然可以改成:

#ifndef __C_TRY_CATCH_H__
#define __C_TRY_CATCH_H__
/*code*/
#endif

然後 #include <string.h> 改成:

#ifndef __STRING_H__  //這是約定的命名規則
#define __STRING_H__
#endif

雖然幾乎所有的編譯器都支持 #pragma once 了。


主程序:

/*main.c*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "C_try_catch.h"

void can_not_be_negative(double input) {
	if (input < 0) {
		throw(ex_neg);
	}
}

double my_sqrt(double input) {
	can_not_be_negative(input); check(0.0);
	return sqrt(input);
}


int main() {

	my_sqrt(-10); try(ex1);
	my_sqrt(20); try(ex2);
	my_sqrt(-30); try(ex3, anthor_ex);

	/*... any things ...*/

	system("pause");

	catch_start(0);
	catch (ex_neg) {
		printf("[ex_neg] exception is happened!\n");
		printf("Input can't no be negative.\n");
	}
	catch (anthor_ex) {
		printf("[anthor_ex] exception is happened!\n");
	}
	finally() {
		printf("exception is happened!\n\n");
	}
	catch_end(ex1, ex2, ex3);
}
[ex_neg] exception is happened!
Input can't no be negative.
exception is happened!

[anthor_ex] exception is happened!
exception is happened!

Press any key to continue . . .

不知道未來回來看的時候,會不會恥笑自己的愚蠢呢,(`・ω・´)。


太晚了,好累,還要上學,

還要上該死的 java 堂java 真是太囉嗦了。

C 語言是世界上最好的語言!!! 我機械碼不服..(拖走


所以明天就是 巨集函數具體的使用方式,

後天就完結撒花咯!!~


巨集有很多黑魔法的使用方式没時間介紹,

有時間再放在我剛開沒多久的blog吧。

(ノ>ω<)ノ~!


上一篇
Day 27: 例外處理系列:研究進行中 :大量優化、黑魔法
下一篇
Day 29: 例外處理系列:巨集函數具體的使用方式
系列文
30 Days 如何把 C 語言偽裝成高階語言 OWO /31

尚未有邦友留言

立即登入留言