Featured image of post 軟韌相關題目

軟韌相關題目

複習C的題目、軟韌相關題目

Bitwise Operation

  • Bitwise Left Shift(«)
  • Bitwise Right Shift(»)
1
2
3
0001 << 1 = 0010
1000 >> 1 = 0100
-
  • AND(&)
1
2
3
4
5
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
-
  • or(|)
1
2
3
4
5
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
-
  • xor(^)
1
2
3
4
5
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
-
  • not(~)
1
2
3
~ 0 = 1
~ 1 = 0
-
  • array: 會分配『連續』的記憶體空間給予陣列存放資料。
1
2
    int x[5] = {1,2,3,4,5};
-
  • stack: 後進先出
  • queue: 先進先出
功能 Link List Array
記憶體 不需要連續的空間 需要連續的空間
節點型態 各node形態不相同 各node形態相同
操作複雜度 插入、刪除都為O(n) 插入刪除都為O(1)
空間配置 不需預留空間 須事先宣告連續空間
資料分割、連結 容易 不容易
存取方式 只能循序存取 可支援隨機與循序存取
存取速度 速度慢 速度快
可靠性 差 佳
額外指標空間 需要額外的指標空間 不需要

Pointer

  • 指標:某變數的位置。
  • 指標變數:用來存放指標的變數。
    • 代表取值
  • & 代表取記憶體位置

題目

Q1:

給一個int a[20]已排序的陣列,請寫一個function(a, size)能印出0~500的數字,且不包含a陣列內的元素,請用最少的時間和空間複雜度完成。

Ans:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
    void function(int* a, int size){
        int* ptr = a;
        for (int i = 0; i <= 500; i++) 
        {
            if (*ptr == i) 
                ptr++;
            else
                printf("%d", i); 
        }
    }
-

Q2:

給一個int a[20]已排序的陣列,請寫一個function(a, size, b)能依照參數b(b = 0~4)別印出該區間的數字,且不包含a陣列內的元素,例如:

1
2
3
4
5

    b = 0, 印出0~99
    b = 1, 印出100~199
    ...
-

Ans:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17

    void function(int *a, int size, int b){
        int *ptr = a;
        int i;

        while (*ptr < b * 100) {
            ptr++;
        }

        for (i = b*100; i<(b+1)*100; i++) {
            if (*ptr == i)
                ptr++;
            else
                printf("%d\n", i);
        }
    }
-

Q3:

情境題,給予一個 structure

1
2
3
4
5
6
7
8
9
    struct ListStruct{
        unsigned int DataH;
        unsigned int DataL;
        unsigned int NextPtr;
    };
    struct ListStruct ListArray[1000];
    #define NULL 0xFFFF
    unsigned int ListHead = 0;
-

其中有兩個條件

  • 條件一: ListArray[Entry1].NextPtr = ListArray[Entry2]
  • 條件二: ListArray[Entry2].DataH « 16 + ListArray[Entry2].DataL > ListArray[Entry1].DataH « 16 + ListArray[Entry1].DataL

代表

  • 第一個 index 中的 NextPtr 會指到另一個 index 中的起始位址
  • 另一個 index 中的起始位址的資料內容大小一定大於原起始資料的大小
  • 請寫一個function(unsigned int DATA_A, unsigned int DATA_B), 能在ListArray中找到符合ListArray[Entry].DataH == Data_A 且 ListArray[Entry].DataL == Data_B 並印出其結果。如果沒有找到的話,印出”no found.”。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void Q3(unsigned int DATA_A, unsigned int DATA_B)
{
    int found_entry = ListHead;
    int pre_entry = NULL;
    int next_entry = NULL;

    while (ListArray[found_entry].NextPtr != NULL) {
        if (ListArray[found_entry].DataH == DATA_A && ListArray[found_entry].DataL == DATA_B) {
	    if (pre_entry == NULL)
	        printf("pre_entry = NULL, found_entry = ListHead\n");
            else
	        printf("pre_entry = %d, found_entry = %d", pre_entry, found_entry);
	    printf("found it\n");

	    next_entry = ListArray[found_entry].NextPtr;
	    if (ListArray[next_entry].DataH << 16 + ListArray[next_entry].DataL >
	        DATA_A << 16 + DATA_B)
		break;
	}

	pre_entry = found_entry;
	found_entry = ListArray[found_entry].NextPtr;
    }

}
-

Sort

  • Quick sort
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
    #define SWAP(x,y) {int t; t = x; x = y; y = t;} 

    void quickSort(int number[], int left, int right) { 
        if(left < right) { 
            int s = number[(left+right)/2]; 
            int i = left - 1; 
            int j = right + 1; 

            while(1) { 
                while(number[++i] < s) ;  // 向右找
                while(number[--j] > s) ;  // 向左找 
                if(i >= j) 
                    break; 
                SWAP(number[i], number[j]); 
            } 

            quickSort(number, left, i-1);   // 對左邊進行遞迴 
            quickSort(number, j+1, right);  // 對右邊進行遞迴 
        } 
    } 
