程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> C語言中基礎小問題總結

C語言中基礎小問題總結

編輯:關於C
1、printf格式輸出函數 如果格式控制說明項數多於輸出表列個數,則會輸出錯誤數據; 如果輸出表列個數多於格式控制說明數,則多出數不被輸出。 %md,m指的是輸出字段的寬度。如果輸出字段位數小於m,則左端以空格補齊,若大於m,則按照實際位數輸出。 %-md,基本同上,只不過不同之處在於,空格在右端補齊 printf參數可以是常量,變量或表達式,VC++ 6.0中采用從右向左順序求值,從左向右輸出如 int x = 5;  printf("%4d%4d%4d", x, ++x, ++x); 輸出的是7,7,6. 而不是5,6,7 注意,不同的編譯器可能輸出不同結果,直接用gcc編譯結果為7,7,7 2、0-9數字轉為字符 數字為m,則m+‘0’即為m的字符形式‘m’ 3、小寫字母變為大寫字母 char c; c為小寫字母,則c-'a'+'A'即為對應的大寫字母 4、switch 如果找到匹配的case入口,則執行後面的語句,執行完語句之後,並不像if語句那樣退出,如果沒有遇到break語句,將逐條執行後面所有的case語句,不再進行條件判斷。 case入口後面的語句可以是一句,也可以是多句,並且不需要大括號。 5、字符數組存儲字符串 當char str[5]=new {"china"};時,程序會出問題,輸出的時候會在china後帶亂碼,這是因為china字符串後還有一位'\0',因此應該給str數組多一位。即char str[6]=new {"china"}; 且'\0'只表示字符串的結束,並不會輸出。 scanf("%s",str);不能存入空格,因為認為空格代表字符串的結束。gets(str);可以在字符串中間加入空格。 puts(str);在輸出字符串後自動加入換行 6、字符串操作函數 字符串拷貝函數:strcy(str1,str2); 將字符串str2拷貝到str1中。 字符串連接函數:strcat(str1,str2); 將str2連同'\0'一起連接到str1的最後一個字符(非'\0')後面,結果放在str1中。 字符串比較函數:strcmp(str1,str2); 比較str1和str2的大小,如果str1==str2,則返回0;如果str1>str2,則返回正整數;如果str1<str2,則返回負整數。 字符串長度函數:strlen(str); 返回字符串str的實際長度,不包括末尾的'\0'。 7、函數的參數和單向值傳遞 函數的參數分為實參和形參。形參出現在函數定義中,在整個函數體中使用,離開函數體則不能使用。實參出現在主調函數中,進入被調函數後,實參不能被使用。 形參只有被調用時才被編譯系統分配內存單元,在調用結束時候,編譯系統即刻釋放所分配的內存單元,因此形參只在函數內部有效,函數調用結束返回主調函數後則不能再使用; 單向傳值:只能把實參的值傳遞給形參,不能把形參的值反向傳遞給實參,叫做單向值傳遞。 因此,函數調用過程中,形參的值發生改變,實參的值不會改變 8、數組作為參數 數組名可以作為函數實參,這時候形參可以是數組或者指針。且形參是一維數組時候可以不指定長度。形參是二維數組時候,第一維大小可以省略,要指定第二維的大小。 9、變量的存儲方式 (1)局部變量 局部變量在每次函數調用時,系統會在內存的動態存儲區為他們重新分配內存單元,隨著函數的頻繁調用,某個變量的存儲位置會隨著程序的運行不斷變化,所以未賦值的局部變量的值是不確定的。函數中的局部變量不能作為返回值,因為函數結束後,局部變量要被回收。 (2)static類型 靜態變量在編譯的時候被分配內存、賦初值,並且只會被賦初值一次。未賦初值的靜態變量,系統自動賦初值0(或'0')。靜態變量在內存靜態存儲區占用固定的內存單元。即使它所在的函數調用結束,也不會釋放存儲單元,其值也會繼續保留,下次調用,會繼續使用該值。靜態變量分為靜態局部變量和靜態全局變量,靜態全局變量就是定義在函數體外的靜態變量,靜態局部變量就是定義在函數體內的靜態變量。 如下: #include<stdio.h> void f() {     static int a=0; //編譯時被賦初值,且整個過程只被賦初值一次     ++a;     printf("%-2d",a); } main() {     f();     f();     f(); } 以上程序的輸出結果為1 2 3 因為對static變量賦初值是在編譯時完成,而且只賦值一次,之後在調用函數不會執行賦初值操作,因此輸出1 2 3 ;若去掉static關鍵字,那麼結果就會變為1 1 1 ;由此看出,函數反復調用多次,局部變量每次都會被賦初值,而靜態變量只是在第一次被調用的時候賦初值。 此處特變注意:java中是沒有靜態局部變量的,只會有針對類的靜態全局變量。 (3)寄存器類型 定義形式: register 數據類型 變量名;寄存器類型局部變量的作用域、生存期與局部變量相同。 寄存器的個數有限,寄存器的存儲數據位數有限,所以寄存器類型的變量不能太多,而且有整型變量和字符型變量才能被定義為寄存器類型的局部變量。現在的優化系統可以自動的判斷把相關變量存到寄存器中。 (4)外部變量 10、編譯預處理 #include<文件名>和#include"文件名"的區別是:使用尖括號時,編譯預處理程序只在系統指定的文件夾中尋找;而使用雙引號,編譯預處理程序首先在當前文件所在的文件夾中尋找,如果找不到,則在系統指定的文件夾中再尋找。 11、&和* 優先級都屬於第二級,從右向左運算 12、*與++、--運算符 都屬於第二級,從右向左計算 *p++  等價於  *(p++) *++p  等價於  *(++p) 13、[  ]和* [  ]優先級高於* 13、二維數組的行地址和列地址 int a[2][2]={1,2,3,4}; 則a為首地址,第一行首地址;*a和a[0]都是第一行第一個元素的地址 a+1為第二行行地址 *(a+1)為第二行第一個元素地址,a[1]也為第二行第一個元素地址 14、指向數組的指針變量(數組指針) int *(p) [4];表示一個指向含有4個int元素的數組的指針。 (1)p指向一維數組的首行地址 main() {     int a[2]={1,2};     int (*p)[2];     p=&a;//p是指向數組的指針,即行指針,因此要用&a給其賦值,&a為數組地址     printf("%d\n",**p);//取第一個元素,其中p為行地址,*p為元素地址,**p為元素值     printf("%d\n",*(*p+1));//取第二個元素     //也可以如下取值     printf("%d\n",(*p)[0]);//(*p)可以取代a     printf("%d\n",(*p)[1]); } (2)p指向二維數組的首行地址 main() {     int a[2][2]={1,2,3,4};     int (*p)[2];     p=a;//p指向二維數組的首行地址     printf("%d\n",**p);//*p是元素的地址,**p則為元素內容     printf("%d\n",*(*(p+1)+1)); } 15、指針數組 int *p[4];表示一個數組中含有4個int型指針。 char *p[4];表示一個數組中含有4個char型數組,或則4個字符串 16、二維數組中的各個地址 int a[2][3]; 則a為首行地址,*a為首行第一個元素地址,**a為首行第一個元素的值 a+1為第二行地址,*(a+1)為第二行第一個元素的地址,**(a+1)為第二行第一個元素的值 *(a+1)與a[1]等價:都代表第二行第一個元素的地址 例子: main() {     int a[2][2]={1,2,3,4};     printf("a=%d\n",a);     printf("*a=%d\n",*a);     printf("**a=%d\n",**a);     printf("*a+1=%d\n",*a+1);     printf("a+1=%d\n",a+1);     printf("a[1]=%d\n",a[1]);     printf("a[1]+1=%d\n",a[1]+1);     printf("*a[1]=%d\n",*a[1]); } 17、字符指針變量在接受輸入字符串時,必須先開辟存儲空間 char *cp; scanf("%s",cp); 以上是錯誤的。 可以改為: char cp[20]; scanf("%s",cp); 或者 char *cp,str[20]; cp=str; scanf("%s",cp); 總之,一定要先開辟空間,再接受字符串 18、c和c++中的返回值不能是數組,java返回值可以是數組 19、指針函數和函數指針 指針函數:int * function(); 函數指針: int (*p) (); int max(int a,int b); p=max; int a=(*p)(2,3); 20、關於變量的生命周期 函數中定義的局部變量是不能作為返回值的,因為函數結束後,局部變量就被回收了。 21、結構體 結構體中可以嵌套結構體,但不能是其本身。且成員結構體的定義必須在主結構體之前。 22、malloc malloc函數位於stdlib.h中,函數原型為void * malloc(unsigned size); eg: struct student *p=(struct student *)malloc(sizeof(struct student)); 因為malloc返回的是一個void類型的指針,所以要強制轉換。 23、free 該函數原型為 void  free(void * ptr) 釋放有指針ptr指向的動態分配的內存空間。為保證動態存儲區的有效利用,當某個存儲空間不再使用時,就應該及時釋放它。   24、結構體和共用體 (1)結構體 結構體可以作為函數的參數和返回值。 結構體只有在初始化的時候才能直接用大括號{}形式賦值;當先聲明,後賦值時候,就只能單個元素賦值,不能再用大括號形式了。這個跟數組的賦值類似。舉例如下 struct student {     int bh;     char *name; }; struct student stu={1,'typ'};//是正確的 但是下面的是錯誤的 struct student stu; stu={1,"typ"};//是錯誤的 此時這能stu.bh=1;stu.name="typ" (2)共用體 共用體不能作為函數的參數和返回值 共用體不能同時存放,每一時刻只能存放一個成員,以最後一次存放的成員為有效成員。共用體的大小是最大元素所占用的大小; 共用體可以出現在結構體類型中,反之,結構體也可以出現在共用體的類型中 25、枚舉類型 enum color {red,green,blue}; enum color c=red; int i=red;//值為0 26、類型標識符的重定義 c語言中用關鍵字typedef來聲明新的類型名 typedef int INTEGER; INTEGER x,y; 等價於 int x , y; 又比如結構體定義: typedef struct {     int num;     char name[10];     float score; }student; student  stu1, stu2, *s; 另外,typedef只是進行類型重定義,只是為該類型命名一個別名,並不產生新的數據類型 27、位運算 包括(與、或、異或、取反)。 其中,位運算符進行運算時,數都是以補碼形式參加運算,且符號位參與運算。 異或:相同為0,不同為1 a^a=0;a^0=a;a^~a=1; 此處可以用異或來實現兩數的交換 a=a^b; b=b^a; a=a^b; 這樣避免引入臨時變量 28、移位運算 (1)a<<b,表示a的二進制值左移b位 (2)a>>b,表示a的二進制值右移b位 移位運算具體實現有3種形式: (1)循環移位:移入的位等於移出的位 (2)邏輯移位:移出的位丟失,移入的位取0 (3)算術移位:移出的位丟失,左移入的位取0,右移入的位取符號位,符號位保持不變 C語言的移位運算與具體的C編譯系統有關,如VC++6.0采用的是算術移位 注意:移位操作並不會改變原操作數的值。例如a>>2運算後,a的值保持不變,除非通過賦值a=a>>2來改變a的值。   29、文件 (1)C語言中文件是字節流文件. (2)C中為用戶定義的文件類型是FILE,FILE文件類型是結構體類型,FILE結構是用關鍵字typedef定義出的一種結構。 struct  _iobuf { char * _ptr; int _cnt; char *base; int _flag; int _file; ......... }; typedef struct  _iobuf  FILE; (3)文件打開與關閉 文件指針 = fopen("文件路徑\\文件名", "文件操作方式"); 操作方式分為r,w,a,r+,w+,a+ 如果fopen打開失敗,則返回NULL   如果緩沖區未滿512B,那麼不會寫到磁盤中,萬一程序異常終止,則緩沖區中數據丟失,導致文件不完整。只有對打開文件執行關閉操作時,才能強制把緩沖區中不足512B的數據寫到磁盤文件中,保證文件的完整性。fclose函數用來關閉文件 fclose(文件指針); 返回值是一個整數值,若為0,表示正常關閉,否則表示無法正常關閉文件。 (4)文件的輸入和輸出 讀寫一個字符:char fgetc(文件指針);EOF fputc(字符,文件指針) 讀寫一個字符串:fgets(字符串s,讀入字符個數n,文件指針)--->在中途遇到\n或者EOF停止,讀n-1個字符,在末尾加'\0';fputs(字符串,文件指針)--->字符串的結束標記不會寫入文件 格式化讀寫:fscanf(fp, "%d%s", &i, s)--->從文件中讀取數據保存到變量;fprintf(fp, "%d%c", j, c)--->按指定格式向文件寫入數據 成塊讀寫:fread(buffer,size,count,fp)和fwrite(buffer,size,count,fp) buffer是一個指針,fread()中表示存放“輸入數據”的變量首地址,fwrite()中表示存放“輸出數據”的變量首地址 size表示數據塊的字節數 count表示數據塊個數 fp文件指針 返回值都是count值 (4)其他文件操作的函數 feof(fp)判斷文件的末尾標志,到達末尾返回1,否則返回0 rewind(fp)用於定位,是文件的位置指針返回文件開頭。 fseek(fp, offset, base)用來控制文件內部位置指針移動。base是位置移動的基准點。offset是偏移量 ftell(fp)用於獲取位置指針的位置,相對於文件開頭。    
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved