程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> C語言中容易被忽略的細節(第四篇)

C語言中容易被忽略的細節(第四篇)

編輯:關於C

前言:本文的目的是記錄C語言中那些容易被忽略的細節。我打算每天抽出一點時間看書整理,堅持下去,今天是第一篇,也許下個月的今天是第二篇,明年的今天又是第幾篇呢?……我堅信,好記性不如爛筆頭。第四篇了,fight~...


第一篇鏈接:C語言中容易被忽略的細節(第一篇)

第二篇鏈接:C語言中容易被忽略的細節(第二篇)

第三篇鏈接:C語言中容易被忽略的細節(第三篇)


1、void*類型的指針不能參與算術運算,只能進行賦值、比較和sizeof操作的原因?

指針的算術運算還要包含指針所指對象的字節數信息。


2、不能把“&”單獨用於一個非變量的東西。不能對字面常量使用“&”來取其地址,因為字面常量保存在符號表中,沒有地址概念。數組名是一個指針常量,不能修改數組名的值。例如以下語句1與語句2是等價的:

int a[10];                  //語句1
int *const a;               //語句2

int b[3][4];                //語句1
int (*const b)[4];          //語句2

int c[3][4][5];             //語句1
int (*const c)[4][5];       //語句2


3、return 0與exit(0)的幾點區別

(1)exit結束正在運行的整個程序,只要調用exit就結束,它將參數返回給OS,把控制權交給操作系統;return退出當前函數,返回函數值,把控制權交給調用函數;

(2)exit是系統調用級別,它表示一個進程的結束;return是語言級別的,它表示調用堆棧的返回。

(3)main函數結束時也會隱式地調用exit函數,它將刪除進程使用的內存空間,同時把錯誤信息返回給父進程。

(4)main函數返回一個整型值與該值調用exit是等價的。


4、static修飾符是一個能夠減少命名沖突的有用工具。例如:static int a;將a的作用域限制在一個源文件內,對於其他源文件,a是不可見的。可以在多個源文件中定義同名的變量a,只要所有的變量a都被定義為static,或者僅僅只有其中一個變量不是static。static修飾符也適用於函數。


5、C語言允許程序員寫操作前控制產生的輸出數據量,這種控制能力是通過庫函數setbuf實現的。例如:setbuf(stdout, buf);語句將通知輸入/輸出庫,所有寫入到stdout的輸出都使用buf作為輸出緩沖區,直到buf緩沖區被填滿或程序員直接調用fflush,buf緩沖區的內容才實際寫入到stdout中。緩沖區的大小由系統頭文件中的BUFSIZ定義。《C陷阱與缺陷》中有一個例子:

#include 

int main(void)
{
	char c;
	char buf[BUFSIZ];
	setbuf(stdout, buf);
	while ((c = getchar()) != EOF)
		putchar(c);

	return 0;
}

以上程序是錯誤的。buf緩沖區最後一次被清空是在main函數結束之後,作為程序交回控制給操作系統之前C運行時庫所必須進行清理工作的一部分。在此之前buf字符數組已經被釋放了。修改的方法有3種:

(1)定義緩沖數組為靜態數組static char buf[BUFSIZ];

(2)將緩沖數組拿到main函數外;

(3)動態分配緩沖區,程序中並不主動釋放分配的緩沖區。setbuf(stdout, malloc(BUFSIZ));

備注:

(1)由於緩沖區是動態分配的,所以main函數結束時並不會釋放該緩沖區,這樣C運行時庫進行清理工作時就不會發生緩沖區已釋放的情況。

(2)如果malloc調用失敗,返回NULL指針,此時標准輸出不需要進行緩沖。

(3)對於由寫操作打開的文件,調用fflush將導致輸出緩沖區的內容被實際地寫入該文件。


6、為什麼向函數傳遞多維數組時候不需要說明第一維長度而必須說明其他維長度?

(1)數組元素在內存中按照“行優先”規則存儲,需要列數確定一行有多少元素;

(2)編譯器在計算元素地址時不需要數組第一維的長度,但需要所有其他維的長度信息;

(3)C/C++不對數組進行越界訪問檢查,對編譯器來說不需要知道第一維的長度。


7、C語言將多維數組轉換為數組指針。以下4種表達方式是等價的:
a[i][j];
*(a[i] + j);
(*(a + i))[j];
*(*(a + i) + j);

8、在語義上,下標操作符返回的是一個元素的引用。例如語句1和語句2是等價的:

//語句1
a[3] = 100;		

//語句2
int &ri = a[3];
ri = 100;

9、不能使用一個元素類型的指針來接收動態創建的多維數組的返回地址,因為一個多維數組在語義上並不等價於一個指向其元素類型的指針,它等價於一個“指向數組的指針”。例如以下用法是正確的:

char *q = new char[5];
delete []q; 

char (*p)[4] = new char[5][4];
delete []p;

10、(1)標號(lable)是具有函數作用域的唯一一種標識符。無論標號定義在函數哪行,函數內嵌套多深,它都能在函數體內任何一個地方訪問到。標號一般用在goto語句中,如果goto語句沒有使用到該標號,那麼該標號將被忽略。(2)當局部變量與某一個全局變量同名時,在函數內部將遮蔽該全局變量。此時在函數內部可通過一元作用域解析運算符來引用全局變量,如::a。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved