2014年1月21日 星期二

[物件導向] 多型 觀念

多型(Polymorphism)

【多型】(多行為),一般指【子類別多型】(Subtype Polymorphism)

子類別,來自同樣父類別的〝行為〞[method],可以有不同響應

ex:
動物 [class] 。。。有。。。  叫() [method]

 雞 [class] 。。。會。。。 啼叫() [method]
 狗 [class] 。。。會。。。 吠叫() [method]

稱之為多型

2014年1月20日 星期一

[物件導向] 物件導向基礎複習 類別~


先不管封裝,皆先用public...

術語

  英文 
  
 中文  類似概念  舉例
 class   類別  類別:請視為→設計圖
或看成→自訂的型別
(下定義、分門別類)
 
ex:定義"人 "類別..
  
  
 property   屬性   名詞
語法似C語言的變數

人有:
性別,生日,身高,體重,...

 method   方法 
 動詞
也有翻譯成:行為
語法似C語言的function
人會:
跑,跳,吃,喝,...

 object 
  
 物件   屬於該類別的實體物
張三,李四,志明,春嬌,...


新增類別step:
方案總管:專案圖示上點右鍵

[加入]->[新增項目]->[類別](取名)


新增 Student 類別後,則出現 Student.cs 檔案
先來設計、撰寫 Student 類別,撰寫它的屬性與方法
Student.cs 添加以下內容
namespace example
{
    class Student
    {
        // Property 屬性
        public int grade; // 幾年級
        public string name; // 姓名

        // Method 方法
        public string Say() // 說:自我介紹
        {
            return "我叫" + name + ",我是" + grade + "年級";
        }

        public string Talk(Student s) // 有輸入:Student
        {
            return grade + "年級的" + name + "對" + s.name + "說早安~";
        }

        public void Upgrade() // 升高一個年級
        {
            grade++;
        }
    }
}


Form1.cs 按鈕按下,測試 method
namespace example
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Student s1 = new Student(); // 新增物件
            s1.grade = 1;               // 設定屬性
            s1.name = "張三";
            Student s2 = new Student();
            s2.grade = 2;
            s2.name = "李四";

            // 方法測試1
            MessageBox.Show(s1.Say());
            MessageBox.Show(s1.Talk(s2));

            // 方法測試2
            MessageBox.Show(s1.Say());
            s1.Upgrade();
            MessageBox.Show(s1.Say());
        }
    }
}



新增物件語法:
Student s1 = new Student();
 類別 物件 = new 類別();

存取物件的屬性、
使用物件的方法:
在object(物件)後面加小數點,
來存取物件的 property(屬性) 跟 method(方法)。

2014年1月18日 星期六

[C#] 第一個 WinForm 教學

寫第一個 Windows Form 程式
練習 textbox 字串轉換數字 & 檢查

敘述:
在textbox輸入考試分數,按下button看反應

------------------------------------------------

步驟如下:
1。在選單選[檔案(F)]→[新增專案(P)...]→[Windows Form應用程式]
2。輸入專案名稱:[WinFormEX1]後→按[確定]
3。左邊[工具箱]中拉一個[textbox]元件與一個[button]元件到form1上
4。滑鼠[雙擊buton元件],會自動生成以下程式碼於Form1.cs

 private void button1_Click(object sender, EventArgs e)
{
    在這撰寫按了button後想要執行的程式..
}

5。程式碼參考..

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WinFormEX1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int score;
            if (!int.TryParse(textBox1.Text, out score)) //把字串轉換為int,傳值給score
            {
                //若轉換失敗,會傳 0 給score
                textBox1.Text = "0"; // 把畫面也更新為0
            }

            if (score < 100 && score >= 0)//輸入的數值介於 0~100之間
            {
                MessageBox.Show("你要被打" + (100 - score) + "下屁股");
            }
            else if (score < 0 || score > 100)//輸入值 大於100 或 小於 0
            {
                MessageBox.Show("小小年紀就說謊,看我不打死你才怪");
            }
            else//只有100分會執行這個條件
            {
                MessageBox.Show("恭喜你,滿分不用被打屁股");
            }
        }
    }
}


6。按下[F5]執行成果

------------------------------------------------

7。其他額外練習:將按下Enter預設執行的button指定為button1

滑鼠[雙擊Form1表單],
自動生成 private void Form1_Load(object sender, EventArgs e)
寫入下面這行程式碼

this.AcceptButton = button1; // 按Enter預設執行的button指定為button1


2014年1月17日 星期五

