久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1413|回復: 0
打印 上一主題 下一主題
收起左側

C語言18個經(jīng)典問題答錄....

[復制鏈接]
跳轉到指定樓層
樓主
ID:107189 發(fā)表于 2016-3-4 23:48 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
1.這樣的初始化有什么問題?char *p = malloc(10); 編譯器提示“非法初始式” 云云。

答:這個聲明是靜態(tài)或非局部變量嗎?函數(shù)調用只能出現(xiàn)在自動變量(即局部非靜態(tài)變量) 的初始式中。
因為靜態(tài)變量的地址必須在編譯的過程中就確定下來而malloc()申請的內存地址是在運行時確定的。

2. *p++ 自增p 還是p 所指向的變量?

答:后綴++ 和-- 操作符本質上比前綴一目操作的優(yōu)先級高, 因此*p++ 和*(p++) 等價, 它自增p 并返回p 自增之前所指向的值。
要自增p 指向的值, 使用(*p)++, 如果副作用的順序無關緊要也可以使用++*p。

3 我有一個char * 型指針正巧指向一些int 型變量, 我想跳過它們。為什么如下的代碼((int *)p)++; 不行?

答:在C 語言中, 類型轉換意味著“把這些二進制位看作另一種類型, 并作相應的對待”; 這是一個轉換操作符,  
根據(jù)定義它只能生成一個右值(rvalue)。而右值既不能賦值, 也不能用++ 自增。(如果編譯器支持這樣的擴展,  
那要么是一個錯誤, 要么是有意作出的非標準擴展。) 要達到你的目的可以用:p = (char *)((int *)p + 1);
或者,因為p 是char * 型, 直接用p += sizeof(int);

4.空指針和未初始化的指針是一回事嗎?

答:空指針在概念上不同于未初始化的指針:空指針可以確保不指向任何對象或函數(shù);
而未初始化指針則可能指向任何地方。

5.我可以用0來表示空指針嗎?

答:根據(jù)語言定義, 在指針上下文中的常數(shù)0 會在編譯時轉換為空指針。也就是說, 在初始化、賦值或比較的時候,  
如果一邊是指針類型的值或表達式, 編譯器可以確定另一邊的常數(shù)0 為空指針并生成正確的空指針值。因此下邊的代碼段完全合法:
char *p = 0;
if(p != 0)

然而, 傳入函數(shù)的參數(shù)不一定被當作指針環(huán)境, 因而編譯器可能不能識別未加修飾的0 “表示” 指針。
在函數(shù)調用的上下文中生成空指針需要明確的類型轉換,強制把0 看作指針。
例如, Unix 系統(tǒng)調用execl 接受變長的以空指針結束的字符指針參數(shù)。它應該如下正確調用:
execl("/bin/sh", "sh", "-c", "date", (char *)0);
如果省略最后一個參數(shù)的(char *) 轉換, 則編譯器無從知道這是一個空指針,從而當作一個0 傳入。(注意很多Unix 手冊在這個例子上都弄錯了。)


摘要:
==========================|=============================
|| 可以使用未加修飾的0 | 需要顯示的類型轉換 ||
||------------------------|---------------------------||
|| *初始化 | *函數(shù)調用, 作用域內無原型 ||
|| *賦值 | *變參函數(shù)調用中的可變參數(shù) ||
|| *比較 | ||
|| *固定參數(shù)的函數(shù)調用 | ||
|| 且在作用域內有原型 | ||
==========================|=============================

有兩條簡單規(guī)則你必須遵循:
1) 當你在源碼中需要空指針常數(shù)時, 用“0” 或“NULL”。
2) 如果在函數(shù)調用中“0” 或“NULL” 用作參數(shù), 把它轉換成被調函數(shù)需要的指針類型

6. 既然數(shù)組引用會蛻化為指針, 如果arr 是數(shù)組, 那么arr 和&arr 又有什么區(qū)別呢?

答:區(qū)別在于類型:
在標準C 中, &arr 生成一個“T 型數(shù)組” 的指針, 指向整個數(shù)組。
在所有的C 編譯器中, 對數(shù)組的簡單引用(不包括& 操作符)生成一個T 的指針類型的指針, 指向數(shù)組的第一成員。

