1.寫出完整版的strcpy函式
如果編寫乙個標準strcpy函式的總分值為10,下面給出幾個不同得分的答案:
2分void
strcpy
(char
*strdest,
char
*strsrc )
4分void
strcpy
(char
*strdest,
const
char
*strsrc )
//將源字串加const,表明其為輸入引數,加2分
7分void
strcpy
(char
*strdest,
const
char
*strsrc)
10分//為了實現鏈式操作,將目的位址返回,加3分!
char
*strcpy
(char
*strdest,
const
char
*strsrc )
2.編寫乙個函式,作用是把乙個char組成的字串迴圈右移n個。比如原來是「abcdefghi」如果n=2,移位後應該是「hiabcdefg」 函式頭是這樣的:
//pstr是指向以』\0』結尾的字串的指標
//steps是要求移動的n
void
loopmove
(char
*str,
int steps)
memcpy(目標位址, 源位址, 拷貝的長度)。
例如 pstr=「123456」,steps=2,那麼 len=6,st=2。
第乙個 memcpy 中,pstr+len-st=「56」,st=2 所以就是把 「56」 這兩個字元拷貝給 temp,temp=「56」 兩個字元,即 temp[0]=『5』,temp[1]=『6』。
第二個 memcpy 中,temp+st=temp[2] 所在的位址,pstr=「123456」,len-st=4,也就是說把 pstr 的前 4 個字元拷貝到從 temp[2] 開始的位址裡,即 temp[2]=『1』,temp[3]=『2』,temp[4]=『3』,temp[5]=『4』,即 temp=「561234」 六個字元。
第三個 memcpy 就是把 temp 裡面的 6 個字元拷貝到從 pstr 起的連續 6 個 char 空間裡頭,因為第 7 個空間裡至始至終都沒有人動過,所以第 7 個空間裡頭還有 『\0』,所以 pstr=「561234」 字串。這樣就能實現迴圈右移了。
3.編寫類string的建構函式、析構函式和賦值函式,已知類string的原型為:
class
string
;
//普通建構函式
string::
string
(const
char
*str)
else
}// string的析構函式
string::
~string
(void
)//拷貝建構函式
string::
string
(const string &other)
// 得分點:輸入引數為const型
//賦值函式
string & string::
operator=(
const string &other)
// 得分點:輸入引數為const型
4.下面**會出現什麼問題?
char
*getmemory
(void
)void
test
(void
)
char p=「hello world」;相當於char p[12],strcpy(p," hello world" ).p是乙個陣列名,屬於區域性變數,儲存在棧中, " hello world" 儲存在文字儲存區,陣列p中儲存的是 " hello world" 的乙個副本,當函式結束,p被**,副本也消失了(確切的說p指向的棧儲存區被取消標記,可能隨時被系統修改),而函式返回的p指向的內容也變得不確定,文字儲存區的 " hello world" 未改變。
可以這樣修改:
①char* p= " hello world" ; return p; 這裡p直接指向文字儲存區的 " hello world" ,函式按值返回p儲存的位址,所以有效。
②static char p= " hello world" ; return p; static指出陣列p為靜態陣列,函式結束也不會釋放,所以有效。
5.為什麼標準標頭檔案都有類似以下的結構?
#ifndef __incvxworksh
#define __incvxworksh
#ifdef __cplusplus
extern
"c"#endif
#endif
/* __incvxworksh */
作為一種物件導向的語言,c++支援函式過載,而過程式語言c則不支援。函式被c++編譯後在symbol庫中的名字與c語言的不同。
例如,假設某個函式的原型為:
void foo(int x, int y);
該函式被c編譯器編譯後在symbol庫中的名字為_foo,而c++編譯器則會產生像_foo_int_int之類的名字。_foo_int_int這樣的名字包含了函式名和函式引數數量及型別資訊,c++就是靠這種機制來實現函式過載的。
為了實現c和c++的混合程式設計,c++提供了c連線交換指定符號extern "c"來解決名字匹配問題,函式宣告前加上extern "c"後,則編譯器就會按照c語言的方式將該函式編譯為_foo,這樣c語言中就可以呼叫c++的函式了。
6.請說出static和const關鍵字盡可能多的作用
static關鍵字至少有下列n個作用:
(1)函式體內static變數的作用範圍為該函式體,不同於auto變數,該變數的記憶體只被分配一次,因此其值在下次呼叫時仍維持上次的值;
(2)在模組內的static全域性變數可以被模組內所用函式訪問,但不能被模組外其它函式訪問;
(3)在模組內的static函式只可被這一模組內的其它函式呼叫,這個函式的使用範圍被限制在宣告它的模組內;
(4)在類中的static成員變數屬於整個類所擁有,對類的所有物件只有乙份拷貝;
(5)在類中的static成員函式屬於整個類所擁有,這個函式不接收this指標,因而只能訪問類的static成員變數。
const關鍵字至少有下列n個作用:
(1)欲阻止乙個變數被改變,可以使用const關鍵字。在定義該const變數時,通常需要對它進行初始化,因為以後就沒有機會再去改變它了;
(2)對指標來說,可以指定指標本身為const,也可以指定指標所指的資料為const,或二者同時指定為const;
(3)在乙個函式宣告中,const可以修飾形參,表明它是乙個輸入引數,在函式內部不能改變其值;
(4)對於類的成員函式,若指定其為const型別,則表明其是乙個常函式,不能修改類的 成員變數;
(5)對於類的成員函式,有時候必須指定其返回值為const型別,以使得其返回值不為「左值」。
例如:const classa operator*(const classa& a1,const classa& a2);
operator的返回結果必須是乙個const物件。如果不是,這樣的****也不會編譯出錯:
classa a, b, c;
(a * b) = c; // 對ab的結果賦值
操作(a * b) = c顯然不符合程式設計者的初衷,也沒有任何意義。
面試練習一
1.const define typedef的區別 const define的區別 1.1 安全性方面 const 能定義常量的型別,編譯的時候能對常量型別進行檢查。而define則不能,它是單純的字元替換,很可能有一些邊際的隱患.1.2 生命週期 const 定義的常量在堆疊中分配了記憶體,而de...
面試練習二
對於socket在這裡我不想究其歷史,我只想說其時它是一種程序通訊的方式,簡言之就是呼叫這個網路庫的一些api函式就能實現分布在不同主機的相關程序之間的資料交換.socket中首先我們要理解如下幾個定義概念 二是埠號 用來標識本地通訊程序,方便os提交資料.就是說程序指定了對方程序的網路ip,但這個...
c 筆試練習
c 控制台1 編乙個程式,從鍵盤上輸入三個數,用 if語句和邏輯表示式把最大數找出來。2 編乙個程式,從鍵盤上輸入三個數,用 if語句和邏輯表示式把最小數找出來。3 編乙個程式,定義乙個字元變數,使用 ifelse 語句,輸入乙個字元,如果它是大寫字母,則把它轉換成小寫字母,如果它是小寫字母,則把它...