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)用於獲取位置指針的位置,相對於文件開頭。