青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

SEMAN

曾經(jīng)滄海難為水、除卻巫山不是云

C++博客 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
  9 Posts :: 3 Stories :: 24 Comments :: 0 Trackbacks

2005年11月30日 #

[介紹]
gcc and g++分別是gnu的c & c++編譯器 gcc/g++在執(zhí)行編譯工作的時(shí)候,總共需要4步

1.預(yù)處理,生成.i的文件[預(yù)處理器cpp]
2.將預(yù)處理后的文件不轉(zhuǎn)換成匯編語(yǔ)言,生成文件.s[編譯器egcs]
3.有匯編變?yōu)槟繕?biāo)代碼(機(jī)器代碼)生成.o的文件[匯編器as]
4.連接目標(biāo)代碼,生成可執(zhí)行程序[鏈接器ld]
[參數(shù)詳解]
-x language filename
  設(shè)定文件所使用的語(yǔ)言,使后綴名無(wú)效,對(duì)以后的多個(gè)有效.也就是根據(jù)約定C語(yǔ)言的后
綴名稱是.c的,而C++的后綴名是.C或者.cpp,如果你很個(gè)性,決定你的C代碼文件的后綴
名是.pig 哈哈,那你就要用這個(gè)參數(shù),這個(gè)參數(shù)對(duì)他后面的文件名都起作用,除非到了
下一個(gè)參數(shù)的使用。
  可以使用的參數(shù)嗎有下面的這些
  `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a
ssembler-with-cpp'.
  看到英文,應(yīng)該可以理解的。
  例子用法:
  gcc -x c hello.pig
  
-x none filename
  關(guān)掉上一個(gè)選項(xiàng),也就是讓gcc根據(jù)文件名后綴,自動(dòng)識(shí)別文件類型
  例子用法:
  gcc -x c hello.pig -x none hello2.c
  
-c
  只激活預(yù)處理,編譯,和匯編,也就是他只把程序做成obj文件
  例子用法:
  gcc -c hello.c
  他將生成.o的obj文件
-S
  只激活預(yù)處理和編譯,就是指把文件編譯成為匯編代碼。
  例子用法
  gcc -S hello.c
  他將生成.s的匯編代碼,你可以用文本編輯器察看
-E
  只激活預(yù)處理,這個(gè)不生成文件,你需要把它重定向到一個(gè)輸出文件里面.
  例子用法:
  gcc -E hello.c > pianoapan.txt
  gcc -E hello.c | more
  慢慢看吧,一個(gè)hello word 也要與處理成800行的代碼
-o
  制定目標(biāo)名稱,缺省的時(shí)候,gcc 編譯出來(lái)的文件是a.out,很難聽,如果你和我有同感
,改掉它,哈哈
  例子用法
  gcc -o hello.exe hello.c (哦,windows用習(xí)慣了)
  gcc -o hello.asm -S hello.c
-pipe
  使用管道代替編譯中臨時(shí)文件,在使用非gnu匯編工具的時(shí)候,可能有些問(wèn)題
  gcc -pipe -o hello.exe hello.c
-ansi
  關(guān)閉gnu c中與ansi c不兼容的特性,激活ansi c的專有特性(包括禁止一些asm inl
ine typeof關(guān)鍵字,以及UNIX,vax等預(yù)處理宏,
-fno-asm
  此選項(xiàng)實(shí)現(xiàn)ansi選項(xiàng)的功能的一部分,它禁止將asm,inline和typeof用作關(guān)鍵字。
    
-fno-strict-prototype
  只對(duì)g++起作用,使用這個(gè)選項(xiàng),g++將對(duì)不帶參數(shù)的函數(shù),都認(rèn)為是沒(méi)有顯式的對(duì)參數(shù)
的個(gè)數(shù)和類型說(shuō)明,而不是沒(méi)有參數(shù).
  而gcc無(wú)論是否使用這個(gè)參數(shù),都將對(duì)沒(méi)有帶參數(shù)的函數(shù),認(rèn)為城沒(méi)有顯式說(shuō)明的類型

  
-fthis-is-varialble
  就是向傳統(tǒng)c++看齊,可以使用this當(dāng)一般變量使用.
  
-fcond-mismatch
  允許條件表達(dá)式的第二和第三參數(shù)類型不匹配,表達(dá)式的值將為void類型
  
-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
  這四個(gè)參數(shù)是對(duì)char類型進(jìn)行設(shè)置,決定將char類型設(shè)置成unsigned char(前兩個(gè)參
數(shù))或者 signed char(后兩個(gè)參數(shù))
  
-include file
  包含某個(gè)代碼,簡(jiǎn)單來(lái)說(shuō),就是便以某個(gè)文件,需要另一個(gè)文件的時(shí)候,就可以用它設(shè)
定,功能就相當(dāng)于在代碼中使用#include<filename>
  例子用法:
  gcc hello.c -include /root/pianopan.h
  
-imacros file
  將file文件的宏,擴(kuò)展到gcc/g++的輸入文件,宏定義本身并不出現(xiàn)在輸入文件中
  
-Dmacro
  相當(dāng)于C語(yǔ)言中的#define macro
  
-Dmacro=defn
  相當(dāng)于C語(yǔ)言中的#define macro=defn
  
-Umacro
  相當(dāng)于C語(yǔ)言中的#undef macro
-undef
  取消對(duì)任何非標(biāo)準(zhǔn)宏的定義
  
-Idir
  在你是用#include"file"的時(shí)候,gcc/g++會(huì)先在當(dāng)前目錄查找你所制定的頭文件,如
果沒(méi)有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,他
  回先在你所制定的目錄查找,然后再按常規(guī)的順序去找.
  對(duì)于#include<file>,gcc/g++會(huì)到-I制定的目錄查找,查找不到,然后將到系統(tǒng)的缺
省的頭文件目錄查找
  
-I-
  就是取消前一個(gè)參數(shù)的功能,所以一般在-Idir之后使用
  
-idirafter dir
  在-I的目錄里面查找失敗,講到這個(gè)目錄里面查找.
  
-iprefix prefix
-iwithprefix dir
  一般一起使用,當(dāng)-I的目錄查找失敗,會(huì)到prefix+dir下查找
  
-nostdinc
  使編譯器不再系統(tǒng)缺省的頭文件目錄里面找頭文件,一般和-I聯(lián)合使用,明確限定頭
文件的位置
  
-nostdin C++
  規(guī)定不在g++指定的標(biāo)準(zhǔn)路經(jīng)中搜索,但仍在其他路徑中搜索,.此選項(xiàng)在創(chuàng)libg++庫(kù)
使用
  
-C
  在預(yù)處理的時(shí)候,不刪除注釋信息,一般和-E使用,有時(shí)候分析程序,用這個(gè)很方便的

  
-M
  生成文件關(guān)聯(lián)的信息。包含目標(biāo)文件所依賴的所有源代碼你可以用gcc -M hello.c
來(lái)測(cè)試一下,很簡(jiǎn)單。
  
-MM
  和上面的那個(gè)一樣,但是它將忽略由#include<file>造成的依賴關(guān)系。
  
-MD
  和-M相同,但是輸出將導(dǎo)入到.d的文件里面
  
-MMD
  和-MM相同,但是輸出將導(dǎo)入到.d的文件里面
  
-Wa,option
  此選項(xiàng)傳遞option給匯編程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),然
后傳遞給會(huì)匯編程序
  
-Wl.option
  此選項(xiàng)傳遞option給連接程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),然
后傳遞給會(huì)連接程序.
  
-llibrary
  制定編譯的時(shí)候使用的庫(kù)
  例子用法
  gcc -lcurses hello.c
  使用ncurses庫(kù)編譯程序
  
-Ldir
  制定編譯的時(shí)候,搜索庫(kù)的路徑。比如你自己的庫(kù),可以用它制定目錄,不然
  編譯器將只在標(biāo)準(zhǔn)庫(kù)的目錄找。這個(gè)dir就是目錄的名稱。
  
-O0
-O1
-O2
-O3
  編譯器的優(yōu)化選項(xiàng)的4個(gè)級(jí)別,-O0表示沒(méi)有優(yōu)化,-O1為缺省值,-O3優(yōu)化級(jí)別最高 
    
-g
  只是編譯器,在編譯的時(shí)候,產(chǎn)生調(diào)試信息。
  
-gstabs
  此選項(xiàng)以stabs格式聲稱調(diào)試信息,但是不包括gdb調(diào)試信息.
  
-gstabs+
  此選項(xiàng)以stabs格式聲稱調(diào)試信息,并且包含僅供gdb使用的額外調(diào)試信息.
  
-ggdb
  此選項(xiàng)將盡可能的生成gdb的可以使用的調(diào)試信息.
-static
  此選項(xiàng)將禁止使用動(dòng)態(tài)庫(kù),所以,編譯出來(lái)的東西,一般都很大,也不需要什么
動(dòng)態(tài)連接庫(kù),就可以運(yùn)行.
-share
  此選項(xiàng)將盡量使用動(dòng)態(tài)庫(kù),所以生成文件比較小,但是需要系統(tǒng)由動(dòng)態(tài)庫(kù).
-traditional
  試圖讓編譯器支持傳統(tǒng)的C語(yǔ)言特性
[參考資料]
-Linux/UNIX高級(jí)編程
  中科紅旗軟件技術(shù)有限公司編著.清華大學(xué)出版社出版
-Gcc man page
  
[ChangeLog]
-2002-08-10
  ver 0.1 發(fā)布最初的文檔
-2002-08-11
  ver 0.11 修改文檔格式
-2002-08-12
  ver 0.12 加入了對(duì)靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)的參數(shù)
-2002-08-16
  ver 0.16 增加了gcc編譯的4個(gè)階段的命令
運(yùn)行 gcc/egcs
**********運(yùn)行 gcc/egcs***********************
  GCC 是 GNU 的 C 和 C++ 編譯器。實(shí)際上,GCC 能夠編譯三種語(yǔ)言:C、C++ 和 O
bject C(C 語(yǔ)言的一種面向?qū)ο髷U(kuò)展)。利用 gcc 命令可同時(shí)編譯并連接 C 和 C++
源程序。
  如果你有兩個(gè)或少數(shù)幾個(gè) C 源文件,也可以方便地利用 GCC 編譯、連接并生成可
執(zhí)行文件。例如,假設(shè)你有兩個(gè)源文件 main.c 和 factorial.c 兩個(gè)源文件,現(xiàn)在要編
譯生成一個(gè)計(jì)算階乘的程序。
代碼:
-----------------------
清單 factorial.c
-----------------------
int factorial (int n)
{
  if (n <= 1)
   return 1;
  else
   return factorial (n - 1) * n;
}
-----------------------
清單 main.c
-----------------------
#include <stdio.h>
#include <unistd.h>
int factorial (int n);
int main (int argc, char **argv)
{
  int n;
  if (argc < 2)
  {
    printf ("Usage: %s n\n", argv [0]);
    return -1;
  }
  else
  {
   n = atoi (argv[1]);
   printf ("Factorial of %d is %d.\n", n, factorial (n));
   }
  return 0;
}
-----------------------
利用如下的命令可編譯生成可執(zhí)行文件,并執(zhí)行程序:
$ gcc -o factorial main.c factorial.c
$ ./factorial 5
Factorial of 5 is 120.
  GCC 可同時(shí)用來(lái)編譯 C 程序和 C++ 程序。一般來(lái)說(shuō),C 編譯器通過(guò)源文件的后綴
名來(lái)判斷是 C 程序還是 C++ 程序。在 Linux 中,C 源文件的后綴名為 .c,而 C++ 源
文件的后綴名為 .C 或 .cpp。但是,gcc 命令只能編譯 C++ 源文件,而不能自動(dòng)和 C
++ 程序使用的庫(kù)連接。因此,通常使用 g++ 命令來(lái)完成 C++ 程序的編譯和連接,該程
序會(huì)自動(dòng)調(diào)用 gcc 實(shí)現(xiàn)編譯。假設(shè)我們有一個(gè)如下的 C++ 源文件(hello.C):
#include <iostream>
void main (void)
{
  cout << "Hello, world!" << endl;
}
則可以如下調(diào)用 g++ 命令編譯、連接并生成可執(zhí)行文件:
$ g++ -o hello hello.C
$ ./hello
Hello, world!
**********************gcc/egcs 的主要選項(xiàng)*********
gcc 命令的常用選項(xiàng)
選項(xiàng) 解釋
-ansi 只支持 ANSI 標(biāo)準(zhǔn)的 C 語(yǔ)法。這一選項(xiàng)將禁止 GNU C 的某些特色,
例如 asm 或 typeof 關(guān)鍵詞。
-c 只編譯并生成目標(biāo)文件。
-DMACRO 以字符串“1”定義 MACRO 宏。
-DMACRO=DEFN 以字符串“DEFN”定義 MACRO 宏。
-E 只運(yùn)行 C 預(yù)編譯器。
-g 生成調(diào)試信息。GNU 調(diào)試器可利用該信息。
-IDIRECTORY 指定額外的頭文件搜索路徑DIRECTORY。
-LDIRECTORY 指定額外的函數(shù)庫(kù)搜索路徑DIRECTORY。
-lLIBRARY 連接時(shí)搜索指定的函數(shù)庫(kù)LIBRARY。
-m486 針對(duì) 486 進(jìn)行代碼優(yōu)化。
-o FILE 生成指定的輸出文件。用在生成可執(zhí)行文件時(shí)。
-O0 不進(jìn)行優(yōu)化處理。
-O 或 -O1 優(yōu)化生成代碼。
-O2 進(jìn)一步優(yōu)化。
-O3 比 -O2 更進(jìn)一步優(yōu)化,包括 inline 函數(shù)。
-shared 生成共享目標(biāo)文件。通常用在建立共享庫(kù)時(shí)。
-static 禁止使用共享連接。
-UMACRO 取消對(duì) MACRO 宏的定義。
-w 不生成任何警告信息。
-Wall 生成所有警告信息。
posted @ 2005-11-30 13:36 味全每日C++ 閱讀(75364) | 評(píng)論 (3)編輯 收藏


Author:sungo
(TW@Javaworld)  文章原文:http://www.javaworld.com.tw/jute/post/view?bid=10&id=53262&sty=1&tpg=1&age=0

Eclipse除了可以開發(fā)Java之外,還支援了許多語(yǔ)言,現(xiàn)在先介紹
C、C++的開發(fā)環(huán)境設(shè)定,以後有機(jī)會(huì)再介紹其它的。Enjoy it!

OS:Windows XP Professional SP1
使用版本:Eclipse 2.1.2

一.首先要下載CDT,Eclipse 2.1.2使用者,請(qǐng)下載這項(xiàng):
CDT 1.2 Full for Windows R2.1.1 1.2.0 GA - Full - Windows。
Eclipse 2.1.3使用者請(qǐng)下載:CDT 1.2.1。
Eclipse 3.0 M7使用者請(qǐng)下載:CDT 2.0 M7。
Eclipse 3.0 M8使用者請(qǐng)下載:CDT 2.0 M8。
Eclipse 3.0 M9使用者請(qǐng)下載:CDT 2.0 M9。
下載網(wǎng)址:
http://www.eclipse.org/cdt/

安裝:將解壓縮後的features、plugins整個(gè)資料夾複製到Eclipse安裝資料
裡,重新開啟Eclipse即可。

二.下載可在Windows上使用的GNU C、C++編譯器,這裡要下載的是:MinGW。
Download頁(yè)面很長(zhǎng)的一串,請(qǐng)選擇這個(gè)版本:
MinGW bin MinGW-3.1.0-1.exe 14863 kb Sep 15, 2003 11:14
下載網(wǎng)址:
http://www.mingw.org/download.shtml

安裝:安裝目錄選C槽,然後狂點(diǎn)下一步(Next)就行了。安裝完後路徑是這
樣->C:\MinGW。

三.先在Command Line模式下測(cè)試編譯與執(zhí)行。先將C:\MinGW\bin底下的
mingw32-make.exe更名為make.exe,因?yàn)榇龝?huì)在Eclipse使用時(shí)它預(yù)設(shè)
會(huì)抓系統(tǒng)裡make這個(gè)檔名而不是mingw32-make。

(註:如果不更名或是還有其他make程式時(shí),也可以在稍後的Eclipse設(shè)定
中,在make targets view的地方,新增一個(gè)task時(shí),build command 取消
use default , 使用 mingw32-make,或在project properties->make project ->
將make 改為 mingw32-make )
-- 由 snpshu 補(bǔ)充。

在環(huán)境變數(shù)裡加入下列設(shè)定:
PATH : C:\MinGW\bin; (如果系統(tǒng)已經(jīng)有裝其它C/C++編譯器,請(qǐng)把C:\MinGW\bin加在最前面。)
LIBRARY_PATH :C:\MinGW\lib
C_INCLUDE_PATH :C:\MinGW\include
CPLUS_INCLUDE_PATH :C:\MinGW\include\c++\3.2.3;C:\MinGW\include\c++\3.2.3\mingw32;
C:\MinGW\include\c++\3.2.3\backward;C:\MinGW\include

先使用文字編輯器編寫測(cè)試用的原始檔,檔名:main.cpp。
1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;
 
int main(void) {
    cout << "Can You Feel My World?" ;
 
    return 0;
}

在Command Line下編譯指令:
1
C:\g++ main.cpp -O3 -o hello

(O3的O是英文大寫"歐")
編譯成功後:便會(huì)產(chǎn)生hello.exe的執(zhí)行檔。
執(zhí)行畫面如下:
1
2
3
4
5
6
7
8
9
10
Microsoft Windows XP [版本 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
 
C:\Documents and Settings\Sungo>cd\
 
C:\>g++ main.cpp -O3 -o hello
 
C:\>hello
Can You Feel My World?
C:\>

註:-O3 旗標(biāo)表示採(cǎi)最高級(jí)編譯最佳化,編譯速度最慢,但產(chǎn)生的執(zhí)行檔
檔案會(huì)最小,執(zhí)行速度會(huì)最快;-o 旗標(biāo)表示將編譯完的*.exe重新更名。

◎步驟一.開啟Eclipse後,首先先開啟C/C++專用視景。
Windows->Open Perspective->C/C++ Development

◎步驟二.建立一個(gè)C++用的專案。
File-New->Project->C++->Standard Make C++ Project
(接下來(lái)的步驟跟建立一般的Java專案一樣,皆採(cǎi)預(yù)設(shè)即可)

◎步驟三.把我們剛剛寫的main.cpp import進(jìn)來(lái),加到專案裡。
File->Import->File System->瀏覽C:\main.cpp

◎步驟四.建立一個(gè)makefile。
File->New->File,檔案名稱填:makefile。(不需打副檔名)

makefile內(nèi)容如下:
1
2
all:
    g++  main.cpp -g -o run

注意:makefile縮排要以Tab鍵作縮排,不能以空格4作縮排,
否則Build會(huì)有問(wèn)題。


◎步驟五.設(shè)定Make Targets。
Windows-Show View->Make Targets
在Make Targets視窗裡按滑鼠右鍵,Add Build Target
,name打:編譯。Build Target打:all。

◎步驟六.編譯。
在剛剛建立的Make Targets "編譯" 上點(diǎn)滑鼠2下,即會(huì)開始編譯,
此時(shí)我們可以發(fā)現(xiàn)hello.exe已經(jīng)產(chǎn)生在我們專案下了。可在底下
C-Build視窗看到以下輸出結(jié)果:
1
2
make -k all 
g++  main.cpp -g -o run


◎步驟七. *.exe執(zhí)行前設(shè)定。因?yàn)樵赪indows下Run,所以要先作個(gè)設(shè)定
,請(qǐng)開啟Project->Properties->C/C++ Make Project->Binary Parser頁(yè)面。
Binary Parser下拉式選單,將ELF Parser改成PE Windows Parser。

◎步驟八.執(zhí)行。
Run->Run as->C Local Application。
在底下Consloe視窗看到hello.exe的執(zhí)行結(jié)果。

註:當(dāng)原始檔有修改,要重新編譯時(shí),只要滑鼠雙擊我們?cè)诓襟E五
所建立的Make Targets "編譯",即可Rebuilding。

posted @ 2005-11-30 12:57 味全每日C++ 閱讀(1583) | 評(píng)論 (0)編輯 收藏

2005年11月23日 #

預(yù)處理器(Preprocessor)


1. 用預(yù)處理指令#define 聲明一個(gè)常數(shù),用以表明1年中有多少秒(忽略閏年問(wèn)題)

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
我在這想看到幾件事情:
1). #define 語(yǔ)法的基本知識(shí)(例如:不能以分號(hào)結(jié)束,括號(hào)的使用,等等)
2). 懂得預(yù)處理器將為你計(jì)算常數(shù)表達(dá)式的值,因此,直接寫出你是如何計(jì)算一年中有多少秒而不是計(jì)算出實(shí)際的值,是更清晰而沒(méi)有代價(jià)的。
3). 意識(shí)到這個(gè)表達(dá)式將使一個(gè)16位機(jī)的整型數(shù)溢出-因此要用到長(zhǎng)整型符號(hào)L,告訴編譯器這個(gè)常數(shù)是的長(zhǎng)整型數(shù)。
4). 如果你在你的表達(dá)式中用到UL(表示無(wú)符號(hào)長(zhǎng)整型),那么你有了一個(gè)好的起點(diǎn)。記住,第一印象很重要。


2. 寫一個(gè)“標(biāo)準(zhǔn)”宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。

#define MIN(A,B) ((A) <= (B) (A) : (B))
這個(gè)測(cè)試是為下面的目的而設(shè)的:
1). 標(biāo)識(shí)#define在宏中應(yīng)用的基本知識(shí)。這是很重要的,因?yàn)橹钡角度?inline)操作符變?yōu)闃?biāo)準(zhǔn)C的一部分,宏是方便產(chǎn)生嵌入代碼的唯一方法,對(duì)于嵌入式系統(tǒng)來(lái)說(shuō),為了能達(dá)到要求的性能,嵌入代碼經(jīng)常是必須的方法。
2). 三重條件操作符的知識(shí)。這個(gè)操作符存在C語(yǔ)言中的原因是它使得編譯器能產(chǎn)生比if-then-else更優(yōu)化的代碼,了解這個(gè)用法是很重要的。
3). 懂得在宏中小心地把參數(shù)用括號(hào)括起來(lái)
4). 我也用這個(gè)問(wèn)題開始討論宏的副作用,例如:當(dāng)你寫下面的代碼時(shí)會(huì)發(fā)生什么事?
least = MIN(*p++, b);


3. 預(yù)處理器標(biāo)識(shí)#error的目的是什么?

如果你不知道答案,請(qǐng)看參考文獻(xiàn)1。這問(wèn)題對(duì)區(qū)分一個(gè)正常的伙計(jì)和一個(gè)書呆子是很有用的。只有書呆子才會(huì)讀C語(yǔ)言課本的附錄去找出象這種
問(wèn)題的答案。當(dāng)然如果你不是在找一個(gè)書呆子,那么應(yīng)試者最好希望自己不要知道答案。


死循環(huán)(Infinite loops)


4. 嵌入式系統(tǒng)中經(jīng)常要用到無(wú)限循環(huán),你怎么樣用C編寫死循環(huán)呢?

這個(gè)問(wèn)題用幾個(gè)解決方案。我首選的方案是:
while(1) { }
一些程序員更喜歡如下方案:
for(;;) { }
這個(gè)實(shí)現(xiàn)方式讓我為難,因?yàn)檫@個(gè)語(yǔ)法沒(méi)有確切表達(dá)到底怎么回事。如果一個(gè)應(yīng)試者給出這個(gè)作為方案,我將用這個(gè)作為一個(gè)機(jī)會(huì)去探究他們這樣做的
基本原理。如果他們的基本答案是:“我被教著這樣做,但從沒(méi)有想到過(guò)為什么。”這會(huì)給我留下一個(gè)壞印象。
第三個(gè)方案是用 goto
Loop:
...
goto Loop;
應(yīng)試者如給出上面的方案,這說(shuō)明或者他是一個(gè)匯編語(yǔ)言程序員(這也許是好事)或者他是一個(gè)想進(jìn)入新領(lǐng)域的BASIC/FORTRAN程序員。

數(shù)據(jù)聲明(Data declarations)

5. 用變量a給出下面的定義
a) 一個(gè)整型數(shù)(An integer)
b) 一個(gè)指向整型數(shù)的指針(A pointer to an integer)
c) 一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)(A pointer to a pointer to an integer)
d) 一個(gè)有10個(gè)整型數(shù)的數(shù)組(An array of 10 integers)
e) 一個(gè)有10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的(An array of 10 pointers to integers)
f) 一個(gè)指向有10個(gè)整型數(shù)數(shù)組的指針(A pointer to an array of 10 integers)
g) 一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一個(gè)有10個(gè)指針的數(shù)組,該指針指向一個(gè)函數(shù),該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)( An array of ten pointers to functions that take an integer argument and return an integer )

答案是:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer


人們經(jīng)常聲稱這里有幾個(gè)問(wèn)題是那種要翻一下書才能回答的問(wèn)題,我同意這種說(shuō)法。當(dāng)我寫這篇文章時(shí),為了確定語(yǔ)法的正確性,我的確查了一下書。
但是當(dāng)我被面試的時(shí)候,我期望被問(wèn)到這個(gè)問(wèn)題(或者相近的問(wèn)題)。因?yàn)樵诒幻嬖嚨倪@段時(shí)間里,我確定我知道這個(gè)問(wèn)題的答案。應(yīng)試者如果不知道
所有的答案(或至少大部分答案),那么也就沒(méi)有為這次面試做準(zhǔn)備,如果該面試者沒(méi)有為這次面試做準(zhǔn)備,那么他又能為什么出準(zhǔn)備呢?


Static

6. 關(guān)鍵字static的作用是什么?

這個(gè)簡(jiǎn)單的問(wèn)題很少有人能回答完全。在C語(yǔ)言中,關(guān)鍵字static有三個(gè)明顯的作用:
1). 在函數(shù)體,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過(guò)程中維持其值不變。
2). 在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn)。它是一個(gè)本地的全局變量。
3). 在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。
大多數(shù)應(yīng)試者能正確回答第一部分,一部分能正確回答第二部分,同是很少的人能懂得第三部分。這是一個(gè)應(yīng)試者的嚴(yán)重的缺點(diǎn),因?yàn)樗@然不懂得本地化數(shù)據(jù)和代碼范圍的好處和重要性。


Const

7.關(guān)鍵字const是什么含意?
我只要一聽到被面試者說(shuō):“const意味著常數(shù)”,我就知道我正在和一個(gè)業(yè)余者打交道。去年Dan Saks已經(jīng)在他的文章里完全概括了const的所有用法,因此ESP(譯者:Embedded Systems Programming)的每一位讀者應(yīng)該非常熟悉const能做什么和不能做什么.如果你從沒(méi)有讀到那篇文章,只要能說(shuō)出const意味著“只讀”就可以了。盡管這個(gè)答案不是完全的答案,但我接受它作為一個(gè)正確的答案。(如果你想知道更詳細(xì)的答案,仔細(xì)讀一下Saks的文章吧。)如果應(yīng)試者能正確回答這個(gè)問(wèn)題,我將問(wèn)他一個(gè)附加的問(wèn)題:下面的聲明都是什么意思?

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

前兩個(gè)的作用是一樣,a是一個(gè)常整型數(shù)。第三個(gè)意味著a是一個(gè)指向常整型數(shù)的指針(也就是,整型數(shù)是不可修改的,但指針可以)。第四個(gè)意思a是一個(gè)指向整型數(shù)的常指針(也就是說(shuō),指針指向的整型數(shù)是可以修改的,但指針是不可修改的)。最后一個(gè)意味著a是一個(gè)指向常整型數(shù)的常指針(也就是說(shuō),指針指向的整型數(shù)是不可修改的,同時(shí)指針也是不可修改的)。如果應(yīng)試者能正確回答這些問(wèn)題,那么他就給我留下了一個(gè)好印象。順帶提一句,也許你可能會(huì)問(wèn),即使不用關(guān)鍵字const,也還是能很容易寫出功能正確的程序,那么我為什么還要如此看重關(guān)鍵字const呢?我也如下的幾下理由:
1). 關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,實(shí)際上,聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。如果你曾花很多時(shí)間清理其它人留下的垃圾,你就會(huì)很快學(xué)會(huì)感謝這點(diǎn)多余的信息。(當(dāng)然,懂得用const的程序員很少會(huì)留下的垃圾讓別人來(lái)清理的。)
2). 通過(guò)給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。
3). 合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù),防止其被無(wú)意的代碼修改。簡(jiǎn)而言之,這樣可以減少bug的出現(xiàn)。

Volatile

8. 關(guān)鍵字volatile有什么含意 并給出三個(gè)不同的例子。

一個(gè)定義為volatile的變量是說(shuō)這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說(shuō)就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子:
1). 并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)
2). 一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量(Non-automatic variables)
3). 多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量
回答不出這個(gè)問(wèn)題的人是不會(huì)被雇傭的。我認(rèn)為這是區(qū)分C程序員和嵌入式系統(tǒng)程序員的最基本的問(wèn)題。嵌入式系統(tǒng)程序員經(jīng)常同硬件、中斷、RTOS等等打交道,所用這些都要求volatile變量。不懂得volatile內(nèi)容將會(huì)帶來(lái)災(zāi)難。
假設(shè)被面試者正確地回答了這是問(wèn)題(嗯,懷疑這否會(huì)是這樣),我將稍微深究一下,看一下這家伙是不是直正懂得volatile完全的重要性。
1). 一個(gè)參數(shù)既可以是const還可以是volatile嗎?解釋為什么。
2). 一個(gè)指針可以是volatile 嗎?解釋為什么。
3). 下面的函數(shù)有什么錯(cuò)誤:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
下面是答案:
1). 是的。一個(gè)例子是只讀的狀態(tài)寄存器。它是volatile因?yàn)樗赡鼙灰庀氩坏降馗淖儭K莄onst因?yàn)槌绦虿粦?yīng)該試圖去修改它。
2). 是的。盡管這并不很常見。一個(gè)例子是當(dāng)一個(gè)中服務(wù)子程序修該一個(gè)指向一個(gè)buffer的指針時(shí)。
3). 這段代碼的有個(gè)惡作劇。這段代碼的目的是用來(lái)返指針*ptr指向值的平方,但是,由于*ptr指向一個(gè)volatile型參數(shù),編譯器將產(chǎn)生類似下面的代碼:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結(jié)果,這段代碼可能返不是你所期望的平方值!正確的代碼如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}

位操作(Bit manipulation)

9. 嵌入式系統(tǒng)總是要用戶對(duì)變量或寄存器進(jìn)行位操作。給定一個(gè)整型變量a,寫兩段代碼,第一個(gè)設(shè)置a的bit 3,第二個(gè)清除a 的bit 3。在以上兩個(gè)操作中,要保持其它位不變。

對(duì)這個(gè)問(wèn)題有三種基本的反應(yīng)
1). 不知道如何下手。該被面者從沒(méi)做過(guò)任何嵌入式系統(tǒng)的工作。
2). 用bit fields。Bit fields是被扔到C語(yǔ)言死角的東西,它保證你的代碼在不同編譯器之間是不可移植的,同時(shí)也保證了的你的代碼是不可重用的。我最近不幸看到Infineon為其較復(fù)雜的通信芯片寫的驅(qū)動(dòng)程序,它用到了bit fields因此完全對(duì)我無(wú)用,因?yàn)槲业木幾g器用其它的方式來(lái)實(shí)現(xiàn)bit fields的。從道德講:永遠(yuǎn)不要讓一個(gè)非嵌入式的家伙粘實(shí)際硬件的邊。
3). 用 #defines 和 bit masks 操作。這是一個(gè)有極高可移植性的方法,是應(yīng)該被用到的方法。最佳的解決方案如下:
#define BIT3 (0x1<<3)
static int a;
void set_bit3(void)
{
a |= BIT3;
}
void clear_bit3(void)
{
a &= ~BIT3;
}
一些人喜歡為設(shè)置和清除值而定義一個(gè)掩碼同時(shí)定義一些說(shuō)明常數(shù),這也是可以接受的。我希望看到幾個(gè)要點(diǎn):說(shuō)明常數(shù)、|=和&=~操作。

訪問(wèn)固定的內(nèi)存位置(Accessing fixed memory locations)

10. 嵌入式系統(tǒng)經(jīng)常具有要求程序員去訪問(wèn)某特定的內(nèi)存位置的特點(diǎn)。在某工程中,要求設(shè)置一絕對(duì)地址為0x67a9的整型變量的值為0xaa66。編譯器是一個(gè)純粹的ANSI編譯器。寫代碼去完成這一任務(wù)。

這一問(wèn)題測(cè)試你是否知道為了訪問(wèn)一絕對(duì)地址把一個(gè)整型數(shù)強(qiáng)制轉(zhuǎn)換(typecast)為一指針是合法的。這一問(wèn)題的實(shí)現(xiàn)方式隨著個(gè)人風(fēng)格不同而不同。典型的類似代碼如下:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;

一個(gè)較晦澀的方法是:
*(int * const)(0x67a9) = 0xaa55;

即使你的品味更接近第二種方案,但我建議你在面試時(shí)使用第一種方案。

中斷(Interrupts)

11. 中斷是嵌入式系統(tǒng)中重要的組成部分,這導(dǎo)致了很多編譯開發(fā)商提供一種擴(kuò)展—讓標(biāo)準(zhǔn)C支持中斷。具代表事實(shí)是,產(chǎn)生了一個(gè)新的關(guān)鍵字__interrupt。下面的代碼就使用了__interrupt關(guān)鍵字去定義了一個(gè)中斷服務(wù)子程序(ISR),請(qǐng)?jiān)u論一下這段代碼的。

__interrupt double compute_area (double radius)
{
    double area = PI * radius * radius;
    printf(" Area = %f", area);
    return area;
}

這個(gè)函數(shù)有太多的錯(cuò)誤了,以至讓人不知從何說(shuō)起了:
1). ISR 不能返回一個(gè)值。如果你不懂這個(gè),那么你不會(huì)被雇用的。
2). ISR 不能傳遞參數(shù)。如果你沒(méi)有看到這一點(diǎn),你被雇用的機(jī)會(huì)等同第一項(xiàng)。
3). 在許多的處理器/編譯器中,浮點(diǎn)一般都是不可重入的。有些處理器/編譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR中做浮點(diǎn)運(yùn)算。此外,ISR應(yīng)該是短而有效率的,在ISR中做浮點(diǎn)運(yùn)算是不明智的。
4). 與第三點(diǎn)一脈相承,printf()經(jīng)常有重入和性能上的問(wèn)題。如果你丟掉了第三和第四點(diǎn),我不會(huì)太為難你的。不用說(shuō),如果你能得到后兩點(diǎn),那么你的被雇用前景越來(lái)越光明了。

代碼例子(Code examples)
12 . 下面的代碼輸出是什么,為什么?

void foo(void)
{
    unsigned int a = 6;
    int b = -20;
    (a+b > 6) puts("> 6") : puts("<= 6");
}

這個(gè)問(wèn)題測(cè)試你是否懂得C語(yǔ)言中的整數(shù)自動(dòng)轉(zhuǎn)換原則,我發(fā)現(xiàn)有些開發(fā)者懂得極少這些東西。不管如何,這無(wú)符號(hào)整型問(wèn)題的答案是輸出是“>6”。原因是當(dāng)表達(dá)式中存在有符號(hào)類型和無(wú)符號(hào)類型時(shí)所有的操作數(shù)都自動(dòng)轉(zhuǎn)換為無(wú)符號(hào)類型。 因此-20變成了一個(gè)非常大的正整數(shù),所以該表達(dá)式計(jì)算出的結(jié)果大于6。這一點(diǎn)對(duì)于應(yīng)當(dāng)頻繁用到無(wú)符號(hào)數(shù)據(jù)類型的嵌入式系統(tǒng)來(lái)說(shuō)是豐常重要的。如果你答錯(cuò)了這個(gè)問(wèn)題,你也就到了得不到這份工作的邊緣。

13. 評(píng)價(jià)下面的代碼片斷:

unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1's complement of zero */

對(duì)于一個(gè)int型不是16位的處理器為說(shuō),上面的代碼是不正確的。應(yīng)編寫如下:

unsigned int compzero = ~0;

這一問(wèn)題真正能揭露出應(yīng)試者是否懂得處理器字長(zhǎng)的重要性。在我的經(jīng)驗(yàn)里,好的嵌入式程序員非常準(zhǔn)確地明白硬件的細(xì)節(jié)和它的局限,然而PC機(jī)程序往往把硬件作為一個(gè)無(wú)法避免的煩惱。
到了這個(gè)階段,應(yīng)試者或者完全垂頭喪氣了或者信心滿滿志在必得。如果顯然應(yīng)試者不是很好,那么這個(gè)測(cè)試就在這里結(jié)束了。但如果顯然應(yīng)試者做得不錯(cuò),那么我就扔出下面的追加問(wèn)題,這些問(wèn)題是比較難的,我想僅僅非常優(yōu)秀的應(yīng)試者能做得不錯(cuò)。提出這些問(wèn)題,我希望更多看到應(yīng)試者應(yīng)付問(wèn)題的方法,而不是答案。不管如何,你就當(dāng)是這個(gè)娛樂(lè)吧…



動(dòng)態(tài)內(nèi)存分配(Dynamic memory allocation)



14. 盡管不像非嵌入式計(jì)算機(jī)那么常見,嵌入式系統(tǒng)還是有從堆(heap)中動(dòng)態(tài)分配內(nèi)存的過(guò)程的。那么嵌入式系統(tǒng)中,動(dòng)態(tài)分配內(nèi)存可能發(fā)生的問(wèn)題是什么?

這里,我期望應(yīng)試者能提到內(nèi)存碎片,碎片收集的問(wèn)題,變量的持行時(shí)間等等。這個(gè)主題已經(jīng)在ESP雜志中被廣泛地討論過(guò)了(主要是 P.J. Plauger, 他的解釋遠(yuǎn)遠(yuǎn)超過(guò)我這里能提到的任何解釋),所有回過(guò)頭看一下這些雜志吧!讓應(yīng)試者進(jìn)入一種虛假的安全感覺后,我拿出這么一個(gè)小節(jié)目:下面的代碼片段的輸出是什么,為什么?

char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");

這是一個(gè)有趣的問(wèn)題。最近在我的一個(gè)同事不經(jīng)意把0值傳給了函數(shù)malloc,得到了一個(gè)合法的指針之后,我才想到這個(gè)問(wèn)題。這就是上面的代碼,該代碼的輸出是“Got a valid pointer”。我用這個(gè)來(lái)開始討論這樣的一問(wèn)題,看看被面試者是否想到庫(kù)例程這樣做是正確。得到正確的答案固然重要,但解決問(wèn)題的方法和你做決定的基本原理更重要些。

Typedef

15. Typedef 在C語(yǔ)言中頻繁用以聲明一個(gè)已經(jīng)存在的數(shù)據(jù)類型的同義字。也可以用預(yù)處理器做類似的事。例如,思考一下下面的例子:
#define dPS struct s *
typedef struct s * tPS;

以上兩種情況的意圖都是要定義dPS 和 tPS 作為一個(gè)指向結(jié)構(gòu)s指針。哪種方法更好呢?(如果有的話)為什么?
這是一個(gè)非常微妙的問(wèn)題,任何人答對(duì)這個(gè)問(wèn)題(正當(dāng)?shù)脑颍┦菓?yīng)當(dāng)被恭喜的。答案是:typedef更好。思考下面的例子:
dPS p1,p2;
tPS p3,p4;

第一個(gè)擴(kuò)展為
struct s * p1, p2;

上面的代碼定義p1為一個(gè)指向結(jié)構(gòu)的指,p2為一個(gè)實(shí)際的結(jié)構(gòu),這也許不是你想要的。第二個(gè)例子正確地定義了p3 和p4 兩個(gè)指針。

晦澀的語(yǔ)法

16. C語(yǔ)言同意一些令人震驚的結(jié)構(gòu),下面的結(jié)構(gòu)是合法的嗎,如果是它做些什么?
int a = 5, b = 7, c;
c = a+++b;

這個(gè)問(wèn)題將做為這個(gè)測(cè)驗(yàn)的一個(gè)愉快的結(jié)尾。不管你相不相信,上面的例子是完全合乎語(yǔ)法的。問(wèn)題是編譯器如何處理它?水平不高的編譯作者實(shí)際上會(huì)爭(zhēng)論這個(gè)問(wèn)題,根據(jù)最處理原則,編譯器應(yīng)當(dāng)能處理盡可能所有合法的用法。因此,上面的代碼被處理成:
c = a++ + b;
因此, 這段代碼持行后a = 6, b = 7, c = 12。
如果你知道答案,或猜出正確答案,做得好。如果你不知道答案,我也不把這個(gè)當(dāng)作問(wèn)題。我發(fā)現(xiàn)這個(gè)問(wèn)題的最大好處是:這是一個(gè)關(guān)于代碼編寫風(fēng)格,代碼的可讀性,代碼的可修改性的好的話題

posted @ 2005-11-23 20:25 味全每日C++ 閱讀(9867) | 評(píng)論 (3)編輯 收藏

2005年11月22日 #

地址:http://www.topcoder.com/pl/?module=Static&d1=gccj05&d2=ZH_overview

Google? Code Jam - 中國(guó)編程挑戰(zhàn)賽
?
English Version
 
重要日期

報(bào)名開始
11月21日星期一

入圍賽
12月12日星期一

總決賽
1月20日星期五
 
價(jià)值25萬(wàn)元的
高科技獎(jiǎng)品


你有用技術(shù)改變世界的夢(mèng)想嗎?你有挑戰(zhàn)難度的決心嗎?你想和國(guó)內(nèi)計(jì)算機(jī)精英一決高下嗎?全球編程界知名的“Google編程挑戰(zhàn)賽Code Jam”即將登陸中國(guó)。這項(xiàng)比賽每年都是全球計(jì)算機(jī)界的一次盛事。今年 Google 首次專門為中國(guó)舉辦這項(xiàng)比賽,旨在弘揚(yáng)計(jì)算機(jī)科學(xué)的藝術(shù),推進(jìn)中國(guó)計(jì)算機(jī)編程教育,鼓勵(lì)并嘉獎(jiǎng)中國(guó)頂級(jí)編程人才。

競(jìng)賽的題目具有相當(dāng)?shù)奶魬?zhàn)性,競(jìng)賽獎(jiǎng)品也非常豐厚。 有志之士可借此機(jī)會(huì)一展才能,成為脫穎而出的中國(guó)最佳。

這里有極富挑戰(zhàn)性的題目,高科技的獎(jiǎng)品,以及令人贊嘆的榮耀,你還在等什么?

賽事運(yùn)作細(xì)則

此次挑戰(zhàn)賽以計(jì)時(shí)賽的形式舉行,所有的參賽者都將在限定的時(shí)間內(nèi)在線完成相同的競(jìng)賽題目。

參賽者在競(jìng)賽過(guò)程當(dāng)中,可以選用以下4種編程語(yǔ)言的一種-Java,C++,C#和VB。

以下是競(jìng)賽相關(guān)過(guò)程說(shuō)明:

下載競(jìng)賽平臺(tái)
參賽者將從TopCoder?公司的競(jìng)賽平臺(tái)(一個(gè)Java程序)開始踏入競(jìng)賽的第一步。下載平臺(tái)程序,仔細(xì)閱讀競(jìng)賽題目,然后將解決方案編寫成代碼形式,編譯并測(cè)試方案,最后提交方案代碼,得到相應(yīng)的分?jǐn)?shù)。參賽者可以在正式競(jìng)賽前下載競(jìng)賽平臺(tái),通過(guò)提供的樣例來(lái)體驗(yàn)和熟悉平臺(tái)的操作環(huán)境。

編碼階段
在指定的日期和時(shí)間,參賽者進(jìn)入競(jìng)賽平臺(tái),以每10人一組被安排進(jìn)入相應(yīng)的虛擬房間。所有參賽者都將獲得相同的3道競(jìng)賽題,3題的難度遞增。此階段競(jìng)賽中,競(jìng)賽者須在最短時(shí)間內(nèi)完成題目,提供正確的方案代碼,代碼提交得越早,競(jìng)賽者得到的分?jǐn)?shù)越高。在競(jìng)賽的整個(gè)過(guò)程中,排名榜會(huì)顯示競(jìng)賽者的累計(jì)分?jǐn)?shù)。

挑戰(zhàn)階段
在挑戰(zhàn)階段,參賽者不但可以看到其他參賽者提交的方案代碼,還可以給出測(cè)試數(shù)據(jù),使其他參賽者提交的程序得到錯(cuò)誤的運(yùn)算結(jié)果,從而推翻其他參賽者所提交的方案。這種方式,對(duì)于編程人員來(lái)說(shuō)是最直接的競(jìng)賽形式。在這個(gè)階段,參賽者的測(cè)試數(shù)據(jù)若能成功推翻他人提交的代碼則可得分;反之,將被扣分。

系統(tǒng)測(cè)試
在系統(tǒng)測(cè)試階段,系統(tǒng)會(huì)自動(dòng)對(duì)每個(gè)提交方案代碼進(jìn)行測(cè)試,確定其正確程度和可行性,并以此給出參賽者相應(yīng)的分?jǐn)?shù)。整個(gè)評(píng)測(cè)過(guò)程耗時(shí)很短,參賽者當(dāng)場(chǎng)可以知道自己的比賽結(jié)果。

參賽須知

報(bào)名注冊(cè)時(shí)間:從北京時(shí)間2005年11月21日星期一上午9時(shí)開始,至北京時(shí)間2005年12月12日上午9時(shí)結(jié)束。報(bào)名注冊(cè)沒(méi)有人數(shù)限制,但是只有通過(guò)資格賽的前500名(12月12日舉行)可以晉級(jí)此次正式比賽的第一輪。第一輪比賽將在12月19日舉行。

首輪名次前250名將于12月22日晉級(jí)第二輪,第二輪的前50名則將參加在中國(guó)舉行的冠軍賽,爭(zhēng)奪總數(shù)達(dá)25萬(wàn)元的高額獎(jiǎng)品。

日期 時(shí)間 * 狀態(tài)
11月21日星期一 9:00 注冊(cè)開始
12月12日星期一 9:00 注冊(cè)結(jié)束
12月12日星期一 12:00 資格賽開始
12月13日星期二 12:00 資格賽結(jié)束
12月19日星期一 21:00 第一輪-500名參賽者
12月22日星期四 21:00 第二輪-250名參賽者
1月20日星期五 待定 冠軍賽-50名參賽者
* 上述時(shí)間皆為北京時(shí)間。冠軍賽日期有可能發(fā)生變化,請(qǐng)注意屆時(shí)通知。


獎(jiǎng)品

晉級(jí)第二輪的250名參賽者將獲贈(zèng)"Google? Code Jam - 中國(guó)編程挑戰(zhàn)賽"T恤一件和李開復(fù)博士撰寫并簽名的《做最好的自己》一書。晉級(jí)冠軍賽的50名參賽者將獲得如下的獎(jiǎng)項(xiàng):

參賽者 獎(jiǎng)品
第1名 (共價(jià)值40,000人民幣) 一組高端個(gè)人編程工作站
第2至第4名 (每位獎(jiǎng)品價(jià)值20,000人民幣) 一臺(tái)筆記本電腦, PDA手機(jī), 以及一款全新個(gè)人隨身聽
第5至10名(每位獎(jiǎng)品價(jià)值8,000人民幣) 一臺(tái)數(shù)字相機(jī),PDA手機(jī), 以及一款全新個(gè)人隨身聽
第11至20名(每位獎(jiǎng)品價(jià)值4,000人民幣) PDA手機(jī), 以及一款全新個(gè)人隨身聽
第21至50名 (每位獎(jiǎng)品價(jià)值2,000人民幣) 一款全新個(gè)人隨身聽
posted @ 2005-11-22 14:57 味全每日C++ 閱讀(923) | 評(píng)論 (0)編輯 收藏

2005年11月21日 #

Introduction   http://www.codeproject.com/cpp/bitbashing.asp

I have noticed that some people seem to have problems with bitwise operators, so I decided to write this brief tutorial on how to use them.

An Introduction to bits

Bits, what are they you may ask?

Well, simply put, bits are the individual ones and zeros that make up every thing we do with computers. All the data you use is stored in your computer using bits. A BYTE is made up of eight bits, a WORD is two BYTEs, or sixteen bits. And a DWORD is two WORDS, or thirty two bits.

 0 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 0 1 1 1 1 0 0 0
||                  |                   |                    |                  ||
|+- bit 31       |                    |                    |         bit 0 -+|
|                   |                    |                    |                   |
+-- BYTE 3 ---+--- BYTE 2 ---+--- BYTE 1 ---+-- BYTE 0 ---+
|                                        |                                         |
+----------- WORD 1 --------+----------- WORD 0 ---------+
|                                                                                  |
+--------------------------- DWORD -----------------------+

The beauty of having bitwise operators is that you can use a BYTE, WORD or DWORD as a small array or structure. Using bitwise operators you can check or set the values of individual bits or even a group of bits.

Hexadecimal numbers and how they relate to bits

When working with bits, it is kind of hard to express every number using just ones and zeros, which is known as binary notation. To get around this we use hexadecimal (base 16) numbers.

As you may or may not know, it takes four bits to cover all the numbers from zero to fifteen, which also happens to be the range of a single digit hexadecimal number. This group of four bits, or half a BYTE, is called a nibble. As there are two nibbles in a BYTE, we can use two hexadecimal digits to show the value of one BYTE.

NIBBLE   HEX VALUE
======   =========
 0000        0
 0001        1
 0010        2
 0011        3
 0100        4
 0101        5
 0110        6
 0111        7
 1000        8
 1001        9
 1010        A
 1011        B
 1100        C
 1101        D
 1110        E
 1111        F

So if we had one BYTE containing the letter 'r' (ASCII code 114) it would look like this:

0111 0010    binary
  7    2     hexadecimal

We could write it as '0x72'

Bitwise operators

There are six bitwise operators. They are:
   &   The AND operator
   |   The OR operator
   ^   The XOR operator
   ~   The Ones Complement or Inversion operator
  >>   The Right Shift operator
  <<   The Left Shift operator.

The & operator

The & (AND) operator compares two values, and returns a value that has its bits set if, and only if, the two values being compared both have their corresponding bits set. The bits are compared using the following table

   1   &   1   ==   1
   1   &   0   ==   0
   0   &   1   ==   0
   0   &   0   ==   0

An ideal use for this is to set up a mask to check the values of certain bits. Say we have a BYTE that contains some bit flags, and we want to check if bit four bit is set.

BYTE b = 50;
if ( b & 0x10 )
    cout << "Bit four is set" << endl;
else
    cout << "Bit four is clear" << endl;

This would result in the following calculation

    00110010  - b
 & 00010000  - & 0x10
  ----------
    00010000  - result

So we see that bit four is set.

The | operator

The | (OR) operator compares two values, and returns a value that has its bits set if one or the other values, or both, have their corresponding bits set. The bits are compared using the following table

   1   |   1   ==   1
   1   |   0   ==   1
   0   |   1   ==   1
   0   |   0   ==   0

An ideal use for this is to ensure that certain bits are set. Say we want to ensure that bit three of some value is set

BYTE b = 50;
BYTE c = b | 0x04;
cout << "c = " << c << endl;

This would result in the following calculation

    00110010  - b
  | 00000100  - | 0x04
  ----------
    00110110  - result

The ^ operator

The ^ (XOR) operator compares two values, and returns a value that has its bits set if one or the other value has its corresponding bits set, but not both. The bits are compared using the following table

   1   ^   1   ==   0
   1   ^   0   ==   1
   0   ^   1   ==   1
   0   ^   0   ==   0

An ideal use for this is to toggle certain bits. Say we want toggle the bits three and four

BYTE b = 50;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;
b = b ^ 0x18;
cout << "b = " << b << endl;

This would result in the following calculations

    00110010  - b
 ^ 00011000  - ^ 0x18
  ----------
    00101010  - result

    00101010  - b
^ 00011000 - ^ 0x18 ---------- 00110010 - result

The ~ operator

The ~ (Ones Complement or inversion) operator acts only on one value and it inverts it, turning all the ones int zeros, and all the zeros into ones. An ideal use of this would be to set certain bytes to zero, and ensuring all other bytes are set to one, regardless of the size of the data. Say we want to set all the bits to one except bits zero and one

BYTE b = ~0x03;
cout << "b = " << b << endl;
WORD w = ~0x03;
cout << "w = " << w << endl;

This would result in the following calculations

    00000011  - 0x03
    11111100  - ~0x03  b

    0000000000000011  - 0x03
    1111111111111100  - ~0x03  w

Another ideal use, is to combine it with the & operator to ensure that certain bits are set to zero. Say we want to clear bit four

BYTE b = 50;
cout << "b = " << b << endl;
BYTE c = b & ~0x10;
cout << "c = " << c << endl;

This would result in the following calculations

    00110010  - b
 & 11101111  - ~0x10
  ----------
    00100010  - result

The >> and << operators

The >> (Right shift) and << (left shift) operators move the bits the number of bit positions specified. The >> operator shifts the bits from the high bit to the low bit. The << operator shifts the bits from the low bit to the high bit. One use for these operators is to align the bits for whatever reason (check out the MAKEWPARAM, HIWORD, and LOWORD macros)

BYTE b = 12;
cout << "b = " << b << endl;
BYTE c = b << 2;
cout << "c = " << c << endl;
c = b >> 2;
cout << "c = " << c << endl;

This would result in the following calculations

    00001100  - b
    00110000  - b << 2
    00000011  - b >> 2

Bit Fields

Another interesting thing that can be done using bits is to have bit fields. With bit fields you can set up minature structures within a BYTE, WORD or DWORD. Say, for example, we want to keep track of dates, but we want to use the least amount of memory as possible. We could declare our structure this way

struct date_struct {
    BYTE day   : 5,   // 1 to 31
         month : 4,   // 1 to 12
         year  : 14;  // 0 to 9999
    } date;

In this example, the day field takes up the lowest 5 bits, month the next four, and year the next 14 bits. So we can store the date structure in twenty three bits, which is contained in three BYTEs. The twenty fourth bit is ignored. If I had declared it using an integer for each field, the structure would have taken up 12 BYTEs.

|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|
   |                                   |          |           |
   +------ year -------------+ month + day --+

Now lets pick this declaration apart to see what we are doing.

First we will look at the data type we are using for the bit field structure. In this case we used a BYTE. A BYTE is 8 bits, and by using it, the compiler will allocate one BYTE for storage. If however, we use more than 8 bits in our structure, the compiler will allocate another BYTE, as many BYTEs as it takes to hold our structure. If we had used a WORD or DWORD, the compiler would have allocated a total of 32 bits to hold our structure.

Now lets look at how the various fields are declared. First we have the variable (day, month, and year), followed by a colon that separates the variable from the number of bits that it contains. Each bit field is separated by a comma, and the list is ended with a semicolon.

Now we get to the struct declaration. We put the bit fields into a struct like this so that we can use convention structure accessing notation to get at the structure members. Also, since we can not get the addresses of bit fields, we can now use the address of the structure.

date.day = 12;

dateptr = &date;
dateptr->year = 1852;


posted @ 2005-11-21 08:03 味全每日C++ 閱讀(812) | 評(píng)論 (0)編輯 收藏

2005年11月14日 #

    今天參加MS2006年度秋季校園招聘會(huì)的筆試第三場(chǎng),有一個(gè)算法題,求一個(gè)樹種兩個(gè)節(jié)點(diǎn)的最低公共節(jié)點(diǎn),在網(wǎng)上Google了一下,看到原題大致這樣的:
      Given the values of two nodes in a *binary search tree*, write a c program to find the lowest common ancestor. You may assume that both values already exist in the tree.

The function prototype is as follows: int FindLowestCommonAncestor(node* root,int value1,int value)
           20
          /  \
         8    22
       /   \
      4     12
           /  \
         10    14
    構(gòu)筑函數(shù): struct TreeNode * FindLowestCommonTreeNode(struct node *pNode,)

Struct TreeNode
{
   int Data;
   TreeNode *pLeft, *pRight;
}

FindLowestAncestor(Struct TreeNode *pRoot, Struct TreeNode *pNode1, Struct TreeNode *pNode2)
{
   if (pRoot==NULL) 
      return NULL;
   if (pRoot==pNode1 && pRoot==pNode2) 
      return pRoot;
   Struct TreeNode *pTemp;
   if (pTemp = FindLowestAncestor(pRoot->pLeft,pNode1,pNode2)) 
      return pTemp;
   if (pTemp = FindLowestAncestor(pRoot->pRight,pNode1,pNode2)) 
      return pTemp;
   if (FindLowestAncestor(pRoot,pNode1,pNode1) && FindLowestAncestor(pRoot,pNo
de2,pNode2)) return pRoot;

   return NULL;
}

posted @ 2005-11-14 02:05 味全每日C++ 閱讀(1393) | 評(píng)論 (5)編輯 收藏

2005年11月2日 #

 

char ** p1;                                   //    pointer to pointer to char
const char **p2;                           //    pointer to pointer to const char
char * const * p3;                         //    pointer to const pointer to char
const char * const * p4;                //    pointer to const pointer to const char
char ** const p5;                          //    const pointer to pointer to char
const char ** const p6;                 //    const pointer to pointer to const char
char * const * const p7;                //    const pointer to const pointer to char
const char * const * const p8;       //    const pointer to const pointer to const char


注:p1是指向char類型的指針的指針;
        p2是指向const char類型的指針的指針;
        p3是指向char類型的const指針;
        p4是指向const char類型的const指針;
        p5是指向char類型的指針的const指針;
        p6是指向const char類型的指針的const指針;
        p7是指向char類型const指針的const指針;
        p8是指向const char類型的const指針的const指針。

typedef char * a;       // a is a pointer to a char 

typedef a b();            
// b is a function that returns a pointer to a char

typedef b 
*c;            // c is a pointer to a function that returns a pointer to a char 

typedef c d();           
// d is a function returning a pointer to a function that returns a pointer to a char 

typedef d 
*e;           // e is a pointer to a function returning a pointer to a function that a pointer to a char 

e var[
10];               // var is an array of 10 pointers to functions returning pointers to  functions returning pointers to chars.


原文地址:http://www.codeproject.com/cpp/complex_declarations.asp

posted @ 2005-11-02 22:08 味全每日C++ 閱讀(2445) | 評(píng)論 (9)編輯 收藏

2005年10月27日 #

Yin Feilong

Address: Room 110 Building 11 Nanjing University Hankou Road 22, Nanjing, Jiangsu Province 210093

Phone: (86-25) 8359-4465  +86135-8519-7909

       E-mail: yinfeil@gmail.com             Homepage: http://www.seman.cn

Objective:

C++ Software Design Engineer

Education:

      B.E Department of Information Management, Nanjing University.  Aug.2002 – Present

      GPA: Overall: 3.2/4.0

Academic Main Courses:

Development Tools of Management Information System

Management Information Systems and software Engineering

Information Analysis and Policy Making, Information Retrieval and Storage

Programming Languages (C), Data Structures, Database Systems

Computer Network, System Science and Techniques, Information Organization

Computer Abilities:

      Certification:

           National Computer Rank Examination Grade Three(NCRE-3)

      Qualification of Computer and Software Technology Proficiency: Software Designer

      Skills:

Expert: C/C++, Visual Foxpro, HTML, Asp, CSS

Intermediate: Rational Rose, SQL Server, XML, Java, Project 2003

Beginner: C#, Asp.net, Visual C++, Oracle

English Skills:

Have a good command of both spoken and written English. Past CET-4

Experiences:

      Developer. Lily-Studio of Nanjing University, June 2003 – May 2004

           Designed and implemented the Community of Lily Alumni

              Editor in chief of the magazine Network Guide

       Lab Manager. Information Technology Lab. June 2004 – Present

Supervisor of Network Application, Designed and implemented FTPSMTP-based mail ServerVPN Web Server

Designed and implemented 2 websites of Department of Information Management and School of Public, using ASP and ACCESS

              Designed and implemented the platform of Tech-Learn Information

           Translate some parts of Web-based Analysis for competitive.

Honors:   

       FootballPing pong

posted @ 2005-10-27 16:36 味全每日C++ 閱讀(1748) | 評(píng)論 (1)編輯 收藏

2005年10月24日 #

     摘要:   #include "iostream.h"#include "stdlib.h"#include "stack.h"#pragma oncetemplate<class T>class CBiTree{    public:    ...  閱讀全文
posted @ 2005-10-24 11:06 味全每日C++ 閱讀(1538) | 評(píng)論 (1)編輯 收藏

僅列出標(biāo)題  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久av一区二区三区| 久久久亚洲一区| 亚洲一区二区三区激情| 一本到12不卡视频在线dvd| 亚洲精品在线观看免费| 亚洲欧洲在线一区| 亚洲国产成人久久| 亚洲精品国精品久久99热一| 亚洲精品视频免费观看| 日韩亚洲在线| 亚洲网址在线| 欧美一级夜夜爽| 久久精品九九| 久久在线视频在线| 欧美激情国产精品| 欧美性事在线| 国产视频精品免费播放| 狠狠色狠狠色综合日日五| 在线观看日韩精品| 日韩视频国产视频| 午夜精品亚洲| 久久久久成人精品免费播放动漫| 你懂的视频欧美| 最新国产の精品合集bt伙计| 99视频日韩| 欧美一进一出视频| 老司机aⅴ在线精品导航| 欧美成人激情在线| 国产精品白丝jk黑袜喷水| 国产视频一区免费看| 亚洲国产精品久久久久秋霞影院 | 国内精品久久久久影院 日本资源| 国内外成人在线视频| 亚洲黑丝一区二区| 亚洲一区二区免费| 久久久青草婷婷精品综合日韩| 欧美不卡高清| 一本色道久久| 久久天天躁狠狠躁夜夜爽蜜月 | 欧美在线观看www| 欧美 日韩 国产 一区| 国产精品a久久久久| 红桃视频国产一区| 99在线精品视频在线观看| 欧美一区亚洲二区| 亚洲国产精品成人一区二区| 亚洲欧美日韩综合一区| 六月丁香综合| 国产精品素人视频| 亚洲人体大胆视频| 欧美一区亚洲一区| 亚洲欧洲在线视频| 久久久99国产精品免费| 欧美日韩国产一区二区三区| 狠狠色噜噜狠狠色综合久| 99精品国产在热久久婷婷| 久久久久久一区二区三区| 日韩午夜激情av| 久久久综合视频| 国产精品av免费在线观看| 亚洲欧洲精品一区二区| 欧美专区亚洲专区| 妖精视频成人观看www| 久久综合九色综合欧美狠狠| 国产精品捆绑调教| 一区二区毛片| 亚洲福利国产| 久久影视三级福利片| 国产女人18毛片水18精品| 亚洲午夜伦理| 亚洲国产另类精品专区 | 亚洲精品美女在线观看播放| 欧美怡红院视频| 国产精品视频网| 亚洲视频一区二区| 亚洲韩日在线| 麻豆成人在线| 精品二区视频| 久久久精品日韩欧美| 亚洲一本视频| 欧美午夜视频在线观看| 一区二区精品在线| 亚洲欧洲综合另类在线| 麻豆精品视频在线观看视频| 精品成人乱色一区二区| 久久精品久久综合| 午夜精品在线观看| 国产乱码精品一区二区三区av| 亚洲午夜高清视频| 亚洲精选久久| 欧美日本一道本在线视频| 亚洲美女网站| 亚洲国产精品国自产拍av秋霞| 久久久一区二区三区| 有坂深雪在线一区| 老司机免费视频久久| 久久成人在线| 黄色精品在线看| 美女日韩欧美| 巨乳诱惑日韩免费av| 亚洲国产91精品在线观看| 美女在线一区二区| 久久婷婷av| 亚洲人成久久| 99国产精品久久久| 欧美日韩综合另类| 亚洲欧美日韩精品久久奇米色影视 | 欧美人与禽猛交乱配视频| 亚洲精选大片| 99精品国产一区二区青青牛奶| 欧美日韩一级视频| 亚洲欧美制服中文字幕| 亚洲无线视频| 国产一区美女| 麻豆精品在线播放| 欧美成人精品三级在线观看 | 欧美激情视频一区二区三区在线播放| 久久免费视频一区| 亚洲黄一区二区| 最新热久久免费视频| 欧美日韩在线观看视频| 午夜久久久久| 久久精品国产久精国产爱| 亚洲春色另类小说| 亚洲精品日韩欧美| 国产精品丝袜白浆摸在线| 久久精品夜夜夜夜久久| 久久综合九色综合欧美就去吻| 亚洲乱码一区二区| 亚洲深夜福利| 激情视频一区二区| 亚洲欧洲一二三| 国产欧美日韩不卡免费| 免费看精品久久片| 欧美日韩免费区域视频在线观看| 亚洲欧洲av一区二区| 久久精品国产欧美激情| 亚洲毛片在线看| 亚洲免费视频一区二区| 又紧又大又爽精品一区二区| 亚洲精品综合精品自拍| 国产午夜精品视频| 亚洲黄网站黄| 国产亚洲一二三区| 亚洲黄色视屏| 国产日韩精品一区二区| 亚洲国产清纯| 国产日韩欧美制服另类| 亚洲高清中文字幕| 国产精品美女| 亚洲大黄网站| 国产情人节一区| 亚洲人成人99网站| 国产综合网站| 99精品国产一区二区青青牛奶| 一区二区亚洲| 亚洲视频在线看| 亚洲精品一区二区三区四区高清 | 激情综合亚洲| 一本久久综合亚洲鲁鲁五月天| 国产亚洲一区二区精品| 日韩午夜在线观看视频| 亚洲高清不卡| 欧美一区激情| 亚洲一区二区免费在线| 看片网站欧美日韩| 欧美在线一区二区| 欧美日韩午夜在线| 欧美99在线视频观看| 国产欧美亚洲日本| 亚洲美女中文字幕| 亚洲国产精品va| 午夜精品久久久久久久99水蜜桃 | 一本到高清视频免费精品| 亚洲在线日韩| 亚洲视频精选在线| 欧美成人高清视频| 久久久久久国产精品mv| 国产精品海角社区在线观看| 亚洲国产精品99久久久久久久久| 国模吧视频一区| 亚洲欧美精品在线| 午夜精品久久久久久久99樱桃| 欧美另类亚洲| 亚洲丰满少妇videoshd| 又紧又大又爽精品一区二区| 香蕉av福利精品导航| 午夜伦理片一区| 国产精品久久久久久久电影| 日韩视频专区| 99视频精品| 欧美精品在线观看一区二区| 欧美国产日韩xxxxx| 亚洲成人原创| 久久精品中文字幕免费mv| 久久九九热re6这里有精品| 国产精品免费网站在线观看| 夜夜精品视频一区二区| 一区二区三区精品久久久| 欧美激情视频免费观看|