C#網絡應用編程基礎練習題與答案(轉載)

C#網絡應用編程基礎練習題與答案
1. C/S結構模式與B/S結構模式的主要區別是什麼? 
【解答】 
首先,在系統的性能方面。只要擁有可上網的瀏覽器,就可以使用B/S系統。不過,B/S結構的客戶端只能完成瀏覽、查詢、數據輸入等簡單功能,絕大部分工作要由服務器承擔,這就對服務器提出了很高的要求,無形中增加了用戶在這一方面的投入。採用C/S結構時,客戶端和服務器都承擔部分工作,有效利用了客戶端和服務器端的資源,使用戶不必在硬件上有更多的投入。另外,瀏覽器頁面不便於修改,這爲用戶定製自己的文件時帶來了不便,比如用戶想自定義一個報表,用B/S結構的系統就比較難完成。 
其次,在系統的開發方面,C/S結構的開發對開發者提出了較高的要求,整個開發過程比較複雜。與B/S結構相比,C/S技術的歷史更爲“悠久”,從技術成熟度和開發人員普遍掌握的水平來看更爲成熟。 
第三,系統升級方面。C/S結構中若有某一模塊發生改變,可能要關聯到其它模塊的變動,使系統升級的成本較大;而B/S結構在開發、維護階段幾乎所有的工作都集中在服務器端,只需更新服務器端的軟件就可以了。如果系統升級比較頻繁,那麼B/S架構的產品就具有維護工作量少的優勢。 
第四,安全性方面。在安全性上,B/S結構則略顯不足,畢竟現在網絡安全係數不高,只要擁有密碼,任何人都可以進入到用戶的系統中;而C/S結構由於需要特定的客戶端軟件,並且一般來說都要對客戶端加密,甚至可以限定只有某一臺計算機可以使用這個客戶端,因而對安全性有更多的保障。 
2. 可以用C#編寫哪些類型的應用程序? 
【解答】 
1) 控制檯應用程序。 
2) Windows應用程序。 
3) 水晶報表應用程序。 
4) ASP.NET Web應用程序。 
5) ASP.NET Web服務應用程序。 
6) ASP.NET 水晶報表Web應用程序。 
7) 智能設備應用程序。 
3. 什麼是命名空間?命名空間和類庫的關係是什麼? 
【解答】 
1) 名稱空間是對類的一種邏輯上的分組,即將類按照某種關係或聯繫劃分到不同的名稱空間下。 
2) 名稱空間又可以包含其它的名稱空間,例如System.Windows.Forms,是指System名稱空間下有Windows名稱空間,Windows名稱空間下有Forms名稱空間。 
3) 所有類庫都在規定的名稱空間下。 
1. C#支持的數據類型有那些?與C++相比有哪些特點? 
【解答】 
C#支持的數據類型有: 
(1) 值類型 
包括:簡單類型、結構類型、枚舉類型。其中,簡單類型又分爲:整型、布爾型、字符型、浮點型、小數型。 
(2) 引用類型 
包括:對象類型、類類型、接口、元數據、字符串類型、數組。 
與C++相比,C#的主要特點有: 
1) C#語言自C/C++演變而來。但是,它是完全按照面向對象的思想來設計的,並保證了類型的安全性。 
2) C#簡化了C++在類、名稱空間、方法重載和異常處理等方面的使用。摒棄了C++的複雜性,使它更易用、更少出錯。 
3) C#減少了C++的一些特性,不再有宏、多重繼承。特別對企業開發者來說,上述功能只會產生更多的麻煩而不是效益。 
4) C#採用嚴格的類型安全、版本控制、垃圾收集(garbage collect)等等。所有的這些功能的目標都是瞄準了開發面向組件的軟件開發。 
5) C#中不再有“::”、“.”、和“->”操作符,僅使用單個操作符“.”。 
6) C#使用統一的類型系統,摒棄了C++多變的類型系統。 
7) 在C#中,不能在類的外部定義全局函數、變量或者是常量等。所有的東西都必須封裝在類中,包括實例成員或靜態成員。從而使C#代碼更加易讀且有助於減少潛在的命名衝突。 
8) 在C#中,不能使用沒有初始化的變量。從而避免了由於使用不經初始化的變量而導致的計算結果錯誤。 
2. C#語言中,值類型和引用類型有何不同? 
【解答】 
值類型和引用類型的區別在於,值類型的變量直接存放實際的數據,而引用類型的變量存放的則是數據的地址,即對象的引用。 
值類型變量直接把變量的值保存在堆棧中,引用類型的變量把實際數據的地址保存在堆棧中,而實際數據則保存在堆中。注意,堆和堆棧是兩個不同的概念,在內存中的存儲位置也不相同,堆一般用於存儲可變長度的數據,如字符串類型;而堆棧則用於存儲固定長度的數據,如整型類型的數據int(每個int變量佔用四個字節)。由數據存儲的位置可以得知,當把一個值變量賦給另一個值變量時,會在堆棧中保存兩個完全相同的值;而把一個引用變量賦給另一個引用變量,則會在堆棧中保存對同一個堆位置的兩個引用,即在堆棧中保存的是同一個堆的地址。在進行數據操作時,對於值類型,由於每個變量都有自己的值,因此對一個變量的操作不會影響到其它變量;對於引用類型的變量,對一個變量的數據進行操作就是對這個變量在堆中的數據進行操作,如果兩個引用類型的變量引用同一個對象,實際含義就是它們在堆棧中保存的堆的地址相同,因此對一個變量的操作就會影響到引用同一個對象的另一個變量。 
3. 結構和類的區別是什麼? 
【解答】 
1) 結構是一個值類型,保存在棧上,而類是一個引用類型,保存在受管制的堆上。 
2) 對結構中的數據進行操作比對類或對象中的數據進行操作速度要快。 
3) 一般用結構存儲多種類型的數據,當創建一個很多類或對象共用的小型對象時,使用結構效率更高。 
4. C#中的數組類型有何特點? 
【解答】 
1) 數組一般用於存儲同一種類型的數據,包括Object類型。 
2) 數組是一種引用類型,而不是值類型。 
3) C#中除了可以有一維數組、多維數組外,還有交錯型數組。 
5. C#中不同整型之間進行轉換的原則是什麼? 
【解答】 
在整型之間進行轉換時,小範圍類型可以隱式轉換爲大範圍類型,但大範圍類型轉換爲小範圍類型時需要使用顯式轉換。 
6. 簡述裝箱和拆箱的過程。 
【解答】 
裝箱是將值類型隱式地轉換爲object類型或者轉換爲由該值類型實現了的接口類型。裝箱一個數值會爲其分配一個對象實例,並把該數值拷貝到新對象中。拆箱是顯式地把object類型轉換成值類型,或者把值類型實現了的接口類型轉換成該值類型。 
7. 下列寫法哪些是錯誤的?爲什麼? 
1) if (nMyValue1=5) i=1; 
2) if(nMyValue2==1)i=1; 
3) int[] myInt={1,2,3}; 
foreach(int test in myInt) 

test++; 
Console.WriteLine(temp); 

4) int[] myInt1={1,2,3}; 
foreach(int test in myInt1) 

Console>WriteLine(test); 