7. 我如何聲明一個數(shù)組指針?

答:通常, 你不需要。當人們隨便提到數(shù)組指針的時候, 他們通常想的是指向它的第一個元素的指針。
考慮使用指向數(shù)組某個元素的指針, 而不是數(shù)組的指針。類型T 的數(shù)組蛻變成類型T 的指針, 這很方便;  
在結果的指針上使用下標或增量就可以訪問數(shù)組中單獨的成員。而真正的數(shù)組指針, 在使用下標或增量時, 會跳過整個數(shù)組,  
通常只在操作數(shù)組的數(shù)組時有用—— 如果還有一點用的話。如果你真的需要聲明指向整個數(shù)組的指針,  
使用類似“int (*ap)[N];”這樣的聲明。其中N 是數(shù)組的大小。如果數(shù)組的大小未知, 原則上可以省略N, 但是這樣生成的類型,  
“指向大小未知的數(shù)組的指針”, 毫無用處。

8.當我向一個接受指針的指針的函數(shù)傳入二維數(shù)組的時候, 編譯器報錯了,這是怎么回事?

答:數(shù)組蛻化為指針的規(guī)則不能遞歸應用。數(shù)組的數(shù)組(即C 語言中的二維數(shù)組) 蛻化為數(shù)組的指針, 而不是指針的指針。
數(shù)組指針常常令人困惑, 需要小心對待; 如果你向函數(shù)傳遞二位數(shù)組:
int array[NROWS][NCOLUMNS];
f(array);
那么函數(shù)的聲明必須匹配:
void f(int a[][NCOLUMNS])
{ ... }
或者
void f(int (*ap)[NCOLUMNS]) /* ap 是個數(shù)組指針*/
{ ... }
在第一個聲明中, 編譯器進行了通常的從“數(shù)組的數(shù)組” 到“數(shù)組的指針” 的隱式轉換; 第二種形式中的指針定義顯而易見。
因為被調函數(shù)并不為數(shù)組分配地址,所以它并不需要知道總的大小, 所以行數(shù)NROWS 可以省略。但數(shù)組的寬度依然重要,
所以列維度NCOLUMNS (對于三維或多維數(shù)組, 相關的維度) 必須保留。
如果一個函數(shù)已經(jīng)定義為接受指針的指針, 那么幾乎可以肯定直接向它傳入二維數(shù)組毫無意義。


9. 我的strcat() 不行.我試了char *s1 = "Hello, "; char *s2 = "world!";  
char *s3 = strcat(s1, s2); 但是我得到了奇怪的結果。

答:這里主要的問題是沒有正確地為連接結果分配空間。C 沒有提供自動管理的字符串類型。
C 編譯器只為源碼中明確提到的對象分配空間(對于字符串, 這包括字符數(shù)組和串常量)。
程序員必須為字符串連接這樣的運行期操作的結果分配足夠的空間,  

常可以通過聲明數(shù)組或調用malloc() 完成。strcat() 不進行任何分配; 第二個串原樣不動地附加在第一個之后。
因此, 一種解決辦法是把第一個串聲明為數(shù)組:
char s1[20] = "Hello, ";
由于strcat() 返回第一個參數(shù)的值, 本例中為s1, s3 實際上是多余的; 在strcat() 調用之后, s1 包含結果。
提問中的strcat() 調用實際上有兩個問題: s1 指向的字符串常數(shù), 除了空間不足以放入連接的字符串之外,  
甚至都不一定可寫。


10. 那么返回字符串或其它集合的正確方法是什么呢?

答:返回指針必須是靜態(tài)分配的緩沖區(qū), 或者調用者傳入的緩沖區(qū),  
或者用malloc() 獲得的內存, 但不能是局部(自動) 數(shù)組。

11. 我有個程序分配了大量的內存, 然后又釋放了。但是從操作系統(tǒng)看,內存的占用率卻并沒有回去。

答:多數(shù)malloc/free 的實現(xiàn)并不把釋放的內存返回操作系統(tǒng), 而是留著供同一程序的后續(xù)malloc() 使用。

