C語言複習

好久沒有看C語言了 從大一上學期開始學C,隔了這麼長時間快到找工作的時候纔想起看看

哎,自己真是夠懶的,

看到了些知識點 都忘記了 悲催  做了幾道題都不小心做錯了  這麼簡單的題都錯  那麼筆試面試怎麼辦  貼出來自勉,以示警示


1. 判斷int x = 0xaffbc;x的結果是(  D ) 。
A.賦值非法  B.溢出  C.爲affb  D.爲ffbc


2.記住A的ascll碼65  a 97 0 48


3.並不是任何對象都可以作爲左值的,運算表達式和常變量就不能作爲左值。任何左值都可做右值。


4.賦值表達式具有計算和賦值雙重功能。程序中的計算功能主要是由賦值語句來完成。


5.C語言的賦值語句與其他高級語言的賦值語句之間的差異:
  (1) C語言中的賦值號“=”是一個運算符,在其他大多數語言中賦值號不是運算符。 
  (2) 要區別賦值表達式和賦值語句。其他多數高級語言沒有“賦值表達式”這一概念。


printf是C語言提供的輸出函數;這句話是錯誤的  printf函數並不是C語言的一部分 C語言本身並沒有輸入輸出函數


6.已有定義,int a=5,b=6,c=7,d=8,m=2,n=2,則邏輯表達式(m=a>b) && (n=c>d)運算後,n的值爲()
解:因爲m=a>b值爲1  因此&&後面的表達式不執行計算  因此n還是爲2


7.break語句不能用於循環語句和switch語句之外的任何其他語句中。


8.設有程序段
 int k=10;
 while(k=0)k=k-1;
 這下面描述中正確的是___C______.
 (A)while循環執行10次         (B)循環是無限循環
 (C)循環體語句一此也不執行      (D)循環體語句執行一次
 雖然賦值爲真   但是k的值還是爲0 所以一次也不執行


9.下面程序的執行結果是_____B_____。
#include<stdio.h>
void main()
{
int y = 10;
do 
y - -;
while(y--);
printf(" %d \n" , y--);
}
(A)程序錯誤       (B)死循環      (C)-1   (D)0
這是一個死循環 while(9->7->5->3->1->-1) 


10.下面程序段的運行結果是____C______.
  int n=0;
  while(n++<=2);
printf("%d",n);
(A)2   (B)3  (C)4   (D)有語法錯




11.定義數組元素的個數必須使用常量表達式,而不能使用變量。
int i,j;  a[i][j]  這樣是不對的


12.如果對數組全部元素賦初值,第一個下標可省略,但第二個下標不可省略。       
可寫成  a[ ][4]={0,1,3,1,2,1,0,2,1,1,2,0};


13.強調:字符串實際佔有單元的數量等於字符串長度+1。
定義時應注意考慮元素總個數應比實際長度多1。


14.scanf("%s",a);   
只能輸入不包括空格、\t和\n的字符串;空格、跳格和回車是輸入數據的結束標誌.
若要輸入空格,用gets函數;
數組名前不加 &符號。


15.char str[10];str="string"; 這樣的賦值方式是不正確的


16.strcmp函數  strcmp(s1,s2) = 0 s1 ==s2
          = 正整數  s1>s2
  = 負整數  s1<s2


17.char c[10];c[10] = "string";//這樣賦值是不正確的


18.. 數組char myArray[6]=”long a”,則printf("%s",myArray)的輸出結果是(D)
A. long a  B. long  C. lon  D. 以上都不對
//因爲沒有遇到'\0'讀取就不會結束  也可能是A  但是後面跟着別的時候就不是A了
eg:char c[6] = "long a";
    char * f="sdfjsdf";
    printf("%s",c);  最後輸出的就不是A




19.C語言不可以函數嵌套定義


20.如果實參表列包括多個實參,對實參求值的順序並不是確定的,有的系統按自左至右順序求實參
的值,有的系統則按自右至左順序。例如:
  printf(“%d, %d”,i, ++i);