【解答】 
1) 錯誤。if中的條件表達式結果不是布爾型。 
2) 正確。 
3) 錯誤一:temp沒有定義。 
錯誤二:在foreach塊內,test作爲枚舉成員是隻讀的,不能使用test++修改其值。 
4) 錯誤。Console後應該是點,而不應該是大於號。 
8. 錯誤和異常有什麼區別,爲什麼要進行異常處理,用於異常處理的語句有哪些? 
【解答】 
錯誤是指在執行代碼過程中發生的事件,它中斷或干擾代碼的正常流程並創建異常對象。當錯誤中斷流程時,該程序將嘗試尋找異常處理程序(一段告訴程序如何對錯誤做出響應的代碼),以幫助程序恢復流程。換句話說,錯誤是一個事件,而異常是該事件創建的對象。 
當使用短語“產生異常”時,表示存在問題的方法發生錯誤,並創建異常對象(包含該錯誤的信息及發生的時間和位置)來響應該錯誤。導致出現錯誤和隨後異常的因素包括用戶錯誤、資源失敗和編程邏輯失敗。這些錯誤與代碼實現特定任務的方法有關,而與該任務的目的無關。 
如果不進行異常處理,即不對錯誤做出響應,程序的健壯性就會大打折扣,甚至無法保證正常運行,所以必須要進行異常處理。 
用於異常處理的語句有:try-catch語句、try-catch-finally語句、throw語句。 
9.
編寫一個控制檯應用程序,輸出1到5的平方值,要求: 
1) 用for語句實現。 
2) 用while語句實現。 
3) 用do-while語句實現。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.Text;  
namespace outputSquareValue  
{  
class Program  
{  
static void Main()  
{  
//用for語句實現  
for (int i = 1; i <= 5; i++)  
{  
Console.WriteLine("{0}的平方值爲{1}", i, i * i);  
}  
//用while語句實現  
int j = 0;  
while (j++ < 5)  
{  
Console.WriteLine("{0}的平方值爲{1}", j, j * j);  
}  
//用do-while語句實現  
int k = 1;  
do  
{  
Console.WriteLine("{0}的平方值爲{1}", k, k * k);  
} while (k++ < 5);  
Console.ReadLine();  
}  
}  

10. 編寫一個控制檯應用程序,要求用戶輸入5個大寫字母,如果用戶輸入的信息不滿足要求,提示幫助信息並要求重新輸入。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.Text;  
namespace inputCapitalLetter  
{  
class Program  
{  
static void Main()  
{  
bool ok = false;  
while (ok == false)  
{  
Console.Write("請輸入5個大寫字母:");  
string str = Console.ReadLine();  
if (str.Length != 5)  
{  
Console.WriteLine("你輸入的字符個數不是5個,請重新輸入。");  
}  
else  
{  
ok = true;  
for (int i = 0; i < 5; i++)  
{  
char c = str[i];  
if (c < 'A' || c > 'Z')  
{  
Console.WriteLine("第{0}個字符“{1}”不是大寫字母,請重新輸入。", i + 1, c);  
ok = false;  
break;  
}  
}  
}  
}  
}  
}  

11. 編寫一個控制檯應用程序,要求完成下列功能。 
1)
接收一個整數n。 
2) 如果接收的值n爲正數,輸出1到n間的全部整數。 
3) 如果接收的值爲負值,用break或者return退出程序。 
4) 轉到(1)繼續接收下一個整數。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.Text;  
namespace testOutput  
{  
class Program  
{  
static void Main()  
{  
while (true)  
{  
Console.Write("請輸入一個整數(負值結束):");  
string str = Console.ReadLine();  
try  
{  
int i = Int32.Parse(str);  
if (i < 0) break;  
for (int j = 1; j <= i; j++) Console.WriteLine(j);  
}  
catch  
{  
Console.WriteLine("你輸入的不是數字或超出整數的表示範圍,請重新輸入");  
}  
}  
}  
}  

12. 編寫一個控制檯應用程序,求1000之內的所有“完數”。所謂“完數”是指一個數恰好等於它的所有因子之和。例如,6是完數,因爲6=1+2+3。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.Text;  
namespace completeNumber  
{  
class Program  
{  
static void Main(string[] args)  
{  
for (int i = 2; i <= 1000; i++)  
{  
int s = 1;  
string str = "1";  
for (int j = 2; j <= (int)Math.Sqrt(i); j++)  
{  
if (j * (i / j) == i)  
{  
if (j != i / j)  
{  
s += j + i / j;  
str += string.Format("+{0}+{1}", j, i / j);  
}  
else  
{  
s += j;  
str += string.Format("+{0}", j);  
}  
}  
}  
if (s == i) Console.WriteLine("{0}={1}", i, str);  
}  
Console.ReadLine();  
}  
}  
}
C#網絡應用編程基礎練習題與答案 
1. 編寫一個控制檯應用程序,完成下列功能。 
1) 創建一個類,用無參數的構造函數輸出該類的類名。 
2) 增加一個重載的構造函數,帶有一個string類型的參數,在此構造函數中將傳遞的字符串打印出來。 
3) 在Main方法中創建屬於這個類的一個對象,不傳遞參數。 
4) 在Main方法中創建屬於這個類的另一個對象,傳遞一個字符串“This is a string.”。 
5) 在Main方法中聲明類型爲這個類的一個具有5個對象的數組,但不要實際創建分配到數組裏的對象。 
6) 寫出運行程序應該輸出的結果。 
【解答】 
using System;  
class Test1  
{  
public Test1()  
{  
Console.WriteLine(this);  
}  
public Test1(string str)  
{  
Console.WriteLine(str);  
}  
public static void Main()  
{  
Test1 t1 = new Test1();  
Test1 t2 = new Test1("This is a string.");  
Test1[] t3 = new Test1[5];  
}  

輸出結果: 
Test1 
This is a string. 
2. 編寫一個控制檯應用程序,定義一個類MyClass,類中包含有public、private以及protected數據成員及方法。然後定義一個從MyClass類繼承的類MyMain,將Main方法放在MyMain中,在Main方法中創建MyClass類的一個對象,並分別訪問類中的數據成員及方法。要求註明在試圖訪問所有類成員時哪些語句會產生編譯錯誤。 
【解答】 
using System;  
class MyClass  
{  
public int i;  
private int j;  
protected int k;  
public void method1()  
{  
Console.WriteLine("public method.");  
}  
private void method2()  
{  
Console.WriteLine("private method.");  
}  
protected void method3()  
{  
Console.WriteLine("protected method.");  
}  
}  
class MyMain : MyClass  
{  
public static void Main()  
{  
MyClass t = new MyClass();  
Console.WriteLine("i={0}", t.i);  
Console.WriteLine("j={0}", t.j); //會出現編譯錯誤,私有成員不允許在其它類中訪問  
Console.WriteLine("k={0}", t.k); //會出現編譯錯誤,應該創建MyMain的對象,然  
//後通過MyMain的對象訪問  
t.method1();  
t.method2(); //會出現編譯錯誤,私有的方法不允許在其它類中調用  
t.method3(); //會出現編譯錯誤,應該創建MyMain的對象,然後通過MyMain的  
//對象調用該方法  
}  

3. 創建一個類包含有protected數據。在相同的文件裏創建第二個類,用一個方法操縱第一個類裏的protected數據。 
【解答】 
using System;  
class Class1  
{  
protected int i = 5;  
protected void MyMethod()  
{  
Console.WriteLine("protected method.");  
}  
}  
class Class2 : Class1  
{  
private void NewMethod()  
{  
Console.WriteLine(this.i);  
this.i += 10;  
Console.WriteLine(this.i);  
}  
public static void Main()  
{  
Class2 t = new Class2();  
t.NewMethod();  
}  

4. 分別寫出下列語句執行的結果。 
1) Console.WriteLine("{0}--{0:p}good",12.34F); 
2) Console.WriteLine("{0}--{0:####}good",0); 
3) Console.WriteLine("{0}--{0:00000}good",456); 
【解答】 
12.34--1,234.00%good 
0--good 
456--00456good 
5. 編寫一個控制檯應用程序,計算 
要求精度爲10-8。 
【解答】 
using System;  
class Test5  
{  
public static void Main()  
{  
int n = 50;  
double x = 3;  
double s = 0;  
double a = 1;  
for (int i = 1; i <= n; i++)  
{  
a *= i;  
s += Math.Pow(-1, i + 1) * Math.Pow(x, i) / a;  
}  
Console.WriteLine("n={0},s={1:0.00000000}", n, s);  
}  

6. 編寫一個控制檯應用程序接收一個長度大於3的字符串,完成下列功能 
1) 輸出字符串的長度。 
2) 輸出字符串中第一個出現字母a的位置。 
3) 在字符串的第3個字符後面插入子串“hello”,輸出新字符串。 
4) 將字符串“hello”替換爲“me”,輸出新字符串。 
5) 以字符“m”爲分隔符,將字符串分離,並輸出分離後的字符串。 
【解答】 
using System;  
class Test6  
{  
public static void Main()  
{  
string str = "";  
while (str.Length <= 3)  
{  
Console.Write("請輸入一個長度大於3的字符串:");  
str = Console.ReadLine();  
}  
//(1)  
Console.WriteLine("字符串的長度爲:{0}", str.Length);  
//(2)  
int i = str.IndexOf('a');  
if (i > -1)  
{  
Console.WriteLine("第一個出現字母a的位置是:{0}", i);  
}  
else  
{  
Console.WriteLine("字符串中不包含字母a。");  
}  
//(3)  
string str1 = str.Insert(3, "hello"); //在第3個(初始序號爲)字符前插入hello  
Console.WriteLine("插入hello後的結果爲:{0}", str1);  
//(4)  
string str2 = str1.Replace("hello", "me");  
Console.WriteLine("將hello替換爲me後的結果爲:{0}", str2);  
//(5)  
string[] arr = str2.Split('m');  
Console.WriteLine("以m爲分隔符分離後的字符串有:");  
for (int j = 0; j < arr.Length; j++)  
{  
Console.WriteLine(arr[j]);  
}  
}  

1. 與結構化編程方法相比,面向對象編程有哪些優點? 
【解答】 
(1) 以過程爲中心和對象爲中心的比較 
結構化編程方法是以過程爲中心的,當面對一個問題時,該方法側重於問題解決過程的層次結構。面向對象的分析和設計方法側重於對象。對象具有特定的行爲和屬性,行爲和屬性決定了對象與其他對象的交互作用方式,以及對象本身的行爲方式。 
(2) 公開數據和隱藏數據的比較 
結構化編程方法對數據和過程僅僅進行簡單的包裝,這些數據和過程是公開的,或者說程序中的其他代碼可以訪問這些數據和過程。面向對象的實現隱藏了特定的數據,並且只把對象的特定行爲公開給用戶。實現這些特定行爲的代碼對用戶來說是不可見的,用戶只能訪問這些公開的行爲。 
(3) 單一單元和標準單元的比較 
結構化編程方法是基於單一代碼單元的。面向對象的編程方法允許對象是獨立的。 
(4) 一次性使用和可重用的比較 
根據不同的實現,結構化過程可能無法重用。而面向對象的方法,對象是一個模塊單元。具有完備的實體,因此可以具有高度的可重用性。 
(5) 有序算法和無序算法的比較 
結構化編程方法所開發的程序,其結構往往是線性的(或者說是自頂向下的)。而面向對象的應用程序是一種基於消息或者事件驅動的程序類型。每個對象都可以向其他對象發送消息。Windows操作系統就是這樣的程序。 
2. 簡要回答下列問題。 
1) 舉例說明new關鍵字可用於那些方面? 
2) sealed關鍵字的作用是什麼?什麼情況下需要使用sealed關鍵字? 
3) 哪些關鍵字可以用於版本控制? 
【解答】 
1) 在C#中,new關鍵字可用作運算符或修飾符。作爲運算符用於在堆上創建對象和調用構造函數。作爲修飾符用於隱藏基類成員的繼承成員。 
2) 在類聲明中使用sealed修飾符可防止其它類繼承此類。在方法聲明中使用sealed修飾符可防止擴充類重寫此方法。 
sealed修飾符主要用於防止非有意的派生,但是它還能促使某些運行時優化。具體說來,由於密封類永遠不會有任何派生類,所以對密封類的實例的虛擬函數成員的調用可以轉換爲非虛擬調用來處理。 
3) override關鍵字和new關鍵字均可用於版本控制。 
在C#中,默認情況下方法不是虛擬的。若要使方法成爲虛擬方法,必須在基類的方法聲明中使用virtual修飾符。然後,派生類可以使用override關鍵字重寫基類中的虛擬方法,或使用new關鍵字隱藏基類中的虛擬方法。如果override關鍵字和new關鍵字均未指定,編譯器將發出警告,並且派生類中的方法將隱藏基類中的方法。 
3. 簡要回答抽象類和接口的主要區別。 
【解答】 
抽象類和接口的一個主要差別是:類可以實現多個接口,但僅能從一個抽象類或任何其它類型的類繼承。 
4. 使用委託的優點是什麼?委託和事件有什麼區別和聯繫? 
【解答】 
C#中的委託類似於C或C++中的函數指針。使用委託使程序員可以將方法引用封裝在委託對象內。然後可以將該委託對象傳遞給可調用所引用方法的代碼,而不必在編譯時知道將調用哪個方法。與C或C++中的函數指針不同,委託是面向對象,而且是類型安全的。 
C#中的“事件”是當對象發生某些事情時,類向該類的客戶提供通知的一種方法。事件最常見的用途是用於圖形用戶界面;通常,表示界面中的控件的類具有一些事件,當用戶對控件進行某些操作(如單擊某個按鈕)時,將通知這些事件。 
使用委託來聲明事件。委託對象封裝一個方法,以便可以匿名調用該方法。事件是類允許客戶爲其提供方法(事件發生時應調用這些方法)的委託的一種方法。事件發生時,將調用其客戶提供給它的委託。 
5. 編寫一個控制檯應用程序,完成下列功能,並回答提出的問題。 
1) 創建一個類A,在構造函數中輸出“A”,再創建一個類B,在構造函數中輸出“B”。 
2) 從A繼承一個名爲C的新類,並在C內創建一個成員B。不要爲C創建構造函數。 
3) 在Main方法中創建類C的一個對象,寫出運行程序後輸出的結果。 
4) 如果在C中也創建一個構造函數輸出“C”,整個程序運行的結果又是什麼? 
【解答】 
using System;  
public class A  
{  
public A()  
{  
Console.WriteLine("A");  
}  
}  
public class B  
{  
public B()  
{  
Console.WriteLine("B");  
}  
}  
public class C : A  
{  
B newb = new B();  
}  
class MainClass  
{  
public static void Main()  
{  
C newc = new C();  
Console.ReadLine();  
}  

輸出結果: 


如果在C中也創建一個構造函數輸出“C”,即添加: 
public C()  
{  
Console.WriteLine("C");  

則整個程序運行的結果爲: 



6. 編寫一個控制檯應用程序,完成下列功能,並寫出運行程序後輸出的結果。 
1) 創建一個類A,在A中編寫一個可以被重寫的帶int類型參數的方法MyMethod, 
並在該方法中輸出傳遞的整型值加10後的結果。 
2) 再創建一個類B,使其繼承自類A,然後重寫A中的MyMethod方法,將A中接 
收的整型值加50,並輸出結果。 
3) 在Main方法中分別創建類A和類B的對象,並分別調用MyMethod方法。 
【解答】 
using System;  
public class A  
{  
public virtual void MyMethod(int num)  
{  
num += 10;  
Console.WriteLine(num);  
}  
}  
public class B : A  
{  
public override void MyMethod(int num)  
{  
num += 50;  
Console.WriteLine(num);  
}  
}  
class MainClass  
{  
public static void Main()  
{  
A newa = new A();  
newa.MyMethod(2);  
B newb = new B();  
newb.MyMethod(2);  
Console.ReadLine();  
}  

輸出結果: 
12 
52 
7. 假設Node類的每一個節點包括有兩個字段:m_data(引用節點的數據)和m_next(引用鏈接列表中的下一項)。這兩個字段都是由構造函數方法設置的。該類有兩個功能,第一個功能是通過名爲Data和Next的只讀屬性訪問m_data和m_next字段。第二個功能是對System.Object的ToString虛擬方法進行重寫。試分別用類和泛型兩種方法編寫程序實現上述功能。 
【解答】 
using System;  
class Node  
{  
Object m_data;  
Node m_next;  
public Node(Object data, Node next)  
{  
m_data = data;  
m_next = next;  
}  
// 訪問結點數據  
public Object Data  
{  
get { return m_data; }  
}  
// 訪問下一個結點  
public Node Next  
{  
get { return m_next; }  
}  
// 獲取結點數據描述  
public override String ToString()  
{  
return m_data.ToString();  
}  
}  
// 鏈表結點類的泛型定義  
class Node  
{  
T m_data;  
Node m_next;  
public Node(T data, Node next)  
{  
m_data = data;  
m_next = next;  
}  
// 訪問結點數據  
public T Data  
{  
get { return m_data; }  
set { m_data = value; }  
}  
// 訪問下一個結點  
public Node Next  
{  
get { return m_next; }  
set { m_next = value; }  
}  
// 獲取結點數據描述  
public override String ToString()  
{  
return m_data.ToString();  
}  
}  
// 使用結點類型或泛型結點類型  
class LinkedList  
{  
static void Main(string[] args)  
{  
//// 創建整數鏈表  
//Node head = new Node(5, null);  
//head = new Node(10, head);  
//head = new Node(15, head);  
////遍歷鏈表求整數和  
//Int32 sum = 0;  
//for (Node current = head; current != null;  
// current = current.Next)  
//{  
// sum += (Int32)current.Data;  
//}  
//// 輸出結果  
//Console.WriteLine("Sum of nodes = {0}", sum);  
// 用泛型創建整數鏈表  
Node head = new Node(5, null);  
head = new Node(10, head);  
head = new Node(15, head);  
// 遍歷求和  
Int32 sum = 0;  
for (Node current = head; current != null;  
current = current.Next)  
{  
sum += current.Data;  
}  
// 輸出  
Console.WriteLine("Sum of nodes = {0}", sum.ToString());  
}  

#網絡應用編程基礎練習題與答案(5) 
1. 填空題 
1) 使控件是否可以對用戶交互作出響應的屬性是 Enabled 。 
2) 控制控件是否顯示的屬性是 Visible 。 
3) 若要在文本框中輸入密碼,常指定 PasswordChar 屬性。 
4) 若某複選框某時刻CheckState屬性的值爲Indeterminate,則其屬性Checked的值爲 Unchecked 。 
5) 使用 Panel 或 GroupBox 控件可以將多個RadioButton控件分爲兩個單選組。 
6) 若不希望用戶在ComboBox控件中編輯文本,則應將屬性 DropDownStyle 的屬性值設置爲DropDownList。 
7) 用於設置MenuStrip控件中某菜單項快捷鍵的屬性是 ShortcutKeys 。 
8) 用於控制ListView控件中的各項顯示方式的屬性是 View 。 
2. 判斷題 
1) 控件就是屬性、方法和事件的集合封裝體。 ( 對 ) 
2) TextBox控件只能用於單行文本的輸入。 ( 錯 ) 
3) 通過RichTextBox控件只能夠與RTF文件進行交互操作。 ( 錯 ) 
4) CheckBox控件的Checked屬性與CheckState屬性的值始終是相同的。 ( 錯 ) 
5) ToolTip組件用於顯示某指定控件的自定義提示信息的。 ( 對 ) 
3. 區別TextBox控件、MaskedTextBox控件、RichTextBox控件的使用場合。 
【解答】 
TextBox控件一般用於單段文本的編輯,可以設置爲單行或多行的輸入模式,也可以用作密碼的輸入;MaskedTextBox控件主要用於特定格式的單段文本編輯,在輸入文本不符合格式要求的將會觸發其MaskInputRejected事件;RichTextBox控件除了具有TextBox的一般文本編輯功能外,還可以進行多段文本的高級編輯功能,如改變文本、段落的顯示格式、在文本中查找特定字符和字符串以及與Rtf文件的交互等。 
4. 簡要說明CheckBox控件和RadioButton控件的區別。 
【解答】 
CheckBox控件可爲用戶提供選擇功能,常用的是二選一的選擇,如“真/假”或“是/否”;但該控件也可以通過屬性的設置作三選一的選擇。每一個CheckBox所代表的選擇都是獨立的,若有多個CheckBox控件構成一組選項時,則可以多個同時被選中,相互之間不影響,即複選。RadioButton控件,它與CheckBox控件功能類似,也是用於接收用戶的選擇,但它是以單項選擇的形式出現,即一組RadioButton按鈕中只能有一個處於選中狀態。一旦某一項被選中,則同組中其他RadioButton按鈕的選中狀態自動清除。 
5. 設計一個Windows應用程序,窗體上有一個TextBox控件、一個Button控件。要求,每當用戶單擊按鈕時,文本框都會增加一行文字來反映單擊的次數,例如“第3次單擊按鈕”。 
【解答】 
1) 窗體界面如圖Ex5-5-1所示; 
2) 窗體中主要控件屬性設置如表Ex5-5-1; 
表Ex5-5-1 窗體中的主要控件屬性 
控件 
Name屬性 
功能 
其它屬性 
TextBox控件 
textBox1 
顯示信息 
ScrollBars=Vertical; Multiline=True 
Button控件 
Button1 
觸發添加信息事件 
Button2 
觸發結束添加事件 
3) 主要事件代碼。 
……  
int i = 1;  
bool Add = true;  
……private void button1_Click(object sender, EventArgs e)  
{  
if(Add) textBox1.Text += "第" + i + "次單擊按鈕/r/n";  
i++;  
}  
private void button2_Click(object sender, EventArgs e)  
{  
Add = false;  

6. 編寫一段程序,向ListBox控件listBox1中,自動添加10個數,每個數佔一項。 
【解答】 
主要代碼如下: 
public partial class Form1 : Form  
{  
int m = 1;  
……  
private void button1_Click(object sender, EventArgs e)  
{  
for (int i = m ; i < m+10; i++)  
{  
listBox1.Items.Add(i);  
}  
m = m + 10;  
}  

7. 參照Windows系統“附件”中的“計算器”,自行編寫一個簡易的計算器。要求:可以實現由0~4構成的整數的加減運算。 
【解答】 
1) 窗體界面如圖Ex5-5-2所示; 
2) 將InputNumber事件作爲button0、button1、button2、button3、button4的Click事件。 
完整代碼如下: 
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
namespace Exer2  
{  
public partial class FormCalculator : Form  
{  
enum calculateType { none, add, sub };  
calculateType myCal = calculateType.none;  
int x, y;  
bool isY = false;  
public FormCalculator()  
{  
InitializeComponent();  
textBox.TextAlign = HorizontalAlignment.Right;  
}  
private void InputNumber(object sender, EventArgs e)  
{  
Button num = (Button)sender;  
if (isY)  
{  
textBox.Clear();  
isY = false;  
}  
textBox.Text += num.Text;  
}  
private void buttonEqual_Click(object sender, EventArgs e)  
{  
y = Convert.ToInt32(textBox.Text);  
if (myCal == calculateType.add)  
{  
textBox.Text = Convert.ToString(x + y);  
myCal = calculateType.none;  
}  
if (myCal == calculateType.sub)  
{  
textBox.Text = Convert.ToString(x - y);  
myCal = calculateType.none;  
}  
isY = true;  
}  
private void addButton_Click(object sender, EventArgs e)  
{  
myCal = calculateType.add;  
x = Convert.ToInt32(textBox.Text);  
isY = true;  
}  
private void buttonSub_Click(object sender, EventArgs e)  
{  
myCal = calculateType.sub;  
x = Convert.ToInt32(textBox.Text);  
isY = true;  
}  
private void buttonClear_Click(object sender, EventArgs e)  
{  
textBox.Text = "";  
myCal = calculateType.none;  
isY = false;  
}  
}  

8. 試利用TreeView、ListView等控件實現一個類似“資源管理器”的文檔管理程序,用於查看C:/Documents and Settings目錄下的文件。 
【解答】 
1) 新建一個名爲WindowsControlsExercise的項目,在【解決方案資源管理器】中重命名文件Form1.cs爲Explorer.cs,並設置Form1窗體的Text屬性爲“資源管理器”。 
2) 向窗體中添加一個SplitContainer控件、一個ImageList控件、一個TreeView控件、一個ListView控件,頁面佈局及各控件屬性如圖Ex5-5-3所示。 
3) 在【解決方案資源管理器】中,將imageList1控件中的兩個圖標文件添加到應用程序目錄中,分別命名爲folder.ico和doc.ico。 
4) 在Explorer.cs代碼文件中添加命名空間:using System.IO,並添加構造函數代碼如下: 
public Explorer()  
{  
InitializeComponent();  
PopulateTreeView();  
}  
private void PopulateTreeView()  
{  
TreeNode rootNode;  
DirectoryInfo info = new DirectoryInfo(@"C:/Documents and Settings");  
if (info.Exists)  
{  
rootNode = new TreeNode(info.Name);  
rootNode.Tag = info;  
GetDirectories(info.GetDirectories(), rootNode);  
treeView1.Nodes.Add(rootNode);  
}  
}  
private void GetDirectories(DirectoryInfo[] subDirs, TreeNode nodeToAddTo)  
{  
TreeNode aNode;  
DirectoryInfo[] subSubDirs;  
foreach (DirectoryInfo subDir in subDirs)  
{  
aNode = new TreeNode(subDir.Name, 0, 0);  
aNode.Tag = subDir;  
aNode.ImageKey = "folder";  
subSubDirs = subDir.GetDirectories();  
if (subSubDirs.Length != 0)  
{  
GetDirectories(subSubDirs, aNode);  
}  
nodeToAddTo.Nodes.Add(aNode);  
}  
}  
5) 添加treeView1的NodeMouseClick事件,使單擊treeView1中某個節點時,用該節點的內容來填充listView1。  
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)  
{  
TreeNode newSelected = e.Node;  
listView1.Items.Clear();  
DirectoryInfo nodeDirInfo = (DirectoryInfo)newSelected.Tag;  
ListViewItem.ListViewSubItem[] subItems;  
ListViewItem item = null;  
foreach (DirectoryInfo dir in nodeDirInfo.GetDirectories())  
{  
item = new ListViewItem(dir.Name, 0);  
subItems = new ListViewItem.ListViewSubItem[]  
{new ListViewItem.ListViewSubItem(item, "Directory"),  
new ListViewItem.ListViewSubItem(item,  
dir.LastAccessTime.ToShortDateString())};  
item.SubItems.AddRange(subItems);  
listView1.Items.Add(item);  
}  
foreach (FileInfo file in nodeDirInfo.GetFiles())  
{  
item = new ListViewItem(file.Name, 1);  
subItems = new ListViewItem.ListViewSubItem[]  
{ new ListViewItem.ListViewSubItem(item, "File"),  
new ListViewItem.ListViewSubItem(item,  
file.LastAccessTime.ToShortDateString())};  
item.SubItems.AddRange(subItems);  
listView1.Items.Add(item);  
}  
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);  