12. calloc() 和malloc() 有什么區(qū)別?利用calloc 的零填充功能安
全嗎?free() 可以釋放calloc() 分配的內存嗎, 還是需要一個cfree()?

答:calloc(m, n) 本質上等價于:
p = malloc(m * n);
memset(p, 0, m * n);
填充的零是全零, 因此不能確保生成有用的空指針值或浮點零值free()  

可以安全地用來釋放calloc() 分配的內存。

13. 我認為我的編譯器有問題: 我注意到sizeof('a') 是2 而不是1 (即,不是sizeof(char))。

答:可能有些令人吃驚, C語言中的字符常數(shù)是int 型, 因此sizeof('a') 是sizeof(int),這是另一個與C++ 不同的地方。

14. 為什么聲明extern int f(struct x *p); 報出了一個奇怪的警告信息“結構x 在參數(shù)列表中聲明”?

答:與C 語言通常的作用范圍規(guī)則大相徑庭的是, 在原型中第一次聲明(甚至提到)的結構不能和同一源文件中的其它結構兼容,  
它在原型的結束出就超出了作用范圍。要解決這個問題, 在同一源文件的原型之前放上這樣的聲明:
struct x;
它在文件范圍內提供了一個不完整的結構x 的聲明, 這樣, 后續(xù)的用到結構x的聲明至少能夠確定它們引用的是同一個結構x。


15. 我不明白為什么我不能象這樣在初始化和數(shù)組維度中使用常量:const int n = 5; int a[n];

答:const 限定詞真正的含義是 “只讀的”; 用它限定的對象是運行時 (同常) 不能被賦值的對象。
因此用 const 限定的對象的值并不完全是一個真正的常量。
在這點上 C 和 C++ 不一樣。如果你需要真正的運行時常量, 使用預定義宏 #define(或enum)。

16. 我能否把 main() 定義為 void, 以避免擾人的 “main無返回值”警告?

答:不能。main() 必須聲明為返回 int, 且沒有參數(shù)或者接受適當類型的兩個參數(shù)。
如果你調用了 exit() 但還是有警告信息, 你可能需要插入一條冗余的 return語句
(或者使用某種 “未到達”指令, 如果有的話)。很多書不負責任地在例子中使用 void main(),  
并宣稱這樣是正確的。但他們錯了。


17. #pragma 是什么, 有什么用?

答:#pragam 指令提供了一種單一的明確定義的 “救生艙”, 可以用作各種 (不可移植的) 實現(xiàn)相關的控制和擴展:
源碼表控制、結構壓縮、警告去除 (就像 lint 的老 /* NOTREACHED */注釋), 等等。

18. “#pragma once” 是什么意思?我在一些頭文件中看到了它。

答:這是某些預處理器實現(xiàn)的擴展用于使頭文件自我識別; 它跟#ifndef技巧等價, 不過移植性差些。


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99免费在线观看视频 | 久久精品二区 | 精品国产免费一区二区三区演员表 | 日韩高清一区二区 | 亚洲精品免费视频 | 欧美激情精品久久久久久 | 欧美日韩精品一区二区三区蜜桃 | 在线视频一区二区 | 国产乱码高清区二区三区在线 | 大伊人久久 | 亚洲国产成人精品女人久久久 | 国产一区二区三区久久久久久久久 | 日韩一区二区在线免费观看 | 国产乱码精品一区二区三区忘忧草 | 国产日韩欧美另类 | 一区二区三区韩国 | 免费在线国产视频 | 精品国产一区二区三区久久 | 毛片久久久| 国产夜恋视频在线观看 | 国产亚洲一区二区三区 | 日本人和亚洲人zjzjhd | 亚洲一区视频在线 | 成人一级视频在线观看 | 中文字幕成人av | 91麻豆精品国产91久久久久久久久 | 久久久一区二区三区 | 国产视频欧美 | 精品乱码一区二区 | 国产精品自拍av | 国产精品久久久久久久久久 | 91大神在线看 | 精品国产18久久久久久二百 | 欧美日韩中文字幕在线 | 羞羞视频一区二区 | 日韩成人免费视频 | 成人1区| 色男人的天堂 | 中文字幕一区二区三区在线视频 | 99久久久国产精品 | 黄毛片 |