若i的原值爲3,在 VC++ 6.0環境下運行的結果不是“3,4”,而爲“4,4”。因爲按自右而左順序,求
++i得4,再向左進行,此時的i已是4了。


21.函數的“定義”和“聲明”不是一回事
函數的定義是指對函數功能的確立,包括指定函數名,函數值類型、形參及其類型、函數體等,
它是一個完整的、獨立的函數單位。函數的聲明的作用則是把函數的名字、函數類型以及形參的類型、
個數和順序通知編譯系統,以便在調用該函數時系統按此進行對照檢查。它不包含函數體。 


22.全局變量:
在函數之外定義的變量是外部變量
有效範圍爲從定義變量的位置開始到本源文件結束。
聲明時默認初始值爲0;
在各個函數執行時都可能改變全局變量的值


23.所謂靜態存儲方式是指在程序運行期間由系統分配固定的存儲空間的方式。
動態存儲方式則是在程序運行期間根據需要進行動態的分配存儲空間的方式。
這個存儲空間可以分爲三部分:
   1.程序區 2.靜態存儲區 3.動態存儲區
在C語言中每一個變量和函數有兩個屬性:數據類型和數據的存儲類別。




24.代碼區:存放程序代碼
靜態區:存放全局變量/數據和靜態變量/數據
堆區:取放動態數據
棧區:存放局部變量/數據


25.自動存儲變量存放在棧區
auto
自動存儲變量存放在棧區
 進入聲明的塊時生成,在結束塊時刪除 
 函數的參數和局部變量都是自動存儲類 
 自動存儲是變量的默認狀態


26.靜態變量:static
1. 靜態局部變量屬於靜態存儲類別,在靜態存儲區內分配存儲單元。
在程序整個運行期間都不釋放。而自動變量(即動態局部變量)屬於動態存儲類別,
佔動態存儲區空間而不佔靜態存儲區空間,函數調用結束後即釋放。
2. 對靜態局部變量是在編譯時賦初值的,即只賦初值一次,在程序運行時它已有初值。
以後每次調用函數時不再重新賦初值而只是保留上次函數調用結束時的值。
3.如在定義局部變量時不賦初值的話,則對靜態局部變量來說,
編譯時自動賦初值0(對數值型變量)或空字符(對字符變量)。而對自動變量來說,
如果不賦初值則它的值是一個不確定的值。
4. 雖然靜態局部變量在函數調用結束後仍然存在,但其他函數不能引用它。


27.寄存器變量(register):
變量的值是存放在內存中的。當程序中用到哪一個變量的值時,
由控制器發出指令將內存中該變量的值送到運算器中。 經過運算器進行運算,如果需要存數,
再從運算器將數據送到內存存放。 


28.自動變量存儲在動態存儲區;靜態局部變量存儲在靜態存儲區;寄存器存儲在CPU中的寄存器中。


29.extern 關鍵字:
在一個文件內擴展外部變量的作用域
#include <stdio.h>
int max(int,int);                //函數聲明
void main( )
 {     extern int a,b;            //對全局變量a,b作提前引用聲明
       printf(“%d\n”,max(a,b));
 }
int a=15,b=-7;                  //定義全局變量a,b
int max(int x,int y)
 {int z;
  z=x>y?x:y;
  return z;
 }
運行結果如下:
15
在main後面定義了全局變量a,b,但由於全局變量定義的位置在函數main之後,因此如果沒有程序的第5行,
在main函數中是不能引用全局變量a和b的。現在我們在main函數第2行用extern對a和b作了提前引用聲明,
表示a和b是將在後面定義的變量。這樣在main函數中就可以合法地使用全局變量a和b了。如果不作extern聲明,
編譯時會出錯,系統認爲a和b未經定義。一般都把全局變量的定義放在引用它的所有函數之前,
這樣可以避免在函數中多加一個extern聲明




30.用extern將外部變量(全局變量)的作用域擴展到其他文件。


31.將外部變量的作用域擴展到其他文件 
 //Ch7_1.cpp
