全文主要是翻譯原文,並記錄自己的閱讀。
在這篇文章中我們的目的是建構一個指向 Shape 物件的指標陣列,每一個 Shape 指向物件 Circle、Square、Goat 等不同物件,皆以純 C 實現。
先建立三個結構。
struct Square{
int width;
int height;
};
struct Circle{
float radius;
};
struct Triangle{
int base;
int height;
};
印出來看看。
printf("size of square is %d\n", sizeof(struct Square));
printf("size of Circle is %d\n", sizeof(struct Circle));
printf("size of Triangle is %d\n", sizeof(struct Triangle));
結果如下。
//size of cube is 8
//size of circle is 4
//size of triangle is 8
可以注意到這邊的結構中的成員在記憶體中很巧妙的對齊。
以下的輸出結果是 1,印出了 Square 前面 4 個 bytes 的值。
struct Square square;
square.width = 1;
square.height = 2;
printf("the first 4 bytes of square are %d", (*(int*)(&square)))
以下這個也是印出 1。
printf("the first 4 bytes of square are %d\n", square); //this works?
operand &
會給我們 square 這個結構一開始的記憶體位置,這個也能印出來,但是我們要把她轉成 int 的地址。
printf("the first 4 bytes of square are %d\n", &square);
這樣我們就可以印出來 int 用我們轉乘的 int 指標。
printf("the first 4 bytes of square are %d\n", (int*)&square);
這個也就是我們第一個範例做的事情,但是在我們印出來之前,可以選擇要移動指標。
printf("the second 4 bytes of square are %d\n", (*(int*)&square + 1));
接下來是 function pointers,C 對待 function pointer 就跟其他 member 一樣。底下是一個函式不用吃任何參數也不用回傳值。
void print_square( void ){
printf("Hello Square\n");
}
function pointer 宣告在結構當中。
struct Square{
int width;
int height;
//now for functions
void (* print)( void );
float (* area)( struct Square * this );
};
就像剛剛提到的,我們要建立 Square 需要手動去設定每個成員對應的值,會需要 constructor。
void init_square( struct Square * square, int w, int h ){
(*square).print = print_square;
(*square).width = w;
(*square).height = h;
(*square).area = calc_square_area;
}
所有結構都要宣告。
struct Square square;
struct Circle circle;
struct Triangle triangle;
init_square( &square, 2, 2 );
init_circle( &circle, 7.7 );
init_triangle( &triangle, 2, 3 );
square.print();
circle.print();
triangle.print();
printf("the area of the square is %f\n", square.area(&square));
printf("the area of the circle is %f\n", circle.area(&circle));
printf("the area of the triangle is %f\n", triangle.area(&triangle));
接下來,讓我們來建立結構 Shape,讓三個物件繼承他。
//abstract father class
struct Shape{
void (* print)( void );
float (* area)( struct Shape * this );
};
如果幫剛剛的 Square 改成用 Shape 呼叫 print 函式,會發生甚麼事呢?
struct Shape * pointer = (struct Shape *)□
(*pointer).print(); //?? what is going to happen??
會得到 segmentation fault。那我們再回來討論這些結構的記憶體。
在 Shape 當中的 print 函式是在最開頭的 4 bytes,但是在 Square 當中是第三個 4 bytes。
當我們把一個指向 Square 指標轉成指向 Shape 的指標,記憶體是不變的(untouched),記住,轉型通常是不會改變內部記憶體的任何東西,除非是依些 dynamic casting。
現在讓我們來解決這個問題,填滿前面 8 bytes。
struct Shape{
char padd[8];
void (* print)( void );
float (* area)( struct Shape * this );
};
最後。
struct Shape * shapes[3];
shapes[0] = (struct Shape *)□
shapes[1] = (struct Shape *)&circle;
shapes[2] = (struct Shape *)▵
int i;
for(i=0; i<3; ++i){
(*shapes[i]).print();
printf("%f\n\n", (*shapes[i]).area(shapes[i]));
}
這就是很基本的用 OOP 觀念實作多形(polymorphism)。
contributed by < Holychung > 2020q3 Homework5 (render) 題目 Outline [TOC] 背景知識 在開始 trace code 之前可以先閱讀 Casting Wolf3D-style Rays with an FPGA and Arduino,當中有提到要撰寫一個 ray casting engine 有兩個方法,其中一個比較直接明瞭的是 Lode's Computer Graphics Tutorial,強烈建議先讀完這篇。 我在讀這篇的時候順便做了點筆記,因為篇幅太長就記錄到 研讀筆記: Raycasting。
Jan 6, 2021source Introduction Raycasting 是一個算繪的技巧,在 2D 呈現 3D 的視野。在電腦運算不夠快的時候是沒辦法跑 3D 引擎,這時候 raycasting 就是一個好辦法。 Raycasting 速度非常的快,因為只需要計算完螢幕上每個垂直的線就好,使用這個方法著名的遊戲 Wolfenstein 3D (德軍總部3D)。 The Basic Idea 基本的 raycasting 觀念是地圖是一個 2D 網狀方格,每一個方格都是 0 (= no wall) 或是正數 (= wall with a certain color or texture)。
Jan 5, 2021antirez/linenoise linenoise 這個 function 是整個程式主要的 API,一開始會檢查是否是 tty,然後在看終端機是否有支援,有支援了話就會呼叫 linenoiseRaw。 char *linenoise(const char *prompt) { char buf[LINENOISE_MAX_LINE]; int count; if (!isatty(STDIN_FILENO)) {
Jan 4, 2021論文連結 dudect Github Introduction Side-channel attack 是一種利用系統實作上的特性,而不是用密碼學演算法本身的攻擊,其中 Timing attacks 是其中一種很常見的手法,可以透過演算法的執行時間進而破解,舉例來說,一個判斷密碼是否正確的算法是從第一個字母開始逐一比對,一遇到不一樣的就馬上返回錯誤,那我們就可以透過多次嘗試,並觀察時間來判斷輸入是否正確。 現今也有一些評估的工具了,像是 Valgrind 的延伸 ctgrind,還有 ctverif 透過靜態的程式分析,但是有一些共同的缺陷是這些方法需要對硬體建模,但是困難的是 CPU 製造商通常不會給太多細節的資訊。 這篇論文的貢獻是,透過自己開發的 dudect,一個透過統計分析的程式判斷程式是否是 constant-time 在給定的平台之下。與其他工具透過靜態分析的手法不同,dudect 是透過 timing leakeage detection tests 對執行時間的統計分析,就可以避開底層硬體的限制,不侷限某特定 CPU 硬體平台。
Jan 4, 2021or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up