# 發哥(聯發科)上機考題目整理 [C test] 1. Explain "#error" `Ans:` 可以用來強制中斷編譯器並且輸出訊息,這是寫給編譯器看的,通常搭配 Cflag,CXXflag 使用,在編譯時中斷錯誤的流程。#error預處理程序指令用於指示錯誤。如果找到#error指令編譯器將發出致命錯誤,並且跳過進一步的編譯過程。 以下是在 glibc 中可見的範例 #if !defined(__cplusplus) #error C++ compiler required. #endif 2. Explain "struct" and "union" `Ans:` struct = 在 C 上 自訂一種資料型態裡面可以包含多種資料型態,並且會按照程式中定義時擺放的順序在內存中排序,按照宣告的順序擺放。編譯器會自動為struct的成員分配空間。 在 C++ 上 struct 被擴展到可以內建 method ,跟 class 的意義非常類似,只是繼承與存取權限預設皆為 public 相反的 class 預設為 private,以及 class 有 template 的擴充 struct 沒有 union 一種特殊的所有內容都從內存開頭開始存取的資料型態,並且他的大小由內部最大的那個資料型態來定義。會用同一個存儲空間,只能存儲最後一個成員訊息。只給其中一個成員給值而使用其他值就會壞掉 補充: typedef:保留字。可以為資料型態建立別名。ex: **typedef unsigned uint**; **typedef int (\*CMP)(int,int)** enum: C語言提供自定型態為enum,是一組由識別字所代表的整數常數。除非特別指定,不然都是由0開始,接下來遞增1。ex: **enum week{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};** 3. Explain "volatile". Can we use "const" and "volatile" in the same variable? Can we use "volatile" in a pointer? `Ans:` volatile 加在變數前面。是在指示編譯器每次對該變數進行存取時都要「立即更新」,不應該對其做任何最佳化。 因為有時候變數會先放在CPU register中沒被寫到mem裡,若有其他人要透過他反應便會壞掉。用volatile就可確保變數可以馬上反應 可以跟 const 合用,假設你要(監看)一個 CPU flag 時就是不錯的時機。 const 限定一個變量不被改變 4. unsigned long v1 = 0x 00001111; unsigned long v2 = 0x 00001202; unsigned long v; v = v1&(~v2); v = v | v2; ask: the value of v? `Ans:` 0x00001313 5. int a[5] ={1,2,3,4,5}; int *p = (int *)(&a+1); ask: the value of *(a+1), (*p-1)? `Ans:` (&a+1) = undefine *(a+1) = 2 (*p-1) = 0 (這邊答案似乎有誤, (*p-1)應為undefined) 6. write a code a) set the specific bit b) clear the specific bit c) inverse the specific bit (0->1; 1->0) `Ans:` ``` #define setBit(x,n) (x|= (1<<n)) #define clearBit(x,n) (x&= ~(1<<n)) #define inverseBit(x,n) (x^= (1<<n)) ``` 7. Re-write void(*(*papf)[3])(char *); typedef__________; pf(*papf)[3]; `Ans:` ```C void (*pf) (char *) -> typedef void(*pf)(char *); ``` 8. write a code that check the input is a multiple of 3 or not without using division or mod `Ans:` ```C //這個是剛好用 3 的特性來解 int divide3(int a){ int ans = 0; while(a){ ans += a&1; a>>=1; ans -= a&1; a>>=1; } return !(ans); } ///通用算法(This can be used for any number) /* set Number = abcde(2進位) abcde = abc<<2 + de = abc*(4) + de = abc(*3) + (abc + de) 任何數字都可以用類似的方式拆出用 &跟<<完成的判斷 */ int isMult3(unsigned int n) { if ( n == 0 || n == 3 ) return 1; if ( n < 3 ) return 0; n = (n >> 2) + (n & 3); /* Recursive call till you get n or a special terminate condition */ return(isMult3(n)); } ``` 9. Explain lvalue and rvalue. `Ans:` lvalue 指 等號的左值 rvalue 指 等號的右值 lvalue 是一個物件的保存在單一運算式之外的物件 rvalue 是一個物件在某個時間單位的結果 `++c` 是lvalue `c++` 是rvalue 10. ```=c int a[5]={1,2,3,4,5}; int *p=a; *(p++)+=123; *(++p)+=123; ``` 請問a陣列的每個值為何? `Ans:` 萬年面試題目 124 2 126 4 5 11. ```=c extern void func1(void); extern void func2(void); extern void func3(void); extern void func4(void); extern void func5(void); void main(int n) { if n==1 execute func1; if n==2 execute func2; if n==3 execute func3; if n==4 execute func4; if n==5 execute func5; } ``` 保證 n 一定是上面五個數字之一 不能用if 和 switch case , 請用你認為最快的方法實作main `Ans:` ```=c void (*fp[5]) (); fp[0] = func1; fp[1] = func2; fp[2] = func3; fp[3] = func4; fp[4] = func5; fp[n-1](); ``` 12. ```=c extern void func1(void); extern void func2(void); extern void func3(void); extern void func4(void); extern void func5(void); void main(int n) { if n==33 execute func1; if n==67 execute func2; if n==324 execute func3; if n==231 execute func4; if n==687 execute func5; } ``` 保證 n 一定是上面五個數字之一 使用if, 請用你認為最快的方法實作main `Ans:` 先把邏輯改成 ```c void main(int n) { // if n==33 execute func1; // if n==67 execute func2; // if n==231 execute func4; // if n==324 execute func3; // if n==687 execute func5; if(n<231) if(n!=67) func1(); else func2(); else if(n>231) if(n!=324) func3(); else func5(); else func4(); } ``` 都在兩次判斷內解決,這是我能想到最快的方法了。 13. 寫一個 function 可傳入正整數參數 N,回傳 1 + 2 + 3 +…+N 的和 `Ans:` ```=C inline int nSum(int N){ return (n+n*n)/2 ``` 14. reverse a string `Ans:` ```=C inline void swap(char *a,char *b){ *a= *a^*b; *b= *a^*b; *a= *a^*b; } void reverseOne(char *s){ if(*(s+1) == '\0') return ; reverseOne(s+1); swap(s,s+1); } void reverseAll(char *s){ if((s=='\0')) return; while(s+1 != '\0'){ reverseOne(s); s++; } } ``` 15. 寫一個“標準”巨集MIN ,這個巨集輸入兩個參數並返回較小的一個。 `Ans:` ``` #define min(a,b) ((a)<(b)?(a):(b)) ``` 16. 寫出一個function判斷輸入的數是2的次方 `Ans:` ``` inline int define2N(int n){ return (!(n&n-1) && n!=0) } ``` 17. Write a MACRO to calculate the square of integer a. `Ans:` `#define sqare(x) ((x)*(x))` 18. Write a function to find the middle field of singled-linked list without traverse whole list. `Ans:` 以下是在某種程度上做到的方法,不過廣義上這種做法依然把整個 list 跑了一次,應該沒有在真的不跑一次又是單向又不知道長度的情況下取得中間的 node ```=c public int getMiddleElement(LinkedList l) { return getMiddleElement(l.getHead()); } private int getMileElement(Node n) { Node slow = n; Node fast = n; while(fast!=null && fast.next!=null) { fast = fast.next.next; slow = slow.next; } return slow.data; } ``` 19. Write a code to reverse the linked list. For example: [0] -> [n], [1]->[n-1],…[n]->[0]. `Ans:` a > b > c > d ```=c void revers(Node *head,Node **newhead){ if(head -> next == NULL){ *newhead = head; return ; } revers(head -> next , newhead); head->next->next = head; head->next = NULL; return ; } ``` ``` c= /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* reverseList(struct ListNode* head){ struct ListNode *cur = head, *pre = NULL, *next = NULL; while(cur){ next = cur->next; cur->next = pre; pre = cur; cur = next; } return pre; } ``` 20. Find the possible error ```=c Int ival; Int **p; Ival = *p; ``` `Ans:` reference a pointer to a int 21. What is the possible error of below SQR function. ```=c int SQR(volatile int *a){ return (*a)*(*a); } ``` `Ans:` a is volatile so a*a may not be a^2 the right version ```=c int SQR(volatile int *a){ int b = *a return b*b; } ``` 22. 用預處理指令#define 聲明一個常數,用以表明1年中有多少秒(忽略閏年問題) `Ans:` #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 23. 1. 一個整型數(An integer) 2. 一個指向整型數的指標(A pointer to an integer) 3. 一個指向指標的的指標,它指向的指標是指向一個整型數(A pointer to a pointer to an integer) 4. 一個有10個整型數的陣列(An array of 10 integers) 5. 一個有10個指標的陣列,該指標是指向一個整型數的(An array of 10 pointers to integers) 6. 一個指向有10個整型數陣列的指標(A pointer to an array of 10 integers) 7. 一個指向函數的指標,該函數有一個整型參數並返回一個整型數(A pointer to a function that takes an integer as an argument and returns an integer) 8. 一個有10個指標的陣列,該指標指向一個函數,該函數有一個整型參數並返回一個整型數( An array of ten pointers to functions that take an integer argument and return an integer ) `Ans:` 1. int p 2. int *p 3. int **p 4. int p[10] 5. int *p[10] 6. int (*p)[10] 7. int (*p)(int) 8. int (*p[10])(int) 24.使用bitwise operation ``` void swap(int *a, int *b) { *a = *a ^ *b; *b = *a ^ *b; *a = *a ^ *b; } ```