工程師應知道的0x10個問題(5): 資料宣告

MuLong PuYang
8 min readFeb 20, 2022

--

英文原參考網址

A ‘C’ Test: The 0x10 Best Questions for Would-be Embedded Programmers

中文參考網址

C語言測試 應知道的0x10個基本問題

原文翻譯

5. Using the variable a, write down definitions for the following:

使用變數a,寫下下列的定義

參考網址: C語言測試 應知道的0x10個基本問題
以下定義的翻譯答案我直接使用這篇文章的描述

(a) An integer

(a) 一個整數

(b) A pointer to an integer

(b) 一個指向整數的指標

(c) A pointer to a pointer to an integer

(c) 一個指向指標的指標,它指向的指標是指向一個整型數

(d) An array of ten integers

(d) 一個有10個整數型的陣列

(e) An array of ten pointers to integers

(e) 一個有10個指標的陣列,該指標是指向一個整數型的

(f) A pointer to an array of ten integers

(f) 一個指向有10個整數型陣列的指標

(g) A pointer to a function that takes an integer as an argument and returns an integer

(g) 一個指向函數的指標,該函數有一個整數型參數並返回一個整數

(h) An array of ten pointers to functions that take an integer argument and return an integer.

(h) 一個有10個指標的陣列,該指標指向一個函數,該函數有一個整數型參數並返回一個整數

The answers are:

答案是

(a) int a; // An integer

(a) int a; // 一個整數

(b) int *a; // A pointer to an integer

(b) int *a; // 一個指向整數的指標

(c) int **a; // A pointer to a pointer to an integer

(c) int **a; // 一個指向指標的指標,它指向的指標是指向一個整型數

(d) int a[10]; // An array of 10 integers

(d) 一個有10個整數型的陣列

(e) int *a[10]; // An array of 10 pointers to integers

(e) 一個有10個指標的陣列,該指標是指向一個整數型的

(f) int (*a)[10]; // A pointer to an array of 10 integers

(f) 一個指向有10個整數型陣列的指標

(g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer

(g) 一個指向函數的指標,該函數有一個整數型參數並返回一個整數

(h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer

(h) 一個有10個指標的陣列,該指標指向一個函數,該函數有一個整數型參數並返回一個整數

People often claim that a couple of these are the sorts of thing that one looks up in textbooks — and I agree. While writing this article, I consulted textbooks to ensure the syntax was correct. However, I expect to be asked this question (or something close to it) when in an interview situation. Consequently, I make sure I know the answers — at least for the few hours of the interview. Candidates that don’t know the answers (or at least most of them) are simply unprepared for the interview. If they can’t be prepared for the interview, what will they be prepared for?

人們常會說這些是要看教科書的東西 — 我同意。當寫這篇文章的時候,我查了教科書來確認語法是正確的。然後,我期待被問這題(或者是相近的東西)當一場面試發生的時候。因為,我要確認我知道這些答案 — 至少是在幾小時內的面試。不知道這些答案(或者是至少大部分的答案)的應試者是簡明的沒有為這次面試做準備。如果他們沒有準備這場面試,那他們又有什麼能準備的?

自我實作以及理解

注1: 以下是我的自我實作以及理解的部分,不保證正確而且很有可能描述不清楚或者是有錯誤,讀者若發現有可以更正的地方也歡迎留言告訴我注2: 以下皆簡單的使用Ubuntu 20.04虛擬機做測試,並非真實的嵌入式系統,所以Ubuntu 20.04出來的成果可能會與嵌入式系統上的有差異注2: 以下皆簡單的使用Ubuntu 20.04虛擬機做測試,並非真實的嵌入式系統,所以Ubuntu 20.04出來的成果可能會與嵌入式系統上的有差異

這裡的自我實作以及理解預計大致講述int *a[10]、int (*a)[10]、int (*a)(int)、int (*a[10])(int)

(一) int *a[10]; // 一個有10個指標的陣列,該指標是指向一個整數型的

參考資料: C 指针数组

這邊我們簡化int *a[10]成三個指標的陣列int *[3]

在以下程式碼,我們宣告了一個int *a[3],然後另外宣告了三個變數,b = 20,c = 40,d = 60,接著我們讓a[0]的指標指向b,a[1]的指標指向c,a[2]的指標指向d,最後我們再打印輸出看結果

輸出結果

*a[0]: 20
*a[1]: 40
*a[2]: 60

接著我們嘗試對每一個指標的數值+1,看看b, c, d的數值是否有隨之改變

輸出結果

看起來確實指標與變數之間的數值是聯動的,指標確實指到變數

*a[0]: 20
*a[1]: 40
*a[2]: 60
*a[0]: 21 and b is 21
*a[1]: 41 and c is 41
*a[2]: 61 and d is 61

(二) int (*a)[10]; // 一個指向有10個整數型陣列的指標

參考資料
int a; int* a; int** a; int (*a)[]; int (*a)(int)

這裡我們簡化(*a)[10]為(*a)[3],然後讓它指到一個二維陣列b[2][3]={{1,2,3},{4,5,6}};,並且讓a指到b

輸出結果

1
2
3
4
5
6

以下這兩種指標型態其實就是function pointer,有興趣的讀者可以參考我之前寫的文章,而在這篇文章中我就做簡短描述而已

Function Pointer參考資料:
(1) [C語言] function pointer介紹
(2) [C語言] function pointer接收多個參數或者是無參數的宣告型態
(3) [C語言]function pointer的應用[一]: pass function to function
(4) [C語言] function pointer的應用[二]: 傳進相同性質的function到function中
(5) [C語言] function pointer的應用[三]: 使用 typdef 來定義函數指標以增加程式的可讀性
(6) [C語言] function pointer的應用[四]: function pointer array

(三) int (*a)(int); // 一個指向函數的指標,該函數有一個整數型參數並返回一個整數

這裡我們先宣告了一個 int func(int num) 的函數,並讓這個函數返回所接收的參數,接著在主函數中,我們宣告 int (*a)(int) 並指到 int func(int num),接著再直接調用 a(10),來看輸出結果

輸出結果

10

輸出結果為10

(四) int (*a[10])(int); // 一個有10個指標的陣列,該指標指向一個函數,該函數有一個整數型參數並返回一個整數

其實這個就是function pointer array,這裡我簡化 int (*a[10])(int) 為 int (*a[3])(int)

這裡我們宣告了一個 int b(int num),回傳2*num,宣告了一個 int c(int num),回傳3*num,宣告了一個 int d(int num),回傳4*num,並讓a[0]指向 b,a[1] 指向 c,a[2] 指向 d,最終把三者都打印出來

輸出結果

2
3
4

當然,我們也可以把function pointer array用(*a[0])(1)這樣的型式調用,我們將程式碼改成這種型式

輸出結果

2
3
4

--

--