<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          分享10道有趣的C語言面試題及答案

          共 8998字,需瀏覽 18分鐘

           ·

          2021-06-09 14:32

          來源:https://blog.csdn.net/sjin_1314/,編輯:嵌入式大雜燴

          10個C語言面試題,涉及指針、進程、運算、結(jié)構(gòu)體、函數(shù)、內(nèi)存,看看你能做出幾個!

          1.gets()函數(shù)

          問:請找出下面代碼里的問題:

          #include<stdio.h> 
          int main(void) 

              char buff[10]; 
              memset(buff,0,sizeof(buff)); 

              gets(buff); 
               
              printf("\n The buffer entered is [%s]\n",buff); 
               
              return 0
          }

          答:上面代碼里的問題在于函數(shù)gets()的使用,這個函數(shù)從stdin接收一個字符串而不檢查它所復制的緩存的容積,這可能會導致緩存溢出。這里推薦使用標準函數(shù)fgets()代替。

          2.strcpy()函數(shù)

          問:下面是一個簡單的密碼保護功能,你能在不知道密碼的情況下將其破解嗎?

          #include<stdio.h> 

          int main(int argc, char *argv[]) 

              int flag = 0
              char passwd[10]; 

              memset(passwd,0,sizeof(passwd)); 
               
              strcpy(passwd, argv[1]); 
               
              if(0 == strcmp("LinuxGeek", passwd)) 
              { 
                  flag = 1
              } 
               
              if(flag) 
              { 
                  printf("\n Password cracked \n"); 
              } 
              else 
              { 
                  printf("\n Incorrect passwd \n"); 
               
              } 
              return 0
          }

          答:破解上述加密的關(guān)鍵在于利用攻破strcpy()函數(shù)的漏洞。所以用戶在向“passwd”緩存輸入隨機密碼的時候并沒有提前檢查“passwd”的容量是否足夠。

          所以,如果用戶輸入一個足夠造成緩存溢出并且重寫“flag”變量默認值所存在位置的內(nèi)存的長“密碼”,即使這個密碼無法通過驗證,flag驗證位也變成了非零,也就可以獲得被保護的數(shù)據(jù)了。例如:

          $ ./psswd aaaaaaaaaaaaa 

          Password cracked

          雖然上面的密碼并不正確,但我們?nèi)匀豢梢酝ㄟ^緩存溢出繞開密碼安全保護。

          要避免這樣的問題,建議使用 strncpy()函數(shù)。

          作者注:最近的編譯器會在內(nèi)部檢測棧溢出的可能,所以這樣往棧里存儲變量很難出現(xiàn)棧溢出。在我的gcc里默認就是這樣,所以我不得不使用編譯命令‘-fno-stack-protector’來實現(xiàn)上述方案。

          3.main()的返回類型

          問:下面的代碼能 編譯通過嗎?如果能,它有什么潛在的問題嗎?

          #include<stdio.h> 

          void main(void) 

              char *ptr = (char*)malloc(10); 

              if(NULL == ptr) 
              { 
                  printf("\n Malloc failed \n"); 
                  return
              } 
              else 
              { 
                  // Do some processing 
                  free(ptr); 
              } 
               
              return
          }

          答:因為main()方法的返回類型,這段代碼的錯誤在大多數(shù)編譯器里會被當作警告。main()的返回類型應(yīng)該是“int”而不是“void”。

          因為“int”返回類型會讓程序返回狀態(tài)值。這點非常重要,特別當程序是作為依賴于程序成功運行的腳本的一部分運行時。

          4.內(nèi)存泄露

          問:下面的代碼會導致內(nèi)存泄漏嗎?

          #include<stdio.h> 

          void main(void) 

              char *ptr = (char*)malloc(10); 

              if(NULL == ptr) 
              { 
                  printf("\n Malloc failed \n"); 
                  return
              } 
              else 
              { 
                  // Do some processing 
              } 
               
              return
          }

          答:盡管上面的代碼并沒有釋放分配給“ptr”的內(nèi)存,但并不會在程序退出后導致內(nèi)存泄漏。在程序結(jié)束后,所有這個程序分配的內(nèi)存都會自動被處理掉。但如果上面的代碼處于一個“while循環(huán)”中,那將會導致嚴重的內(nèi)存泄漏問題!

          提示:如果你想知道更多關(guān)于內(nèi)存泄漏的知識和內(nèi)存泄漏檢測工具,可以來看看我們在Valgrind上的文章。

          5.free()函數(shù)

          問:下面的程序會在用戶輸入’freeze’的時候出問題,而’zebra’則不會,為什么?

          #include<stdio.h> 

          int main(int argc, char *argv[]) 

              char *ptr = (char*)malloc(10); 

              if(NULL == ptr) 
              { 
                  printf("\n Malloc failed \n"); 
                  return -1
              } 
              else if(argc == 1
              { 
                  printf("\n Usage  \n"); 
              } 
              else 
              { 
                  memset(ptr, 010); 
               
                  strncpy(ptr, argv[1], 9); 
               
                  while(*ptr != 'z'
                  { 
                      if(*ptr == '') 
                          break; 
                      else 
                          ptr++; 
                  } 
               
                  if(*ptr == '
          z'
                  { 
                      printf("\n String contains 'z'\n"); 
                      // Do some more processing 
                  } 
               
                 free(ptr); 
              } 
               
              return 0
          }

          答:這里的問題在于,代碼會(通過增加“ptr”)修改while循環(huán)里“ptr”存儲的地址。當輸入“zebra”時,while循環(huán)會在執(zhí)行前被終止,因此傳給free()的變量就是傳給malloc()的地址。

          但在“freeze”時,“ptr”存儲的地址會在while循環(huán)里被修改,因此導致傳給free()的地址出錯,也就導致了seg-fault或者崩潰。

          6.使用_exit退出

          問:在下面的代碼中,atexit()并沒有被調(diào)用,為什么?

          #include<stdio.h> 

          void func(void) 

              printf("\n Cleanup function called \n"); 
              return


          int main(void) 

              int i = 0

              atexit(func); 
               
              for(;i<0xffffff;i++); 
               
              _exit(0); 
          }

          這是因為_exit()函數(shù)的使用,該函數(shù)并沒有調(diào)用atexit()等函數(shù)清理。如果使用atexit()就應(yīng)當使用exit()或者“return”與之相配合。

          7.void*和C結(jié)構(gòu)體

          問:你能設(shè)計一個能接受任何類型的參數(shù)并返回interger(整數(shù))結(jié)果的函數(shù)嗎?

          答:如下:

          int func(void *ptr)

          如果這個函數(shù)的參數(shù)超過一個,那么這個函數(shù)應(yīng)該由一個結(jié)構(gòu)體來調(diào)用,這個結(jié)構(gòu)體可以由需要傳遞參數(shù)來填充。

          8. * 和 ++ 操作

          問:下面的操作會輸出什么?為什么?

          #include<stdio.h> 

          int main(void) 

              char *ptr = "Linux"
              printf("\n [%c] \n",*ptr++); 
              printf("\n [%c] \n",*ptr); 

              return 0
          }

          答:輸出結(jié)果應(yīng)該是這樣:

          [L] 

          [i]

          因為“++”和“ * ” 的優(yōu)先權(quán)一樣,所以“ * ptr++ ”相當于 “ * (ptr++) ”。即應(yīng)該先執(zhí)行 ptr++,然后才是 * ptr,所以操作結(jié)果是“L”。第二個結(jié)果是“i”。

          9.問:修改代碼片段

          問:下面的代碼段有錯,你能指出來嗎?

          #include<stdio.h> 

          int main(void) 

              char *ptr = "Linux"
              *ptr = 'T'

              printf("\n [%s] \n", ptr); 
               
              return 0
          }

          答:這是因為,通過 * ptr = ‘T’,會改變內(nèi)存中代碼段(只讀代碼)“Linux”的第一個字母。這個操作是無效的,因此會造成segment-fault或者崩潰。

          10.返回本地變量的地址

          問:下面代碼有問題嗎?如果有,該怎么修改?

          #include<stdio.h> 

          intinc(int val) 

            int a = val; 
            a++; 
            return &a; 


          int main(void) 

              int a = 10
              int *val = inc(a); 
              printf("\n Incremented value is equal to [%d] \n", *val); 

              return 0
          }

          答:盡管上面的程序有時候能夠正常運行,但是在“inc()”中存在嚴重的漏洞。這個函數(shù)返回本地變量的地址。

          因為本地變量的生命周期就是“inc()”的生命周期,所以在inc結(jié)束后,使用本地變量會發(fā)生不好的結(jié)果。這可以通過將main()中變量“a”的地址來避免,這樣以后還可以修改這個地址存儲的值。

          溫馨提示

          由于微信公眾號近期改變了推送規(guī)則,如果您想經(jīng)常看到我們的文章,可以在每次閱讀后,在頁面下方點一個「贊」或「在看」,這樣每次推送的文章才會第一時間出現(xiàn)在您的訂閱列表里。

          版權(quán)聲明:本文來源網(wǎng)絡(luò),免費傳達知識,版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請聯(lián)系我進行刪除。

          點擊查看往期內(nèi)容
          (關(guān)注芯片之家)

          往期好文閱讀 



          芯片之家精選文章合集 (一):收藏起來慢慢看
          芯片之家精選文章合集 (二):收藏起來慢慢看
          點擊閱讀??

          瀏覽 68
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线免费观看ww视频 | 国产精品婷婷午夜在线观看 | 国产特一级黄片 | 亚洲欧美日韩在线 | 影音先锋色av |