-
  • Binary serach
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    int binsearch(int* arr, int k, int n) {
    int left = 0, right = n;
    while (left <= right) {
        int mid = (left+right)/2;
        if (arr[mid] > k) {       // 往左半部找
        right = mid - 1;
        }
        else if (arr[mid] < k) {  // 往右半部找
        left = mid + 1;
        }
        else
        return mid;
    }
    return -1; // not found
    }
-

Big / Little -Endian

  • 在現今主流的 CPU 中,最常見的位元組順序有兩種,分別是 Big-Endian 與 Little-Endian,Big-Endian 是指資料放進記憶體中的時候,最高位的位元組會放在最低的記憶體位址上,而 Little-Endian 則是剛好相反,它會把最高位的位元組放在最高的記憶體位址上。

Image 1 Image 2

不同 type pointer++時,memery address的差別

  • 當你對一個int指針執行pointer++操作時,它會遞增內存地址,遞增的內存地址通常是4或8字節。
  • 當你對一個char指針執行pointer++操作時,它會遞增內存地址,遞增的內存地址通常是1字節。

Copy by value / Call by reference 的意思

  • Copy by value:當你將參數傳遞給函數時,函數使用參數的副本來執行操作。這意味著在函數內部對參數的任何更改都不會影響原始參數的值。
  • Call by reference:當你將參數按引用傳遞給函數時,函數可以直接訪問和修改原始參數的值,因為它具有對原始參數內存位置的引用。

Struct / Union / Enum

結構體(struct)用於組織具有不同數據類型的成員變數,每個成員變數占據獨立的內存空間。 聯合體(union)用於組織具有相同起始位置的成員變數,它們共享內存空間。 列舉(enum)用於定義命名常數集合,通常實現為整數值。

  • 結構體(struct):

    • 結構體用於定義一種自定義的數據類型,它可以包含多個不同類型的成員變數(字段),每個成員變數占據自己的內存空間。
    • 結構體的內存布局是成員按照定義的順序依次排列,每個成員變數在內存中占據連續的空間。
    • 結構體的內存大小等於所有成員變數的內存大小之和,沒有內存重疊。
  • 聯合體(union):

    • 聯合體也是用於組織數據的構造,但它與結構體不同,它的成員共享相同的內存位置。
    • 聯合體的內存布局是所有成員共享相同的內存空間,占據的空間等於最大成員的大小。
    • 僅能同時使用一個成員變數,改變一個成員的值會影響其他成員。
  • 列舉(enum):

    • 列舉用於定義一組命名常數,它們在內存中通常被實現為整數值。
    • 列舉的內存布局通常是整數,它們的值按照聲明的順序遞增,但它們只占據一個整數的內存空間。

OS

解釋multi-thread、multi-process

它們允許程序同時執行多個任務,提高了程序的性能和響應能力。

  • 多線程通過在單個進程內並發執行多個線程來提高程序性能,線程之間共享相同的內存和資源。
  • 多進程通過在操作系統中並發執行多個獨立的進程來提高程序性能,每個進程有自己的獨立內存和資源。
  • 多線程適用於需要共享數據或共享內存的情況,而多進程適用於需要隔離和保護數據的情況。選擇哪種方式取決於應用程序的需求和性能要求。

題目

最大公因數

1
2
3
4
5
6
7
8
9

    int gcd(int x, int y) {
        // x > y
        if (y == 0)  /* 餘 0,除數 x 即為最大公因數 */
            return x;
        else
            return gcd(y, x % y);  /* 前一步驟的除數為被除數,餘數為除數 */
    }
-

字串反轉

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    void swap(char* a, char* b) {
    char t = *a;
    *a = *b;
    *b = t;
}

    void reverseString(char* s, int sSize){
        if (s == NULL) return NULL;
        int j = sSize - 1;
        for (int i = 0; i < sSize/2; i++) {
            swap( &s[i], &s[j] );
            j--;
        }
    }
-

給一個unsigned short, 問換算成16進制後四個值是否相同? 若是回傳1,否則回傳0

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    int isHexEqaul(unsigned short input) {     // input = 0xAAAA;
    unsigned short input;
    unsigned short hex[4]; // 0xFFFF ==> 0000 0000 0000 0000
    int is_eqaul;

    hex[0] = (input & 0xF000) >> 12;
    hex[1] = (input & 0x0F00) >> 8;
    hex[2] = (input & 0x00F0) >> 4;
    hex[3] = input & 0x000F;

    is_eqaul = ((hex[0] == hex[1]) && (hex[1] == hex[2]) && (hex[2] == hex[3]));
    return is_eqaul;
}
-

求一個數的最高位1在第幾位

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    int main(){
        unsigned int a = 0x65; // 0110 0101
        unsigned int test_bit = 128; // 1000 0000
        int count = 7;  // sizeof(unsigned int)*8   == 該data type的bit數
        while (((a & test_bit) >> count) != 1) {
            count--;
            test_bit >>= 1;
        }
        printf("hightest bit is %d th bit\n", count);
        
        return 0;
    }
-
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Sora