[C#] Hello World


[新增專案]->[主控台應用程式]

// 以下自動生成,只要手寫兩行秀字&讀key

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



namespace HelloWorld // 依專案名稱

{

    class Program

    {

        static void Main(string[] args)

        {

            // 兩行解決

            Console.WriteLine("Hello World");

            Console.ReadKey();

        }

    }

}

2014年1月16日 星期四

syntaxhighlighter - blog程式碼排版

插入語法


brush:.....<-顯示語言


<pre class="brush:csharp">
... 呈現的程式碼,放置於此 ...
</pre>

================================================


在blogger上使用..

找到[編輯Html]按鈕(在範本分頁下)
插入以下code,可在最後</body></html>的前面

------------------------------------------------

<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shCore.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushCSharp.js"></script>

<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/3.0.83/styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/3.0.83/styles/shThemeDefault.css" id="shTheme"/>

<script type="text/javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>

------------------------------------------------
這是使用外部資源連結(官網資源)..
------------------------------------------------
以下是可支援語言..

Brush name Brush aliases File name
Bash/shell bash, shell shBrushBash.js
C# c-sharp, csharp shBrushCSharp.js
C++ cpp, c shBrushCpp.js
CSS css shBrushCss.js
Delpi delphi, pas, pascal shBrushDelphi.js
Diff diff, patch shBrushDiff.js
Groovy groovy shBrushGroovy.js
JavaScript js, jscript, javascript shBrushJScript.js
Java java shBrushJava.js
Perl perl, pl shBrushPerl.js
PHP php shBrushPhp.js
Plain Text plain, text shBrushPlain.js
Python py, python shBrushPython.js
Ruby rails, ror, ruby shBrushRuby.js
Scala scala shBrushScala.js
SQL sql shBrushSql.js
Visual Basic vb, vbnet shBrushVb.js
XML xml, xhtml, xslt, html, xhtml shBrushXml.js

2012年12月9日 星期日

C語言:結構的宣告&定義


struct

結構 / 結構體


struct 其實就是使用者自訂型態。(利用基本型態再組合成一個自訂型態)

struct sName;  //結構宣告

結構宣告:只是宣告存在一個叫做 sName 的 struct
還沒有表明 struct 具體內容長得如何

struct sName {  //結構定義
    int i;
    double d;
    char c;
};

結構定義:表明了 struct 的具體內容、具體結構
但是尚未分配記憶體空間

定義好了 struct ,就可以把它當成一個型態來使用,例如:
int var1;
struct sName var2; //定義實體var2
struct sName array1[10];
struct sName *ptr;

可以把「struct sName」看成是一種型態
此時系統才會分配記憶體空間
我們把分配了記憶體空間的這些,例如:var2、array1 通稱為「實體」






如果把結構定義寫在.c

我們把變數和函式的宣告寫在.h檔,定義寫在.c檔
可是結構的定義卻建議寫在.h檔,為什麼?
寫在.c檔也可以啦,但是你在每個用到結構的.c都要寫一份結構定義,否則是編譯不會過的

s.h
//s.h
struct s;     //結構宣告

extern struct s entity;  //結構實體宣告

s.c
//s.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

struct s entity;     //定義了結構實體

source1.c
//source1.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

void function1(void)
{
    entity.integer = 1;
  //需要結構定義
    return;
}


source2.c
//source2.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

void function2(void)
{
    entity.integer = 2; //需要結構定義
    return;
}


source3.c
//source3.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

void function3(void)
{
    entity.integer = 3; //需要結構定義
    return;
}



用到 struct 都要寫一份同樣的結構定義,將來若要修改這個 struct 要一個一個改,若漏掉沒改到 struct 就不一致了,將產生問題









【標題】結構的定義寫在 .h 要注意:
先說在一個.c檔內 struct 定義也必須是唯一的。
所以例如試試看 struct s { int i }; 寫兩次,編譯是不會過的。
// file.c
struct s { int i };
struct s { int i }; //重複定義

為了避免寫在 .h 檔以後,經過多重的引用以後可能出現"重複定義"的錯誤,
我們使用稱為 header guard 的寫法
,把它加上巨集防範 (#include 防範)

// file.h
#ifndef _FILE_H_
#define _FILE_H_
 內容
 。
 。
 。
#endif

_FILE_H_ 必須確保此名稱是『唯一的』,名稱重複就沒救了,所以我們常用檔名加底線做為唯一名稱
ifndef 意思是 if not define 如果沒定義過 _FILE_H_,也就是第一次碰到就做中間的內容,第二次再碰到就會跳過不做,就樣就可以避免重複定義






完整 struct 寫法

// s.h
#ifndef _S_H_
#define _S_H_

struct s {
     // 結構定義寫在 .h 檔
    int integer;
    float f; 
};

extern struct s entity;  // entity實體宣告

#endif


// s.c
#include "s.h"

struct s entity;  // entity實體定義 (為entity分配空間)


// file.c
#include "s.h"
#include <stdio.h>

void function( void )
{
    entity.integer = 123;
    printf("i=%d\n", entity.integer);
    return;
}

.........
參考

http://stackoverflow.com/questions/6316987/should-struct-definitions-go-in-h-or-c-file

2012年12月8日 星期六

C陷阱: extern & static & 多檔案、宣告、定義、變數、函式


宣告&定義 ( Declarations & Definitions )

將[宣告]與[定義]的細微不同分辨清楚,不混淆
https://en.wikipedia.org/wiki/Declaration_(computer_programming)

語法;寫法:

全局變數
函式
宣告 extern int i;
void function( void );
或 extern void function( void );
定義 int i; void function( void ) { ...內容... }
  函式宣告 extern 關鍵字可以省略


編譯器行為 compiler behavior:

宣告變數 只告知 compiler 變數的存在,和告知變數的型態。
定義變數 叫 compiler 為變數分配儲存空間。
(當然也得知變數的存在與型態)






若程式只有一個檔案


金句:當程式只有一個檔案,變數就用定義就夠了。
   不需要使用到變數宣告。


變數與函式,使用前必須先定義,而且也只能定義這唯一的一次。
(分配儲存空間當然只能唯一的一次)

正確
// file.c
int main( void )
{
    int var = 1; // 定義,並且設定初始值
    var++; // 將var變數值+1
    return 0;
}


錯誤:未定義
// file.c
int main( void )
{
    var++; // compiler 未分配  var 空間
    return 0;
}


錯誤:重複定義
// file.c
int main( void )
{
    int var = 1; // 定義
    int var = 1; // 重複定義
    var++;
    return 0;
}






若程式有多個檔案

當程式是多個檔案,才有使用宣告的必要。

現代習慣做法,原則為:
『把宣告寫在.h檔,把定義寫在.c檔』

若沒按照這個原則,在.h檔裡放了定義,
當某.h檔有多個.c檔去 include它,就會產生重複定義的錯誤。


可以宣告很多次,但定義必須是唯一的!
(記得宣告只是得知變數的存在與型態,所以可以宣告很多次)
(定義還會分配儲存空間,當然只能唯一的一次)
多檔案(multiple files)下的宣告,編譯器會自動從所有檔案中尋找它的定義。




var.h
// var.h
extern int globalVar; // 變數宣告

void function( void ); // 函式宣告

var.c
// var.c
#include "var.h"
#include <stdio.h>

int globalVar = 1; // 變數定義,並且設定初始值

void function( void ) // 函式定義
{
    printf("Variable is : %d\n", globalVar);
}

file.c
// file.c
#include "var.h" // 只要 include .h檔的宣告,
        // 即可使用定義在其他檔案的全局變數

int main( void )
{
    globalVar++;
    function();
    return 0;
}






請在定義變數時,設定初始值!

定義變數,沒有設定初始值,其值是無法保證的。
#include <stdio.h>
int main( void )
{
    int sum;  // 沒有設定初始值
    for( int i = 0 ; i < 5 ; i++ )
        sum++;  // 無法保證數值是什麼
    function( );
    return 0;
}

註:全局變數初始值


不要在宣告變數時,設定初始值!

※在宣告變數的同時設定初始值,會轉變成定義。

例如:extern int i=1; 是定義,不要這樣寫,容易混淆視聽..
請拆開來
..

.h
extern int i; //宣告 i,寫在.h檔

.c
int i = 1; //定義 i,此時設定初始值,寫在.c檔





全局變數&局部變數

全局變數(Global Variable):定義在函式之外的變數。
局部變數(Local Variable):定義在大括號 { } 之內的變數。

int global_var;    //全局變數:生命週期直到程式結束,而且跨檔案共享

int main( void )
{
    int block_var;    //局部變數:生命週期在大括號 { } 之間
    return 0;
}







static

static 變數 & static 函式


static:是〝私有化〞的概念

static 表示其:
1.存取的範圍:只在定義的文件檔內,不具跨文件檔共享。
2.生命週期:直到程式結束,才會從記憶體消逝。

現在習慣應用在,模組化的程式!
把大的程式,拆解為功能獨立的小程式,各自寫在不同的.c檔內。
將只有在模組用到的變數&函式設為 static,讓這些 static 只在模組內的.c檔使用。

定義 static 的寫法:
static通常寫在.c檔 
static int i;
static void function( void ) { ..........內容.......... }

思考:
若想要宣告static在.h檔,則所有include了.h的.c檔都會產生static,
必須思考目的為何?是否為想要的效果,be careful。

變數的儲存週期
https://www.ptt.cc/bbs/b97902HW/M.1226692638.A.F2B.html



struct;結構

struct 結構的[宣告]與[定義]

struct S; // declares S
struct S { int a; int b; }; // defines S, S::a, and S::b

私用的 private struct

// s.c
#include <stdio.h>

struct justInFile {     // 結構定義
    int integer;
    float f; 
};

struct justInFile entity;  // 這裡才做出實體entity,分配空間

void function( void )
{
    printf("i=%d\n", entity.integer);
    return;
}


不跨檔案使用的、私用的 struct definition 應該寫在 .c 檔,這很正常
但是跨檔案使用的、公開的 struct definition 建議寫在 .h 檔。why?
思路寫在另一篇
http://ashinzzz.blogspot.tw/2012/12/struct-declaration.html






。


int a;只能定義一次?
int a;
暫時定義?

重複寫定義,到底?    暫時定義是不會配置記憶體空間的???
參考
神人http://hsian-studio.blogspot.tw/2008/09/blog-post_126.html
神整理http://www.ptt.cc/bbs/C_and_CPP/M.1315949529.A.DD0.html
錯誤http://libai.math.ncu.edu.tw/bcc16/C/C/b-9.shtml