C 面試練習20200518

2021-10-06 07:04:43 字數 3933 閱讀 3793

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 語句,輸入乙個字元,如果它是大寫字母,則把它轉換成小寫字母,如果它是小寫字母,則把它...