---
tags: C/C++
---
# C/C++ preparation(keep updating)
- the value of v?
```c
unsigned long v1 = 0x00001111;
unsigned long v2 = 0x00001202;
unsigned long v;
v = v1&(~v2);
v = v|v2;
```
ans :
```c
v = (v1 & (~v2)) | v2
= (v1 | v2) & (~v2 | v2)
= (v1 | v2) & (0xffffffff)
= 0x00001313
```
- the value of *(a+1), (*p-1)?
```c
int a[5] ={1,2,3,4,5};
int *p = (int *)(&a + 1);
```
ans:
(a+1) 其實就是 a[1],所以就是 2;
(*p - 1) 就比較奇怪了,因為 (&a+1) 的關係所以 p 其實存的是 a[5] 的記憶體位置,
(a_pointer + a_number) = (a_pointer + (a_number * sizeof(*a_pointer)))
所以 &a + 1 = &a + 1 * sizeof(*&a) = &a + 1 * 20 = a[5] (這邊是假設 int 大小是 4 bytes)
所以理論上來說 *p 應該是 garbage,就算 - 1 以後還是 garbage ,答案應該是:不知道?
- Fill the blank (still don’t know)
```c
void(*(*papf)[3])(char *); // Rewrite this
typedef ___________;
pf(*papf)[3];
```
ans : typedef void(*pf) (char *)
- Write a code that check the input is a multiple of 3 or not without using division or mod
目前看到有個比較可行的做法是,在 N base 的系統中測試能否被 (N+1) 整除的方式是將偶數位數的和跟奇數位數的和相減,再看是否能被 N+1整除。最常見的例子就是 11 啦,不過那是因為是在 10 base 的系統中,所以在 2 base (也就是 2 進位啦) 的系統中可以用這種方式來判斷是否為 3 的倍數。
```c
int is_multi_of_three (int n) {
int even = 0;
int odd = 0;
if (n < 0)
n = -n;
if (0 == n)
return 1;
if (n == 1 || n == 2)
return 0;
while (n !=0 ) {
even += (n & 0x1);
n >>= 1;
odd += (n & 0x1);
n >>= 1;
}
return is_multi_of_three(even - odd);
}
```
- 求fun(456)+fun(123)+fun(789)=?
```c
int fun (int x){
int count = 0 ;
while (x) {
count++ ;
x = x & (x - 1) ;
}
return count ;
}
```
ans :
456 = 111001000 (4個1)
455 = 111000111
123 = 1111011(6個1)
122 = 1111010
789 = 1100010101(5個1)
788 = 1100010100
=> 每次減少一個1
=> 4 + 6 + 5 = 15
- 給兩個數 a b,判斷兩數是否互值
```c
int gcd(int a, int b) {
return a % b == 0 ? b : gcd(b, a % b);
}
```
- 質數表(Sieve of Eratosthenes algorithm)
```cpp
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <vector>
using namespace std;
vector<int> myprime;
int prime[1001];
int main(){
for (int i = 2; i <= sqrt(1000); i++) {
for (int j = i * i; j <= 1000; j = j + i) {
prime[j] = 1;
}
}
for (int i = 2; i <= 1000; i++) {
if (prime[i] == 0){
myprime.push_back(i);
printf("%d ", i);
}
}
return 0;
}
```
- 從兩個數字中找出最大的一個而不使用判斷描述
```cpp
int max(int a, int b)
{
return ((a + b) + abs((a - b))) / 2;
}
```
- pointer and &
```cpp
int a = 3;
int &c= a;
printf("%d\n", c);
c *= a;
printf("%d\n", a);
printf("%d\n", c);
// 3 9 9
// c就是指到a的位置 簡單來說c完全等於a 不是只有得到a的值
```
- pointer-to-pointer
```c
//改變外來的pointer的值(非pointer所指向的變數)
int gint = 0;
void changePtr (int *pInt)
{
pInt = &gint;
}
void main ()
{
int local_int = 1;
int *localPtr = &local_int;
changePtr (localPtr);
printf ("%d\n", *localPtr);
}
```
上述例子, 印出來的數值仍為1,
因為changePtr的pInt是localPtr的複本, 對pInt做變更, 其實並不會影響到localPtr本身
使用call by pointer (or address)來傳遞參數,
被呼叫的函式只是複製pointer的值過去罷了!
所以當我們想在函式內改變外來的pointer的值(非pointer所指向的變數),
且函式外部能使用其改變的pointer的值,
此刻就是call by pointer to pointer登場的最佳機會!
- 判斷一個整數是不是 2 的次方
```cpp
bool ispow2(int n)
{
return n > 0 && (n & n - 1) == 0;
}
```
- the content of array a?
```cpp
int a[] = {6,7,8,9,10};
int *p = a;
*(p++) += 123;
*(++p) += 123;
```
ans : {129, 7, 131, 9, 10}
- 給定一個正整數n,求出第n個質數
```cpp
int main()
{
int num, PrimeCount = 0, i, flag, prime = 1;
printf("\n enter the number:");
scanf("%d", &num);
while (num != PrimeCount)
{
flag=0;
prime++;
for (i = 2; i <= (prime / 2); i++)
{
if (prime % i == 0)
flag = 1;
}
if (flag == 0)
{
PrimeCount++;
}
}
printf("%d prime number is: %d", num, prime);
return 0;
}
```
- 以下代碼的輸出
```c
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a + b > 6) ? puts("> 6") : puts("<= 6");
}
```
ans : “> 6”, unsigned int + int —> unsigned int, -20 被轉換成非常大的數
- 以下代碼的輸出
```c
#define INC(x) x*=2;x+=1
int main()
{
int i, j;
for (i = 0, j = 1; i < 5; i++)
INC(j);
printf("j = %d\n", j);
return 0;
}
```
ans : 33, for 迴圈沒有{},答案是2^5+1
- 寫出一個會發生memory leak 的程式
malloc 不 free or new 不 delete
- 寫出一個會發生pointer 會失效但 compile 會成功的
free 後重新access
- 对绝对地址0x100000赋值且想让程序跳转到绝对地址是0x100000去执行
```c
(unsigned int*)0x100000 = 1234;
// 首先要将0x100000强制转换成函数指针,即:
(void (**)())0x100000;
//然后再调用它:
*((void ()(*))0x100000)();
//用typedef可以看得更直观些:
typedef void(**)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
```
- 不能用if 和 switch case , 請用你認為最快的方法實作main
```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;
}
```
ans :
```c
void (*fp[5]) ();
fp[0] = func1;
fp[1] = func2;
fp[2] = func3;
fp[3] = func4;
fp[4] = func5;
fp[n-1]();
```
- 保證 n 一定是五個數字之一,使用if, 請用你認為最快的方法實作main
```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;
}
```
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();
}
```
- 用變量a給出下面的定義
a) 一個整型數(An integer)
b) 一個指向整型數的指針(A pointer to an integer)
c) 一個指向指針的的指針,它指向的指針是指向一個整型數(A pointer to a pointer to an integer)
d) 一個有10個整型數的數組(An array of 10 integers)
e) 一個有10個指針的數組,該指針是指向一個整型數的(An array of 10 pointers to integers)
f) 一個指向有10個整型數數組的指針(A pointer to an array of 10 integers)
g) 一個指向函數的指針,該函數有一個整型參數並返回一個整型數(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數( An array of ten pointers to functions that take an integer
argument and return an integer )
```c
int a;
int *a;
int **a;
int a[10];
int *a[10];
int (*a)[10];
int (*a)(int);
int (*a[10])(int);
```