C/C++ Q&A

1. typedef 與 #define 差異?

typedef 是用來定義一個新的資料型態名稱,而 #define 是定義巨集,但編譯器只是用來取代。

ex.

typedef char char_1; // 定義一個新的資料型態名稱,從此多了一個型態。

#define char_2 char; //定義了一個 char 型態,往後遇到 char_2 型態的變數都認為是 char。

2. *& reference to pointer 用意

#include <iostream>
char *str1 = "Hello";
char *str2 = "World";
char *ptr = str1;
char *&rptr = str1;
rptr = str2;
std::cout << ptr << str1 << std::endl;

上面程式會輸出 "Hello World",因為 rptr 是一個 char 指標的『參考』(rptr 是 str1 的參考)。

在 Visual Studio 2008 下 Compile C Program

最近由於要執行別人的 C model,才發現 Visual Studio 2008 支持的 C 語言規範只到 C89 (是最早的 C 語言規範,在90年由美國國家表準協會(ANSI)推出 ANSI 版本,所以也稱做 C90)。然而 C89 coding 方式繁瑣且不直觀,所有的變數宣告都要在函式執行之前,簡單來說就是所有變數都要宣告在頂端就對了。

所以要讓 C model 可以執行,有以下的解決方法,

  1. 最直覺也最簡單的方式,將 C code 全部轉成 .cpp 的格式,利用 VC 裡面的 C++ compiler 來執行。(但這個方法會存在些差異)
  2. IDE 用 VC 或 eclipse,然後 compiler 用 MinGW (MinGW 支援 C99)。
  3. 升級到VC2013,VC2013 裡的 C++ compiler 支援 C99 的變數宣告方式。

 


 

reference :

http://stackoverflow.com/questions/13308944/how-to-simulate-c99-in-visual-studio-for-variables-declaration

http://jashliao.pixnet.net/blog/post/167143629

Visual Studio & .NET Framework

進公司後就對於前人所留下來的code,可以直接點 .dsw 檔案(VC++ 6 Workspace)專案就可以 run 感到覺得很方便,以後自己程式開發也希望能做到一樣,不需要再開新專案重新編譯執行。但我一直找不到如何輸出 .dsp 和 .dsw ...困惑了一陣子,今天終於開竅了...

其實 .dsp 和 .dsw 是 VC6 的產物,在 VS.net2002 (使用 .NET Framework)之後就改成 .vcproj 和 .sln 了,然而我的 IDE 是 visual studio 2008 (VC9),所以根本就不會有 .dsp 和 .dsw 存在。

.vcproj : VisualC++ Project (就是以前的 .dsp)

.sln : Microsoft Visual Studio Solution (就是以前的 .dsw)


再來探討 Visual Studio 與 .net 的關係。

VS 是一個 IDE (Integrated Development Environment) 或稱開發工具,提供 C/C++、C#、java...等開發程式的環境;而 .net 是一個 framework (軟體開發平台)1000px-Common_Language_Runtime_diagram.svg所有的編譯程序(從 Bytecode 到 Nativeode )都要在這平台下做運算,以一種系統虛擬機運行的編程平台,有點像是 java 的 Java Virtual Machine,對程式語言開發的程序做的編程動作。每一代的 VS 也會搭配不同的 framework,增加不同的 API 或者 Library 提供更多更廣的支援與功能。

Visual Studio .NET2002(VC7.0) : 使用 .NET Framework 1.0 ,最早的 .NET 的架構,也把之前的 Visual Basic 包在 Visual Studio 裡面。

VC .NET2002 (VC7.1) : 使用 .NET Framework 1.1。

VC 2005 (VC8.0) : 使用 .NET Framework 2.0,多了 OpenMP 的功能,之後也開始支援64bit系統。

VC 2008 (VC9.0) : 使用 .NET Framework 3.5。

VC 2010 (VC10.0)

VC 2012 (VC11.0)

VC 2013 (VC12.0)


編譯與執行程序:

未命名


reference : wiki

 

 

OpenCV error note

1. OpenCV Mat copy 的方法

在使用 Mat 複製時,特別要注意到不能直接把等號打上,cv::Mat 會認為是另外一個Mat的參考,表示說兩個 Mat 都是指向同一組數據。因此,要 Copy Mat 的話要用 copyTo 或是 clone 這兩種方式來實現。

example :

cv::Mat img1 = cv::imread("123.bmp");

cv::Mat img2 = img1; // "warning" 沒有數據拷貝

cv::Mat img3 = img1.clone(); // 有數據拷貝

cv::Mat img4;

img1.copyTo( img4 ); //有數據拷貝

今天就是犯了這樣一個大錯誤,害我花了很多時間 debug 。


reference : http://blog.csdn.net/jianguo_cui/article/details/7387169



2. release Mat error