int num =3;
….
//Ch7_2.cpp
extern int num;
編譯系統由此知道num是一個已在別處定義的外部變量,它先在本文件中找有無外部變量num,如果有,
則將其作用域擴展到本行開始。如果本文件中無此外部變量,則在程序連接時從其他文件中找有無外部變量num,
如果有,則把在另一文件中定義的外部變量num的作用域擴展到本文件,在本文件中可以合法地引用該外部變量num。




32.將外部變量的作用域限制在本文件中 
在程序設計中,某些外部變量只限於被本文件引用,而不能被其他文件引用。這時可以在定義外部變量時加
一個static聲明。
例如:
file1.c                           file2.c
static int A;                   extern int A; // Error!
void main ( )                  void fun (int n)
{                                      {…
…                                    A=A*n;

//就是說如果一個變量是static(靜態的),那麼它就不能使用extern引用




33.用static 聲明一個變量的作用是:
(1) 對局部變量用static聲明,把它分配在靜態存儲區,該變量在整個程序執行期間不釋放,
其所分配的空間始終存在。
(2) 對全局變量用static聲明,則該變量的作用域只限於本文件模塊(即被聲明的文件中)


34.內部函數:
如果一個函數只能被本文件中其他函數所調用,它稱爲內部函數。在定義內部函數時,
在函數名和函數類型的前面加static。即
static 類型標識符 函數名(形參表)
例如:   static int fun ( int a , int b )


35.外部函數
(1)定義函數時,如果在函數首部的最左端加關鍵字extern,則表示此函數是外部函數,可供其他文件調用。
例如,函數首部可以寫爲extern int fun (int a, int b),這樣,函數fun就可以爲其他文件調用。
如果在定義函數時省略extern,則隱含爲外部函數。
(2) 在需要調用此函數的文件中,用extern對函數作聲明,表示該函數是在其他文件中定義的外部函數 


36.一個變量除了數據類型以外,還有3種屬性: 
(1)作用域:  指程序中可以引用該變量的區域。 
(2)存儲類別 : auto,static,register和extern 4種存儲類別。
(3) 存儲期 : 指變量在內存的存儲期限


37.變量小結:
(1) 從作用域角度分
局部變量
靜態局部變量(離開函數,值仍保留)
自動變量,即動態局部變量(離開函數,值就消失)
寄存器變量(離開函數,值就消失)
形式參數(可以定義爲自動變量或寄存器變量)
全局變量
靜態外部變量(只限本文件引用)
外部變量(即非靜態的外部變量,允許其他文件引用)




38..在C語言中,函數類型的定義可以是默認類型,此時函數值的默認類型是(int )。


39.下列哪一個存儲類別只用於全局變量( D )
A. auto B. static C. register D. extern(只用於全局變量)


40.下列有關extern 關鍵字的說明錯誤的是( D )
A. extern 可以改變同一個文件中的全局變量的作用域
B. extern 可以使得一個文件中的函數對其他文件可見
C. extern不能將靜態外部變量的作用域擴展到其他文件
D. extern 可以用來定義一個外部變量(錯誤,不是定義外部變量)


41.//這個地方有個結合性的問題  運算符的優先級
自右向左
*p++: 取p所指向單元的數據作爲表達式的值,然後使p指向下一個單元;//這個一定要注意
 (*p)++:取p所指向單元的數據作爲表達式的值,然後使該單元的數據值增1;
*++p: 使p指向下一個單元,然後取該單元的數據作爲表達式的值;
++*p:將p所指向單元的數據增1並作爲表達式的值;


42.int (*p)[4]; ---p是一個指針變量,它指向包含4個整型元素的一維數組


43.char string1[] ="I love China!";
char * string2 ="I love China!";
string1[i]=‘A’; //允許,因爲string1[i]有可修改的內存單元
string1=“xyz”; //不允許,因爲string1是常量指針
string2[i]=‘A’; //不允許,因爲string2指向常量區
string2=“xyz”; //允許,因爲string2本身是指針變量
根本原因:存儲位置(是否有可修改的內存單元)




44.字符數組和字符指針變量的區別
(1)字符數組由若干元素組成,每個元素中放一個字符,字符指針變量中存放的是地址(字符串第1個字符的地址),
而不是將字符串放到字符指針變量中。
(2) 賦值方式
對字符數組只能對各個元素賦值。
 char  str[20] = “hello”;
str=″I love China!″; // error
字符指針變量  
char*a = 0;      a=″I love China!″;     
(3) 初始化方式
對字符指針變量賦初值:
char *a=″I love China!″;
等價於     char*a = 0;a=″I love China!″;
對數組的初始化:
char  str[]=″I love  China!″;
不能等價於char str[20];str[ ]=″I love China!″;
(4) 內存分配 :定義一個字符數組,在編譯時爲它分配內存單元,  
它有確定的地址和連續的內存空間。
定義一個字符指針變量,給指針變量分配內存單元,  
在其中可以放一個字符變量的地址。  
(5) 指針變量的值是可以改變的,數組名爲指針常量,不能改變!
(6) 字符數組中各元素的值是可以改變的,字符指針變量指向的字符串中的內容是不變的(不能對字符串常量再賦值)。 
char a[]=”House”;
char *b=” House”;
a[0]=’h’;              //r取代u   
b[2]=’r’;              //非法,字符串常量不能改變  


45.不能通過改變形參指針變量的值而使實參指針變量的值改變。


46.指向函數的指針
含義:可以定義一個指向函數的指針變量,用來存放某一函數的起始地址,這就意味着此指針變量指向該函數。
形式:數據類型 (*指針變量名)(函數參數表列)例如: int  (*p)(int, int);
作用:調用一個函數兩種方式:通過函數名  通過指向函數的指針變量  指向函數的指針也可以作爲函數的參數


47.//多重指針
指向指針型數據的指針變量,簡稱指向指針的指針   類型名**指針名;




48.全局變量是分配在內存中的靜態存儲區的,非靜態的局部變量(包括形參)是分配在內存中的動態存儲區的,
這個存儲區是一個稱爲棧(stack)的區域。
C語言還允許建立內存動態分配區域,以存放一些臨時用的數據,這些數據是臨時存放在一個的特別的自由存儲區,
稱爲堆(heap)區。
堆是內存空間,堆允許程序在運行時(而非編譯時)動態申請某個大小的內存空間,需要時隨時開闢,不需要時隨時釋放。


49.指針指向多維數組是要注意的事項:
int a[3][4]  a是數組的起始地址也是第一列的起始地址  a+1是數組第二列的起始地址  a+i 是i+1列的起始地址
eg;a的值是2000  那麼 a + 1 的值應該注意計算 2000 + 2 × 4 = 2008 (每個int佔的字節數 × 列數)
int * p = a; p++ 這時p是&a[0][1]的值  因爲p是指向int的指針  p++會移動一個int  所以會指到&a[0][1]上
另一種  int (*p)[4]; p = a;
這是一個指向包含四個整型元素的一維數組,因此p++會引動2×4個int 所以p直接指到&a[1][0]上
int (*p)[4] 表示*p有四個元素,每個元素爲整型,也就是p所指向的對象是有4個整型元素的數組,即p是指向
一維數組的指針
可以這樣理解  int a[3][4] int (*p)[4]  所以p指向a p+1指向a[1]


50.文件指針
在緩衝文件系統中,每個被使用的文件都要在內存中開闢一FILE類型的區,存放文件的有關信息.
查看stdio.h中文件類型聲明:typedef struct{…}  FILE; 
文件型指針變量:
FILE  *fp;在標準輸入輸出庫中,系統定義了三個FILE型的指針變量:
1.stdin (標準輸入文件指針)
2.stdout (標準輸出文件指針)
3.stderr (標準錯誤文件指針)




51.#define  宏替換隻對記號進行,對括在引號中的字符串不起作用
宏定義可以帶參數
#define square(x) x * x  int temp = square(z+ 1);  會替換成  z +1 × z + 1 = 2 × z + 1


52.const用於聲明可以存放在存儲器中的對象,並可能提高優化的可能性
volatile用於強制某個實現屏蔽可能的優化





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章