6) 按鍵編譯並執行。 
1. 簡要回答文件和流之間的區別和聯繫。 
【解答】 
文件(file)和流(stream)即有區別又有聯繫。文件是在各種媒質上(可移動磁盤、硬盤、CD 等)永久存儲的數據的有序集合。它是一種進行數據讀寫操作的基本對象。通常情況下,文件按照樹狀目錄進行組織,每個文件都有文件名、文件所在路徑、創建時間、訪問權限等屬性。 
流是字節序列的抽象概念,例如文件、輸入輸出設備、內部進程通信管道或者TCP/IP套接字等均可以看成流。流提供一種向後備存儲器寫入字節和從後備存儲器讀取字節的方式。 
2. Directory類爲我們提供了哪些目錄管理的功能,它們是通過哪些方法來實現的? 
【解答】 
Directory類爲我們提供了對磁盤和目錄進行管理的功能,如複製、移動、重命名、創建和刪除目錄,獲取和設置與目錄的創建、訪問及寫入操作相關的時間信息。 
如:CreateDirectory方法用於創建指定路徑中的所有目錄;Delete方法用於刪除指定的目錄;Move方法能夠重命名或移動目錄;Exists方法用於確定給定路徑是否引用磁盤上的現有目錄;GetCurrentDirectory方法用於獲取應用程序的當前工作目錄;GetFiles方法用於返回指定目錄中的文件的名稱等。 
3. 編寫程序綜合應用Directory類的主要方法。首先確定指定的目錄是否存在,如果存在,則刪除該目錄;如果不存在,則創建該目錄。然後,移動此目錄,在其中創建一個文件,並對文件進行計數。 
【解答】 
程序清單如下: 
using System;  
using System.IO;  
class Test  
{  
public static void Main()  
{  
string path = @"c:/MyDir";  
string target = @"c:/TestDir";  
try  
{  
if (!Directory.Exists(path))  
{  
Directory.CreateDirectory(path);  
}  
if (Directory.Exists(target))  
{  
Directory.Delete(target, true);  
}  
Directory.Move(path, target);  
File.CreateText(target + @"/myfile.txt");  
Console.WriteLine("在{0}中的文件數目是{1}",  
target, Directory.GetFiles(target).Length);  
}  
catch (Exception e)  
{  
Console.WriteLine("操作失敗: {0}", e.ToString());  
}  
finally {}  
}  

4. 編寫程序,將文件複製到指定路徑,允許改寫同名的目標文件。 
【解答】 
程序清單如下: 
using System;  
using System.IO;  
class Test  
{  
public static void Main()  
{  
string path = @"c:/temp/MyTest.txt";  
string path2 = path + "temp";  
try  
{  
using (FileStream fs = File.Create(path)) {}  
File.Delete(path2);  
File.Copy(path, path2);  
Console.WriteLine("{0}拷貝到:{1}", path, path2);  
File.Copy(path, path2, true);  
Console.WriteLine("第二次拷貝成功");  
}  
catch  
{  
Console.WriteLine("重複拷貝不允許");  
}  
}  

5. 編寫程序,使用File類實現刪除當前目錄下的所有文件。 
【解答】 
程序清單如下: 
using System;  
using System.IO;  
class FileTest  
{  
public static void Main()  
{  
Console.WriteLine("確認刪除當前目錄下的所有文件?");  
Console.WriteLine("點擊'Y'鍵繼續,其它鍵取消操作");  
int a = Console.Read();  
if(a == 'Y' || a == 'y'){  
Console.WriteLine("正在刪除文件...");  
}  
else  
{  
Console.WriteLine("用戶取消操作");  
return;  
}  
DirectoryInfo dir = new DirectoryInfo (".");  
foreach (FileInfo f in dir.GetFiles())  
{  
f.Delete();  
}  
}  

1. 解釋正則表達式 ]+)""?>(.+)各部分代表的含義。 
【解答】 此正則表達式用於匹配源文件中類似於搜狐新聞的字符串,各部分表示的含義爲: 
/s+ 一個或多個空白字符 
href 後接 HTML 定位點中的確切文本 
/s* 零個或多個空白字符 
= 後接 HTML 定位點中的確切文本 
/s* 零個或多個空白字符 
""? 零或無引號(轉義的) 
( 定義子字符串(定位點 URL)的組的起始點。 
[^"" >]+ 任意字符的一個或多個匹配項,括號中的字符除外。 
) 定義子字符串的第一組的結束 
""? 零或無引號(轉義的) 
> 後接 HTML 定位點中的確切文本 
(.+) 與任意字符(定位點文本)匹配的組。 
結束 HTML 定位點的確切文本 
2. 下面是檢查輸入字符串是否爲有效的電子郵件的正則表達式: 
^([/w-]+/.)*?[/w-]+@[/w-]+/.([/w-]+/.)*?[/w]+$ 
試解釋各部分的含義。 
【解答】 
[/w-]+ 
一個或多個任意字符(a-z、A-Z、0-9 以及下劃線)或短劃線。在@字符兩邊,確保地址形式爲name@domainname。 
/. 
一個轉義點號。(不帶反斜槓,一個點號與除換行符外的任意單個字符匹配。)以此確保域名中至少有一個點號。 
*? 
對前面的表達式,非貪婪(non-greedy,即最小)地查找零次或多次匹配。 
([/w-]+/.)*? 
以上三個表達式的組合: 
對於包含一個或多個任意字符(a-z、A-Z、0-9 以及下劃線)或短劃線並且後面只跟一個點號的表達式,非貪婪地查找零次或多次匹配。 
3. 寫出符合下列要求的正則表達式: 
1) 要求4-8個英文字母。 
2) 不能包含字母,至少1個字符。 
3) 至少3個數字。 
4) 至少3個字符。 
5) 至少3個英文字母。 
6) 任意字符。 
7) 3個字母或數字,如123,r3a等。 
8) 3個點。 
9) @前至少有1個字符,@後至少有3個字符。 
10) 必須輸入左括號。 
【解答】 
1) [a-zA-Z]{4,8} 
2) [^a-zA-Z]{1,} 
3) [0-9]{3,} 
4) {3,} 
5) [a-zA-Z]{3,} 
6) .{0,} 
7) [A-Za-z0-9]{3} 
8) /.{3} 
9) .{1,}@ .{3,} 
10) /( 
C#網絡應用編程基礎練習題與答案(8) 
1. 使用保持連接的方式編寫程序,計算各年級平均成績,並顯示結果。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
using System.Data.SqlClient;  
namespace 習題8_6_1  
{  
public partial class Form1 : Form  
{  
public Form1()  
{  
InitializeComponent();  
}  
//添加Button按鈕在ListBox中顯示結果  
private void button1_Click(object sender, EventArgs e)  
{  
listBox1.Items.Add("年級 平均成績");  
string connectionString = Properties.Settings.Default.MyDatabaseConnectionString;  
//根據連接字符串創建SqlConnection實例  
SqlConnection conn = new SqlConnection(connectionString);  
//創建SqlCommand實例,並設置SQL語句和使用的連接實例  
SqlCommand cmd = new SqlCommand();  
cmd.CommandText = "select substring(學號,1,2) as 年級,avg(成績) as 平均成績 from MyTable2 group by substring(學號,1,2)";  
cmd.Connection = conn;  
try  
{  
conn.Open();  
SqlDataReader r = cmd.ExecuteReader();  
while (r.Read() == true)  
{  
listBox1.Items.Add(string.Format("{0}級 {1}", r[0], r[1]));  
}  
r.Close();  
}  
catch (Exception err)  
{  
MessageBox.Show(err.Message, "計算成績失敗");  
}  
finally  
{  
conn.Close();  
}  
}  
}  

2. 使用保持連接的方式編寫程序,查詢MyTable2中不及格學生的學號,姓名,性別,成績。並將結果在ListBox中顯示出來。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
using System.Data.SqlClient;  
namespace 習題8_6_2  
{  
public partial class Form1 : Form  
{  
public Form1()  
{  
InitializeComponent();  
}  
private void button1_Click(object sender, EventArgs e)  
{  
listBox1.Items.Add(" 學號 姓名 性別 成績");  
string connectionString = Properties.Settings.Default.MyDatabaseConnectionString;  
//根據連接字符串創建SqlConnection實例  
SqlConnection conn = new SqlConnection(connectionString);  
//創建SqlCommand實例,並設置SQL語句和使用的連接實例  
SqlCommand cmd = new SqlCommand();  
cmd.CommandText =  
"Select 學號,姓名,性別, 成績 From MyTable2 Where (成績<60)";  
cmd.Connection = conn;  
try  
{  
conn.Open();  
SqlDataReader r = cmd.ExecuteReader();  
while (r.Read() == true)  
{  
listBox1.Items.Add( string.Format("{0} {1} {2} {3}", r[0], r[1], r[2], r[3]));  
}  
r.Close();  
}  
catch (Exception err)  
{  
MessageBox.Show(err.Message, "查詢成績失敗");  
}  
finally  
{  
conn.Close();  
}  
}  
}  

3. 編寫程序,以“[編碼]名稱”的樣式在comboBox1中顯示MyTable1的內容。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
using System.Data.SqlClient;  
namespace 習題8_6_3  
{  
public partial class Form1 : Form  
{  
public Form1()  
{  
InitializeComponent();  
}  
private void Form1_Load(object sender, EventArgs e)  
{  
string connectionString = Properties.Settings.Default.MyDatabaseConnectionString;  
//根據連接字符串創建SqlConnection實例  
SqlConnection conn = new SqlConnection(connectionString);  
//創建SqlCommand實例,並設置SQL語句和使用的連接實例  
SqlCommand cmd = new SqlCommand();  
cmd.CommandText = "Select * From MyTable1";  
cmd.Connection = conn;  
try  
{  
conn.Open();  
SqlDataReader r = cmd.ExecuteReader();  
while (r.Read() == true)  
{  
comboBox1.Items.Add(string.Format("[{0}] {1}", r[0], r[1]));  
}  
comboBox1.SelectedIndex = 0;  
r.Close();  
}  
catch (Exception err)  
{  
MessageBox.Show(err.Message, "顯示數據失敗");  
}  
finally  
{  
conn.Close();  
}  
}  
}  

4. 在畫線處填上合適的內容,使程序變得正確完整。 
string connString="server=localhost;Integrated Security=SSPI;database=pubs";  
SqlConnection conn=____________________________  
string strsql="select * from MyTable2";  
SqlDataAdapter adapter=new SqlDataAdapter(_____________);  
dataset=new DataSet();  
adapter.Fill(________________,"MyTable2");  
this.dataGridView1.DataSource=dataset.Tables["MyTable2"]; 
【解答】 
string connString="server=localhost;Integrated Security=SSPI;database=pubs";  
SqlConnection conn= new SqlConnection(Properties.Settings.Default.MyDatabaseConnectionString);  
string strsql="select * from MyTable2";  
SqlDataAdapter adapter=new SqlDataAdapter(conn);  
dataset=new DataSet();  
adapter.Fill(dataset,"MyTable2");  
this.dataGridView1.DataSource=dataset.Tables["MyTable2"]; 
5. 已知數據庫中定義了一張person表,表的數據結構如下: 
字段名稱字段類型字段含義 
id數字編號 
xm文本姓名 
xb文本性別 
nl數字年齡 
zip文本郵政編碼 
用編寫代碼的方法在DataGridView中顯示該數據表中年齡大於18的所有紀錄,顯示時以編號的升序排序,要求禁止用戶編輯數據。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
using System.Data.SqlClient;  
namespace 習題8_6_5  
{  
public partial class Form1 : Form  
{  
public Form1()  
{  
InitializeComponent();  
}  
private void button1_Click(object sender, EventArgs e)  
{  
string connectionstring = Properties.Settings.Default.MyDatabaseConnectionString ;  
SqlConnection conn = new SqlConnection(connectionstring);  
try  
{  
conn.Open();  
SqlDataAdapter adapter = new SqlDataAdapter(  
"select id,xm,xb,nl from person where nl > 18 order by id", conn);  
DataSet dataset = new DataSet();  
//如果不指定表名,則系統自動生成一個默認的表名  
adapter.Fill(dataset, "person");  
//可以使用索引引用生成的表  
dataGridView1.DataSource = dataset.Tables["person"];  
adapter.Dispose();  
}  
catch (Exception err)  
{  
MessageBox.Show(err.Message);  
}  
finally  
{  
conn.Close();  
}  
}  
private void Form1_Load(object sender, EventArgs e)  
{  
//不允許用戶直接在最下面的行添加新行  
dataGridView1.AllowUserToAddRows = false;  
//不允許用戶直接按Delete鍵刪除行  
dataGridView1.AllowUserToDeleteRows = false;  
}  
}  

6.例8-18的存儲過程定義中,將“@surname nvarchar(2),”改爲“@surname nchar(2),”,是否仍然能夠得到正確結果,爲什麼? 
【解答】 
不一定。因爲如果傳遞的參數值爲“王”,在存儲過程中會自動變爲“王 ”。 
7. 調用存儲過程,設計程序完成下列功能:任意給出一個漢字,統計MyTable2中所有包含該漢字的人數,並顯示統計結果。 
【解答】 
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
using System.Data.SqlClient;  
namespace 習題8_6_7  
{  
public partial class Form1 : Form  
{  
public Form1()  
{  
InitializeComponent();  
}  
private void button1_Click(object sender, EventArgs e)  
{  
SqlConnection conn =  
new SqlConnection(Properties.Settings.Default.MyDatabaseConnectionString);  
SqlCommand cmd = new SqlCommand();  
cmd.Connection = conn;  
//設置SQL語句爲存儲過程名,命令類型爲存儲過程  
cmd.CommandText = "SelectFilterStudentsNum";  
cmd.CommandType = CommandType.StoredProcedure;  
//添加存儲過程中參數需要的初始值,注意參數名要和存儲過程定義的參數名相同  
if( textBox1.Text=="")  
{  
MessageBox.Show("請輸入有效信息","錯誤");  
textBox1.Focus();  
return ;  
}  
cmd.Parameters.AddWithValue("@surname", textBox1.Text);  
cmd.Parameters.AddWithValue("@record", 0);  
//指定哪些參數需要返回結果  
cmd.Parameters["@record"].Direction = ParameterDirection.Output;  
try  
{  
conn.Open();  
//執行存儲過程  
cmd.ExecuteNonQuery();  
//顯示返回的結果  
MessageBox.Show(string.Format("有{0}條含 {1} 的記錄",  
cmd.Parameters["@record"].Value,textBox1.Text));  
}  
catch (Exception err)  
{  
MessageBox.Show(err.Message);  
}  
finally  
{  
conn.Close();  
}  
}  
}  

1. 簡述三類二維座標系統之間的相同點和區別。 
【解答】 
GDI+中的二維笛卡兒座標系統分爲三類:全局座標系統、頁面座標系統和設備座標系統。 
三類座標系統的相同點:它們都有座標原點以及向右和向下的x軸和y軸。 
三類座標系統的區別:全局座標系統可以進行旋轉、平移等操作。頁面座標系統與設備座標系統都是以設備的左上角爲座標原點,X水平向右爲正,Y垂直向下爲正。頁面座標系統與設備座標系統的差異在於X,Y的單位不同:頁面座標系中的X,Y單位可以任意設定,如英寸、毫米等;而設備座標系中,只有一種單位,那就是點(point)或者像素(pixel)。頁面座標系是不能更改的,它是一個參照標準,將全局座標最終轉換爲設備座標。 
2. 簡述創建Graphics類對象的三種方法。 
【解答】 
(1) 在窗體或控件的Paint事件中直接引用Graphics對象。在爲窗體創建繪製代碼時,一般使用此方法獲取對圖像的引用。 
(2) 從當前窗體獲取對Graphics對象的引用。注意這種對象只有在處理當前Windows窗體消息的過程中有效。如果想在已經存在的窗體或控件中繪圖,可以使用此種方法。 
(3) 從繼承自圖像的任何對象創建Graphics對象。這個方法適用於需要更改已經存在的 
圖像。 
3. 同時創建多個矩形並用紅黑相間的顏色進行填充。 
【解答】 
(1) 新建一個Windows應用程序,命名爲“FillMultiRectangle”,調整窗體到適當大小。更改“Form1.cs”爲“FormFillMultiRectangle.cs”。 
(2) 切換到代碼方式,添加名稱空間引用: 
using System.Drawing.Drawing2D; 
(3) 雙擊窗體的屬性面板裏事件頁中的Paint事件,添加FormFillMultiRectangle_Paint事件代碼。 
private void FormFillMultiRetangle_Paint(object sender, PaintEventArgs e)  
{  
  Graphics g = e.Graphics;  
HatchBrush mybrush=new HatchBrush (HatchStyle.Cross,Color .Red,Color .Black);  
Rectangle[] rect=  
{  
new Rectangle( 0, 0, 50, 100),  
new Rectangle(50,100, 100, 50),  
new Rectangle(150, 150, 50, 100),  
};  
g.FillRectangles(mybrush, rect);  
g.Dispose();  

(4) 結果如圖所示。 
4. 使用Label控件分別以矩形、橢圓和圓形的方式顯示圖片,並保證圖片完全由繪製對象的邊框決定。 
【解答】 
(1)新建一個Windows應用程序,命名爲“ShowImageExe”,調整窗體到適當大小。更改“Form1.cs”爲“FromShowImageExe.cs”。 
(2)切換到代碼方式,添加名稱空間引用: 
using System.Drawing.Drawing2D; 
(3) 添加四個Button控件分別命名爲“buttonOpenFile”、“buttonRectangle”、“buttonEllipse”、“buttonRound”,以及一個openFileDiolog和label控件。 
(4)在Form類下聲明兩個私有變量filename和flag,分別用來記錄打開的文件名和判斷哪個按鈕的click時間被觸發。 
private string filename = ""; 
private int flag = 0; 
(5) 添加【打開文件】按鈕的click事件 
private void buttonOpenFile_Click(object sender, EventArgs e)  
{  
openFileDialog1.ShowDialog();  
filename = openFileDialog1.FileName;  
label1.Refresh();  

(6) 在label1控件的paint事件下添加如下代碼: 
private void label1_Paint(object sender, PaintEventArgs e)  
{  
if (filename.Trim() == "")  
return;  
Bitmap mybitmap = new Bitmap(filename);  
Graphics g = e.Graphics;  
TextureBrush mybrush = new TextureBrush(mybitmap,WrapMode.Clamp);  
//保證圖片完全由繪製對象的邊框決定  
switch (flag)  
{  
case 1:  
g.FillRectangle(mybrush, label1.ClientRectangle);  
break;  
case 2:  
g.FillEllipse(mybrush, label1.ClientRectangle);  
break;  
case 3:  
g.FillEllipse(mybrush, (label1.Width- label1.Height)/2,0, label1.Height, label1.Height);  
break;  
}  

(7) 在其他幾個按鈕的click事件中分別添加如下代碼: 
private void buttonRectangle_Click(object sender, EventArgs e)  
{  
flag = 1;  
label1.Refresh();  
}  
private void buttonEllipse_Click(object sender, EventArgs e)  
{  
flag = 2;  
label1.Refresh();  
}  
private void buttonRound_Click(object sender, EventArgs e)  
{  
flag = 3;  
label1.Refresh();  

(8) 結果如圖所示。 
5. 利用PictureBox控件和Panel控件實現使用滾動條瀏覽大圖片。 
【解答】 
由於Picturebox控件在顯示圖片時不能直接使用滾動條,所以必須藉助Panel控件實現以滾動條的方式瀏覽大圖片。具體操作步驟如下: 
(1)新建一個Windows應用程序,命名爲“scrollBar”,調整窗體到適當大小。更改“Form1.cs”爲“FormScrollBar.cs”。 
(2)切換到代碼方式,添加名稱空間引用: 
using System.Drawing.Drawing2D; 
(3) 在窗體上分別添加一個button控件命名爲“buttonOpenFile”,一個openFileDiolog控件,Picturebox和Panel控件各一個,將Panel控件的AutoScroll屬性設爲true。 
(4) 在“buttonOpenFile”控件的click事件中添加如下代碼: 
private void buttonOpenFile_Click(object sender, EventArgs e)  
{  
openFileDialog1.ShowDialog();  
if (openFileDialog1.FileName.Trim() == "")  
return;  
try  
{  
Bitmap mybitmap = new Bitmap(openFileDialog1.FileName);  
pictureBox1.Image = mybitmap;  
}  
catch (Exception Err)  
{  
MessageBox.Show("打開文件錯誤!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);  
}  

(5) 結果如圖所示。 
6. 實現對圖片按任意角度進行旋轉、按任意比例進行縮放、按任意位移進行平移。 
【解答】 
(1) 在窗體上添加六個label控件(其中label1用來顯示圖片)、一個button控件(用於打開圖片文件)和五個numericUpDown控件(分別用來選擇圖片縮放的比例、圖片旋轉的角度、圖片位移的大小)。 
(2) 在構造函數上方添加代碼: 
private string strfilename=""; 
(3) 在button控件的click事件裏添加如下代碼: 
private void button1_Click(object sender, EventArgs e)  
{  
openFileDialog1.ShowDialog();  
strfilename=openFileDialog1.FileName;  
label1.Refresh();  

(4) 在每一個numericUpDown控件的ValueChanged事件中添加如下代碼: 
label1.Refresh(); 
(5) 在label1控件的paint事件中添加如下代碼: 
private void label1_Paint(object sender, PaintEventArgs e)  
{  
if (this.strfilename.Trim()=="")  
return ;  
try  
{  
Bitmap mybitmap = new Bitmap(strfilename);  
Graphics g = e.Graphics;  
TextureBrush mybrush = new TextureBrush(mybitmap);  
float x = (float)(numericUpDownS1.Value / 100);  
float y = (float)(numericUpDownS2.Value / 100);  
mybrush.ScaleTransform(x, y);  
g.FillRectangle(mybrush, 0, 0, ClientRectangle.Width, ClientRectangle.Height);  
float r = (float)(numericUpDownR1.Value);  
mybrush.RotateTransform(r);  
g.FillRectangle(mybrush, 0, 0, ClientRectangle.Width, ClientRectangle.Height);  
float tx = (float)(numericUpDownT1.Value);  
float ty = (float)(numericUpDownT2.Value);  
mybrush.TranslateTransform(tx, ty);  
g.FillRectangle(mybrush, 0, 0, ClientRectangle.Width, ClientRectangle.Height);  
}  
catch (Exception Err)  
{  
MessageBox.Show("打開文件錯誤!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);  
}  

8-8-6 
C#網絡應用編程基礎練習題與答案 
1. 組件與控件的主要區別是什麼? 
【解答】 
組件是指可重複使用並且可以和其他對象進行交互的對象。組件(component)是靠類實現的。控件是能夠提供用戶界面接口(UI)功能的組件。換句話說就是,控件是具有用戶界面功能的組件。 
所有控件肯定都是組件,但並不是每個組件都一定是控件。 
2. 控件有幾種類型?各有什麼特點? 
【解答】 
控件分爲:複合、擴展和自定義三類。 
複合控件是封裝在公共容器內的Windows窗體控件的集合。這種控件有時稱爲“用戶控件”,包含的控件稱爲“構成控件”。複合控件包含與每個包含的Windows窗體控件相關聯的所有固有功能,允許有選擇地公開和綁定它們的屬性。複合控件還提供了大量的默認鍵盤處理功能,不需要任何額外的開發。複合控件從UserControl類派生而來。 
擴展控件是從任何現有的Windows窗體控件或者自定義控件導出的繼承控件。它保留Windows窗體控件的所有固有功能,然後通過添加自定義屬性、方法或其他功能擴展此固有功能。可以使用此選項重寫基控件的繪製邏輯,然後更改該控件的外觀以擴展其用戶界面。 
創建控件的另一種方法是通過從Control繼承從頭開始創建一個控件。Control類提供控件所需的所有基本功能(包括鼠標和鍵盤處理事件),但不提供控件特定的功能或圖形界面。若要實現自定義控件,必須編寫該控件的OnPaint事件的代碼,以及所需的任何功能特定的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章