<th id="ik4gr"><pre id="ik4gr"></pre></th>
<rp id="ik4gr"></rp>
    <dd id="ik4gr"></dd>

  1. <rp id="ik4gr"><object id="ik4gr"><blockquote id="ik4gr"></blockquote></object></rp>
      <rp id="ik4gr"></rp>
        <button id="ik4gr"><acronym id="ik4gr"></acronym></button>
      1. <rp id="ik4gr"><object id="ik4gr"><input id="ik4gr"></input></object></rp>
        1. 杭州嵌入式培訓
          達內杭州嵌入式培訓中心

          13175137725

          想做嵌入式工程師,先來自測一下吧

          • 時間:2019-06-17 15:00
          • 發布:轉載
          • 來源:網絡

          你想要成為一名嵌入式工程師嗎?今天本文帶來的是嵌入式軟件工程師的筆、面試,主要針對初次找嵌入式工作的人群,并且有對面試和筆試中遇到的一些問題進行分析。快來小試牛刀吧:

          1、sizeof與strlen的區別

          (1)、sizeof是運算符,strlen是函數

          (2)、strlen只能用char*做參數,且必須是以''\0''結尾的,而sizeof可用類型做參數,還可用函數做參數,如:

          int sum();

          printf("%d\n", sizeof(sum()));//輸出的結果是sizeof(int),即4。

          (3)、數組做sizeof的參數不退化,傳遞給strlen就退化為指針了。

          (4)、大部分編譯程序,sizeof在編譯時確定,因此sizeof(x)可以用來定義數組維數;而strlen要在運行時才能計算出來,用來計算字符串的長度,而不是類型占內存的大小;

          char str[20]="0123456789";

          int len1=strlen(str); //len1=10;

          int len2=sizeof(str); //len2=20;

          (5)、sizeof后,若為類型必須加括弧,若為變量名可以不加括弧。這是因為sizeof是個操作符不是個函數。

          (6)、當適用于一個結構類型時或變量,sizeof 返回實際的大小;當適用一靜態地空間數組,sizeof歸還全部數組的尺寸。

          sizeof 操作符不能返回動態地被分派了的數組或外部的數組的尺寸;

          (7)、數組作為參數傳給函數時傳的是指針而不是數組,傳遞的是數組的首地址,

          如:

          fun(char [8])

          fun(char [])

          都等價于 fun(char *)

          在C++里參數傳遞數組永遠都是傳遞指向數組首元素的指針,編譯器不知道數組的大小,如果想在函數內知道數組的大小, 需要這樣做:

          進入函數后用memcpy拷貝出來,長度由另一個形參傳進去

          fun(unsiged char *p1, int len)

          {

          unsigned char* buf = new unsigned char[len+1]

          memcpy(buf, p1, len);

          }

          常在用到 sizeof和 strlen的時候,通常是計算字符串數組的長度,如果是對指針,結果則會不一樣的:

          char* str = "abacd";

          sizeof(str)//結果 4 --->str是指向字符串常量的字符指針,sizeof 獲得的是一個指針所占的空間,應該是長整型的,所以是4;

          sizeof(*str) //結果 1 --->*str是第一個字符,其實就是字符串的第一位'a' 所占的內存空間,是char類型的,占了 1 位;

          strlen(str)= 5 //--->若要獲得這個字符串的長度,則一定要使用strlen

          2、使用C語言的宏定義

          (1)、宏定義給某個數bit3置位和清零

          #define SET(a,b) a|(0x1<<b);

          #define CLR(a,b) a&(~(0x1<<b));

          (2)、宏定義一個求兩個數最小值的函數

          #define MIN(A,B) ((A)>(B))?B:A

          不能使用大于、小于、if語句

          #definemax(a,b) (((a)-(b))&(1<<31))?(b):(a)

          #define max(a,b) (a-b)==abs(a-b)?a:b

          #define max(a,b) ((((long)((a)-(b)))&0x80000000)?(b):(a))

          (3)、宏定義交換兩個數:

          #define SWAP (a,b) {a=a+b; b=a-b; a=a-b; }

          3、程序編譯的過程

          預處理:預處理相當于根據預處理命令組裝成新的C程 序,不過常以i為擴展名。

          編譯: 將得到的i文件翻譯成匯編代碼。s文件。

          匯編:將匯編文件翻譯成機器指令,并打包成可重定位目標程序的O文件。該文件是二進制文件,字節編碼是機器指令。

          鏈接:將引用的其他O文件并入到我們程序所在的o文件中,處理得到最終的可執行文件。

          4、++i和i++的區別

          (1)、整形數++i和i++的區別

          [cpp] view plain copy

          1. #include <stdio.h>

          2. int main(void)

          3. {

          4. int a, b, i = 7;

          5. i++; //等價于i = i + 1;

          6. ++i; //等價于i = i + 1;

          7. a = i++; //等價于a = i; i = i + 1;

          8. b = ++i; //等價于i = i + 1; b = i;

          9. printf("a = %d, b = %d\n", a, b);

          10. return 0;

          11. }

          12. a = 9, b = 11

          在例子中,第7和第8行的作用一樣,僅僅是為變量i加1,這時i的值已經增加為9,接下來第10行變量a先獲得i的值(即9),然后i加1,第11行變量i 先再加1,然后把得到的值賦給b,所以b的值為11。

          (2)、(*p)++和++(*p)的區別

          [cpp] view plain copy

          1. #include <stdio.h>

          2. int main(void)

          3. {

          4. int a = 5;

          5. int *p = &a;

          6. int b = (*p)++; //等價于b = a++; 即b = a; a = a + 1;

          7. int c = ++(*p); //等價于c = ++a; 即a = a + 1; c = a;

          8. printf("b = %d, c = %d\n", b, c);

          9. printf("(*p)++ = %d, ++(*p) = %d\n", (*p)++, ++(*p));

          10. return 0;

          11. }

          12. 例子輸出結果:

          13. b = 5, c = 7 ;

          14. (*p)++ = 8, ++(*p) = 8

          (3)、*p++和*++p的區別:

          [cpp] view plain copy

          1. #include <stdio.h>

          2. int main(void)

          3. {

          4. int arr[] = {1, 2, 3, 4};

          5. int *p = arr;

          6. int a = *p++; //等價于a = *(p++); 即a = *p; p = p + 1;

          7. int b = *++p; //等價于b = *(++p); 即p = p + 1; b = *p;

          8. printf("a = %d, b = %d\n", a, b);

          9. return 0;

          10. }

          11. a = 1, b = 3

          對于第8行的操作數p而言,*和++的優先級相同,但根據它們的右結合性可知,在這個表達式里可認為++的優先級高于*,即*p++等價于*(p++)。

          而對于第10行的操作數p而言,它只有一個運算符++,所以先計算++p得出結果,然后間接運算。

          5、二分法的實現過程和代碼分析

          二分查找算法是在有序數組中用到的較為頻繁的一種算法,在未接觸二分查找算法時,最通用的一種做法是,對數組進 行遍 歷,跟每個元素進行比較,其時間為O(n).但二分查找算法則更優,因為其查找時間為 O(lgn),譬如數組{1,2,3,4 ,5,6,7, 8,9},查找元素6,用二分查找的算法執行的話,其順序為:

          (1)、第一步查找中間元素,即5,由于5<6,則6必然在5之后的數組元素中,那么就在{6, 7, 8, 9}中查找,

          (2)、尋找{6, 7, 8, 9}的中位數,為7,7>6,則6應該在7左邊的數組元素中,那么只剩下6,即找到了。

          代碼:

          [cpp] view plain copy

          1. int binary_search(int* a, int len, int goal)

          2. {

          3. int low =0;

          4. int high = len -1;

          5. while(low <= high)

          6. {

          7. int middle = (low + high)/2;

          8. if(a[middle] == goal)

          9. return middle;

          10. //在左半邊

          11. elseif(a[middle] > goal)

          12. high = middle -1;

          13. //在右半邊

          14. else

          15. low = middle +1;

          16. }

          17. //沒找到

          18. return-1;

          19. }

          6、大端小端的轉換

          0x3132(0x32是低位,0x31是高位),把它賦值給一個short變量,那么它在內存中的存儲可能有如下兩種情況:

          (1)、大端字節(Big-endian):

          ----------------->>>>>>>>內存地址增大方向

          short變量地址

          0x1000 0x1001

          _____________________________

          | |

          | 0x31 | 0x32

          |_______________|________________

          高位字節在低位字節的前面,也就是高位在內存地址低的一端.可以這樣記住(大端->高位->在前->正常的邏輯順序)

          (2)、小端字節(little-endian):

          ----------------->>>>>>>>內存地址增大方向

          short變量地址

          0x1000 0x1001

          _____________________________

          | |

          | 0x32 | 0x31

          |________________|________________

          低位字節在高位字節的前面,也就是低位在內存地址低的一端.可以這樣記住(小端->低位->在前->與正常邏輯順序相反)

          7、棧和堆的區別

          棧(操作系統):由操作系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧。

          堆(操作系統):一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似于鏈表。

          8、Volatile與Register修飾符的作用

          Volatile與Register修飾符的作用volatile的作用是:

          作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值,

          volatile表示這個變量會被意想不到的改變,每次用他的時候都會小心的重新讀取一遍,不適用寄存器保存的副本

          1) 并行設備的硬件寄存器(如:狀態寄存器)

          2) 一個中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)

          3) 多線程應用中被幾個任務共享的變量

          register

          建議編譯器使用寄存器來優化對變量的存取

          register修飾符暗示編譯程序相應的變量將被頻繁地使用,如果可能的話,應將其保存在CPU的寄存器中,以加快其 存儲速度

          9、char *a 與char a[] 的區別

          char *a存放在常量區,是無法修的。而char a[] 是存放在棧中,是可以修改的

          10、要求設置一絕對地址為0x67a9 的整型變量的值為0xaa66

          int *ptr = (int *)0xaa66; *ptr = 0x67a9;

          11、信號量與互斥鎖的區別

          (1)、互斥量用于線程的互斥,信號量用于線程的同步。

          互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪 問順序,即訪問是無 序的。

          同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已 經實現了互斥,特別 是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源

          (2)、互斥量值只能為0/1,信號量值可以為非負整數。

          也就是說,一個互斥量只能用于一個資源的互斥訪問,它不能實現多個資源的多線程互斥問題。信號量可以實現多個 同類資源的多線程 互斥和同步。當信號量為單值信號量是,也可以完成一個資源的互斥訪問。

          (3)、互斥量的加鎖和解鎖必須由同一線程分別對應使用,信號量可以由一個線程釋放,另一個線程得到。

          12、用C語言實現字符串倒序

          [cpp] view plain copy

          1. int fun(char *w)

          2. {

          3. char t, *s1,*s2;

          4. int n=strlen(w);

          5. s1=w;

          6. s2=w+n-1;

          7. while(s1<s2)

          8. {

          9. t=*s1;

          10. *s1=*s2;

          11. *s2=t;

          12. s1++;

          13. s2--;

          14. }

          15. }

          13、選擇排序和冒泡排序

          (1)、選擇法

          [cpp] view plain copy

          1. void selectsort(int k[],int n) /*選擇排序*/

          2. {

          3. int i,j;

          4. int temp;

          5. for(i=0;i<n;i++)// “ i ” 就是起始值

          6. {

          7. for(j=i+1;j<n;j++)

          8. {

          9. if(k[j] < k[i])

          10. {

          11. temp=k[j];

          12. k[j]=k[i];

          13. k[i]=temp;

          14. }

          15. }

          16. }

          17. }

          (2)、冒泡法

          [cpp] view plain copy

          1. void bubblesort(int k[],int n)

          2. { /*冒泡排序*/

          3. int i,j,tmp;

          4. for(i=0;i<n ;i++) //控制每趟往前推一個,即少比較一次

          5. {

          6. for(j=0;j<n-i-1;j++) //從第一個開始,不斷與相鄰的值比較,并交換最值,一直推到最后,形如冒泡

          7. {

          8. if(k[j]<k[j+1])

          9. {

          10. temp=k[j];

          11. k[j]=k[j+1]

          12. k[j+1]=temp;

          13. }

          14. }

          15. }

          16.

          17. }

          14、memcpy和strcpy的區別

          (1)、復制的內容不同。strcpy只能復制字符串,而memcpy可以復制任意內容,例如字符數組、整型、結構體、類等。

          (2)、復制的方法不同。strcpy不需要指定長度,它遇到被復制字符的串結束符"\0"才結束,所以容易溢出。memcpy則是 根據其第3個參數決定復制 的長度。

          (3)、用途不同。通常在復制字符串時用strcpy,而需要復制其他類型數據時則一般用memcpy

          15、進程與線程的區別

          (1)、地址空間和其它資源:進程間相互獨立,同一進程的各線程間共享。某進程內的線程在其它進程不可見。

          (2)、通信:進程間通信IPC,通過管道、信號量、消息隊列、信號、套接字、共享內存通信,線程間可以直接讀寫進程數據段(如全局變量)來進行通信——需要進程同步和互斥手段的輔助,以保證數據的一致性。

          (3)、一個線程可以創建和撤銷另一個線程,同一個進程中的多個線程之間可以并發執行。

          16、TCP和UDP的區別

          TCP的可靠性:

          首先,為了防止數據在傳輸的過程中被損壞,每個信息包都包含一個校驗碼,這個校驗碼頭就是一個用來保證信息包在傳輸過程中沒有被更改的 代碼,當信息到達目的地的時候,接收方會對比較驗碼和收到的信息中的數據,如果校驗碼不對,則被信息包將被省略。

          第二,為了防止信息包丟失,TCP會要求接收方每收到一個信息包都反饋一下,如果接收方沒有提供反饋,發送方會自動重發一次,一直到接收方 收到為止,或者它會判斷網絡鏈接斷開了,就會在程序中返回一個錯誤的提示。

          第三,為了防止信息包重復或順序錯誤,TCP每傳送一個信息包都會傳送一個序號,接收方會檢查這個序號,確保收到該信息包,并把全部信息包 按順序重新合并,同時,如果接收方看到一個已接收了的序號,則這個信息包就會被丟棄。

          17、用變量a給出下面的定義

          a) 一個整型數(An integer)

          b)一個指向整型數的指針( A pointer to an integer)

          c)一個指向指針的的指針,它指向的指針是指向一個整型數( A pointer to a pointer to an intege)r

          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 )

          答案是:

          a) int a; // An integer

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

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

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

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

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

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

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

          18、關鍵字static的作用是什么?

          1) 在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。

          2) 在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。

          3) 在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地范圍內使用。

          19、關鍵字const有什么含意?

          下面的聲明都是什么意思?

          1、const int a;

          2、int const a;

          3、const int *a;

          4、int * const a;

          5、int const * a const;

          前兩個的作用是一樣,a是一個常整型數。第三個意味著a是一個指向常整型數的指針(也就是,整型數是不可修改的,但指針可以)。第四個意思a是一個指向整型數的常指針(也就是說,指針指向的整型數是可以修改的,但指針是不可修改的)。最后一個意味著a是一個指向常整型數的常指針(也就是說,指針指向的整型數是不可修改的,同時指針也是不可修改的)。如果應試者能正確回答這些問題,那么他就給我留下了一個好印象。順帶提一句,也許你可能會問,即使不用關鍵字 const,也還是能很容易寫出功能正確的程序,那么我為什么還要如此看重關鍵字const呢?我也如下的幾下理由:

          1) 關鍵字const的作用是為給讀你代碼的人傳達非常有用的信息,實際上,聲明一個參數為常量是為了告訴了用戶這個參數的應用目的。如果你曾花很多時間清理其它人留下的垃圾,你就會很快學會感謝這點多余的信息。(當然,懂得用const的程序員很少會留下的垃圾讓別人來清理的。)

          2) 通過給優化器一些附加的信息,使用關鍵字const也許能產生更緊湊的代碼。

          3) 合理地使用關鍵字const可以使編譯器很自然地保護那些不希望被改變的參數,防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現。

          以上就是本文為大家分享的內容,如果你還有更多的疑問歡迎咨詢達內在線老師。

          預約申請免費試聽課

          怕錢不夠?就業掙錢后再付學費!    怕學不會?從入學起,達內定制課程!     擔心就業?達內多家實踐企業供你挑選!

          上一篇:Python爬蟲面試技巧分享
          下一篇:收好了:C語言面試基礎算法及代碼

          一文告訴你:如何參加IT培訓拿高薪?

          非科班出身轉行IT難嗎?好就業嗎?

          面試時程序員應該如何解答薪資問題?

          交付前你需要這樣的UI自查

          • 掃碼領取資料

            回復關鍵字:視頻資料

            免費領取 達內課程視頻學習資料

          • 視頻學習QQ群

            添加QQ群:1143617948

            免費領取達內課程視頻學習資料

          Copyright ? 2018 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

          選擇城市和中心
          江西省

          貴州省

          廣西省

          海南省

          香蕉视频在线一级a做爰片免费观看视频 欧美成年性色生活片 百度 好搜 搜狗
          <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>