2012聯發科校園招聘 手機軟件部門筆試&第一輪面試 試題詳解
選擇題我有印象的:
1.int p = (short)0x8000,問打印p是多少?-32678
將16 位short擴展爲 32位int ,把符號位一起擴展 oxffff8000,最高位爲 1是負數,取反加1 得到-32768
2.##的使用(連接):
define call(x,y) x##y
3.char* str = "hello"
str = "pri"
prinf("%s",str);有什麼問題?直接崩潰,char *s = "hello",hello存在了常量存儲區,只能讀不能修改
指針存儲的是全局變量,是在靜態的存儲區域內的,是不能隨便修改的,
如果是數組,那麼是存儲在局部變量的,是可以修改的。
4.大端小端的概念
char c = 'abc'
在大段和小段下,打印c的結果是什麼?
大端情況爲 數據的高字節是在存儲空間的低位 ,數據的低字節是在存儲空間的高位
相反,小端情況 是數據的高字節在存儲空間的高位 ,數據的低字節在存儲空間低位
打印一般是按先打印存儲空間的低位,然後打印高位:
在大端情況下爲: abc
小端情況爲:cba
簡答題:
(1)動態內存分配
爲了防止內存在編譯是造成浪費或者內存不足,需要在運行的時候進行動態內存分配,根據數據大小動態分配內存,new delete , malloc free 在動態申請後 ,使用完進行釋放內存。對一個動態申請的內存不能釋放兩次。
(2)extern c的用法
extern C 一個是用來修飾函數和全局變量的,聲明一個函數或者變量,但是並沒有定義它們,而且它們只能被定義一次。含有statci的函數和全局變量不能聲明爲extern c
另一個是讓函數和變量按照C方式編譯連接,C++是支持函數重載的,經過C++編譯後的函數名稱會發生變化,根據函數名,參數化類型重載,而C編譯方式不會是名字發生變化。
使用 extern C 按照C的方式編譯。
(3)sizeof對指針,數組的用法
sizeof() 指針是4個字節 ,數組是數組定義的長度,但是當數組作爲函數參數的時候就會變爲了指針。
(4)求1的個數(x&(x-1))
int fun(int x)
{
int k = 0;
while(x)
{
k++;
x = (x&(x-1));
}
return k;
}
void main()
{
int a = 9;
int m = fun(a);
cout<<m<<endl;
}
程序設計:
(1)堆排序
void sift(int r[] ,int k ,int m)
{
int i ,j,x;
int t;
bool finished = false;
i = k;
j = 2*i;
t= r[k];
x =t;
while(j<= m &&(!finished))
{
if((j<m)&&(r[j]>r[j+1]))
{
j =j+1;
}
if(x<=r[j])
{
finished = true;
}
else
{
r[i] = r[j];
i = j;
j = 2*i;
}
}
r[i] = t;
}
void heapsort(int c[] ,int n)
{
int i ,m,t;
m = n/2;
for(i = m;i>= 1;i--)
{
sift(c , i , n);
}
for(i = n ;i>=2 ;i--)
{
t = c[i];
c[i] = c[1];
c[1] = t;
sift(c, 1, i-1);
}
}
void main()
{
int a[]={0,51,38,49,27,62,5,16,38};
heapsort(a,8);
int i=0;
for(i = 1 ;i<=8;i++)
{
cout<<a[i]<<endl;;
}
}
(2)求有環鏈表第一個入環節點
// 首先要找到是否有環,並找到在換上相同的那個節點,並返回節點
node *is_findx_circle(node *head)
{
node *p1,*p2,*p;
p1 = head->next;
p2=head->next->next;
while(p1 !=NULL && p2!= NULL)
{
if( p1==p2 )
{
p = p1;
}
p1 = p1->next;
p2=p2->next->next;
}
return p;
}
// 找出點鏈表中第一個相交的點
node *find_frist(node *head1 ,node *head2)
{
int len1 ,len2,i ;
node *p1,*p2;
p1 = p1->next;
p2 = p2->next;
len1 = length(head1);
len2 = length(head2);
if(len1 > len2)
{
for(i = 0 ; i <len1-len2 ; i++)
{
p1 = p1->next;
}
}
if(len2>len1)
{
for( i =0;i<len2-len1 ; i++)
{
p2 = p2->next;
}
}
while( (p1 != NULL) && (p2 != NULL) )
{
if(p1==p2)
{
return p1;
break;
}
else
{
p1 = p1->next;
p2 = p2->next;
}
}
}
(3)atol的寫法
程序設計題注意把自己的思路展示出來。
一面:
(1)c語言static,const用法
static 靜態變量或者函數,只能在本模塊或者函數使用,
const 防止變量被隨意的改變
(2)const char *p,char *const p的意義和用法
const char *p 說明 指針指向的內容是不能夠改變的
char *const p 說明指針是不能夠被改變的
(3)遇到過哪些警告:答曰:類型不匹配,精度丟失
(4)C語言中的默認全局作用域,爲什麼會成立?編譯器角度來分析?其實與extern c的用法一樣。
c 中沒有定義static ,extern 那麼這變量是全局變量,是從定義開始到當前文件結尾處。
static 是將全局變量的作用域限制在了定義到當前文件結尾處,並且不能能使用exttern 來聲明.
extern聲明一個在別處定義的了的全局變量,不進行定義,只是擴展了使用範圍。
要求區分編譯錯誤和鏈接錯誤。
(5)我沒有答對:
- void foo(int *p){
- //dosomething
- }
void foo(int *p){
//dosomething
}
現在主函數是
- int main(){
- char c = 1;
- foo(&c);
- }
int main(){
char c = 1;
foo(&c);
}
有啥問題?
我說的還是類型不匹配,恩,面試官認爲太泛了。
我說類型對於指針式非常重要的,只有編譯器知道了指針的類型,才知道一次處理,如自增操作,走幾步?(其實,這裏,如果我相當此時如果打印指針內容,指針的類型同樣要決定函數要讀入地址的內容的幾個字節,這就是面試官要得答案。如char p,那麼只會讀取p所指地址的1個字節,但是int p會讀取p所指向地址的4分字節)
正解爲:foo中調用的時候,希望傳入的是1,但是實際上想foo函數傳遞參數的時候,會把&c後面的3個字節的內容也傳入,這是垃圾信息,這樣就會出現隱晦的bug。當然,編譯器肯定會警告。
測試用例:
- # include <stdio.h>
- void foo(int *p){
- printf("%d",*p);
- }
- int main(){
- char c = 1;
- foo(&c);
- return 0;
- }
# include <stdio.h>
void foo(int *p){
printf("%d",*p);
}
int main(){
char c = 1;
foo(&c);
return 0;
}
輸出結果:
-42991615
而且這個還是隨時變化的。
第一面收穫:
就是最後一個題目了,以前覺得C的基礎還不錯,還是有沒有考慮到的地方。
另外我看見自己的編程大題目得分很低,看來需要把自己的思路展示出來。其實最後2道題目都比較容易解決