上禮拜在做 Mat reread的動作時,在 debug mode 的狀態下,程式可以正常運作,但換到 release mode 時,Mat 經過 release() 後再 imread 時,程式出現“堆疊損毀”的錯誤訊息。Google 後發現問題是在於函式在呼叫的過程中,所有的變數、參考及回傳位置都是存放在堆疊底下的,然而 debug 下堆疊的存取是透過暫存器儲存的位址來實現;而 release 下,將暫存器(EBP)最佳化而省略了堆疊位址的指標,因此在存取堆疊時,容易造成回傳位址錯誤,而使堆疊損毀。

解決方法:

在 Mat release 前將 refcount = 0,即可避免發生錯誤。

Mat img = imread("a.bmp",1);
img.refcount = 0;
img.release();
img = imread("b.bmp",1); // re-read an image

另外,如果是從 Iplimage 定義一個 Mat 的情況下,則要用 deallocated() 函式來釋放分配記憶體。


reference : 

http://stackoverflow.com/questions/15873617/cvmats-release-method

http://stackoverflow.com/questions/11156019/opencv-mixing-iplimage-with-cvmat

https://kevincg.wordpress.com/2006/04/19/release


3. save mat suggestion

在寫回 Mat1b 的圖檔時,記得要存成 .bmp 格式,這樣在 photoshop 讀出來的值才會正確。如果今天轉存為 .png 格式,原本 intensity 為 28,在 photoshop 上看到的值會變成 20。

 

Post source code on WordPress

https://en.support.wordpress.com/code/posting-source-code/
這篇很明確的講解如何要把source code貼在Wordpress上,只要加上以下的tag
[ code language="css"]
your code
[ /code]

""內就輸入你程式碼格式(css,cpp,java,html....)在上方的聯結都可以查詢。

當初以為這功能是wordpress內建的,直接打上tags可以使用了,沒想到還要掛上一個plugin才能使用...這plugin就是:

SyntaxHighlighter Evolved

在Wordpress的Plugins內搜尋SyntaxHighlighter Evolved,

未命名

就是他囉,按下install後,就可以開始使用了。

int a = 2;
printf("a = %d\n", a);
double b = 1.23;
printf("b = %f\n", b);
char c = "Hello World!!!";
printf("c = %s\n", c); 

注意 [ code language=”css”]和[/code]內,除了code與language之間有空格外,其他地方都不能有空格喔。


Configuration Parameters

  • autolinks(true/false) :: default true。使所有 URL 都可以被點擊的。
  • collapse(true/false) :: default false。如果是 true 的話 post code 將會被縮成一行,適合用於大型的 code post 。
  • [ code language ="cpp" collapse="true"]

    int a = 2;
    printf("a = %d\n", a);
    double b = 1.23;
    printf("b = %f\n", b);
    char c = "Hello World!!!";
    printf("c = %s\n", c); 
  • firstline(number) :: default 1。決定你 post code 左邊的行號。
  • [ code language ="cpp" firstline="23"]

    int a = 2;
    printf("a = %d\n", a);
    double b = 1.23;
    printf("b = %f\n", b);
    char c = "Hello World!!!";
    printf("c = %s\n", c); 
  • gutter(true/false) :: default true。左側的行號是否不被隱藏。
  • [ code language ="cpp" gutter="false"]

    int a = 2;
    printf("a = %d\n", a);
    double b = 1.23;
    printf("b = %f\n", b);
    char c = "Hello World!!!";
    printf("c = %s\n", c); 
  • highlight(list of numbers) :: 列出想被凸顯的行。
  • [ code language ="cpp" highlight="2,4,6"]

    int a = 2;
    printf("a = %d\n", a);
    double b = 1.23;
    printf("b = %f\n", b);
    char c = "Hello World!!!";
    printf("c = %s\n", c); 
  • htmlscript(true/false) :: default false。當混合使用程式語言時( ex. HTML mixed with PHP),決定是否凸顯 HTML/XML。
  • light(true/false) :: default false。決定行號與工具列是否被隱藏。
  • padlinenumbers(true/false/integer) :: default false。決定秀出的行號是否補零對齊;或者可以指定行號秀出來的位數,如果設定 "4",則行號會顯示 0001、0002...
  • [ code language ="cpp" padlinenumbers="4"]

    int a = 2;
    printf("a = %d\n", a);
    double b = 1.23;
    printf("b = %f\n", b);
    char c = "Hello World!!!";
    printf("c = %s\n", c); 
  • title(string) :: 設定 post code 的標題名稱,通常可以與 collapse 一起使用。
  • [ code language ="cpp" collapse="true" title="SourceCode"]

    int a = 2;
    printf("a = %d\n", a);
    double b = 1.23;
    printf("b = %f\n", b);
    char c = "Hello World!!!";
    printf("c = %s\n", c); 

    reference : https://en.support.wordpress.com/code/posting-source-code/