C语言位于30到100之间的一个奇数,《帮你度过C语言新手阶段》系列之三
真正深入學習C語言已經3年有余了。不過還是有很多知識點沒有記下來,在此總結一下,也幫助C語言新手度過新手難關。
如果你已經認真閱讀過譚浩強C,那么復習如下知識大約需要1個小時:)
本篇是《幫你度過C語言新手階段》系列的最后一篇。
第三十五關:
char *a;
scanf(”%s”,a);
上述程序是絕對禁止的,是錯誤的。正確的寫法如下:
char *a,str[10];
a=str;
scanf(”%s”,a);
第三十六關:
用指針變量來指向一個格式字符串,可以用它來代替printf函數中的格式字符串,如:
char *format;
format=”a=%d,b=%f\n”;
printf(format,a,b);
其實format也可以定義為char format[]形式,但不建議,因為用指針的話,可以很方便指向另一個格式字符串。
第三十七關:
聲明一個指向函數的指針:int (*p)(); 定義p是一個指向函數的指針變量,此函數帶回整型的返回值。
所以定義指向函數的指針時,只需要注意返回值相匹配即可,而形參部分不需要考慮。
注意,如果寫成int *p();由于()的優先級高于*,就變成了聲明一個函數,它的返回值是指向整型的指針。
使用p的方法:
int max(int a, int b);
p=max;
num=(*p)(3,5);
在一個程序中,一個指針變量可以先后指向返回類型相同的不同函數。
第三十八關:
用指向函數的指針做函數參數:
sub(int (*x1)(int),int (*x2)(int,int));
這里的參數列表可以選擇不寫(不推薦此種寫法),即sub(int (*x1)(),int (*x2)());,不過如果寫參數,就必須要寫全寫正確。
雖然C允許在參數中用()省略掉形參表,但是,從一個良好的程序風格來看,還是應當禁止這樣的使用。
第三十九關:
指針數組的定義:
char *name[]={”follow me”,”basic”,”great wall”,”fortran”,”computer”};
name代表該指針數組的首地址,name+i是name[i]的地址。
程序舉例:
char *name[]={”follow me”,”basic”,”great wall”,”fortran”,”computer”};
char **p;
int i;
for (i=0;i<5;i++){
p=name+i;
printf(”%s\n”,*p);
}
第四十關:
struct定義一定不要忘了最后的分號:
struct 結構體名
{成員列表};
在引用結構體變量的域時,*p.num相當于*(p.num),因為.的優先級是最高的!
第四十一關:
共用體的定義為:
union 共用體名稱
{
成員列表;
}變量列表;
例如:
union data
{
int i;
char ch;
float f;
}a,b,c;
共用體變量所占的內存長度是最長的成員的長度。
在引用共用體變量時應十分注意當前存放在共用體變量中的究竟是哪一個成員。
&a、&a.i、&a.ch、&a.f都是同一個地址值。
不能對共用體變量名賦值,也不能企圖引用變量名得到一個值,更不能在定義共用體時對它初始化。
第四十二關:
聲明枚舉類型的舉例:
enum weekday{sun,mon,tue,wed,thu,fri,sat};
聲明了枚舉類型之后,就可以用枚舉類型來定義變量:
enum weekday workday,weekend;
對于枚舉元素,C語言編譯時的順序使它們的值為0,1,2…
如
workday=mon;
printf(”%d”,workday);
則會顯示1
當然你可以改變這種現狀:
enum weekday{sun=7,mon=1,tue,wed,thu,fri,sat}workday,weekend;
此時,sun=7,mon=1,tue=2…以此類推
一個整數不能直接賦值給一個枚舉變量,而要先進行類型轉換:
workday=(enum workday)2;
第四十三關:
用typedef聲明結構體類型:
typedef struct
{
int month;
int day;
int year;
}DATE;
這樣就聲明了新的類型DATE,然后就可以用DATE來聲明結構體變量了。如DATE birthday;DATE *p;
用typedef聲明數組類型:
typedef int NUM[100];
然后就可以用NUM來定義數組變量:
NUM n;
第四十四關:
C語言的位運算有6個運算符:
1 與&
2 或|
3 異或^
4 取反~
5 左移<<
6 右移>>
位運算的運算量只能是整型或字符型,不能是其他類型,否則會報錯。
按位與:用于清零或提取某一位
按位或:用于置1
異或:用于交換兩個整型值或兩個字符型值。如a=a^b;b=b^a;a=a^b;
取反:令最低位置1。如a=a&~1。此方法適用于在32位和64位機之間兼容。
左移:相當于乘以2,右補0。
右移:如果首位為0,則左補0;如果首位為1,則分為邏輯右移和算術右移兩種情況。
邏輯右移:左補0
算術右移:左補1
第四十五關:
位段的概念非常重要,在編寫網絡程序常會用到。
struct packet_data
{
unsigned a:2;
unsigned b:6;
unsigned c:4;
unsigned d:4;
int i;
}data;
當然也可以不恰好占滿一個字節,如
struct packet_data
{
unsigned a:2;
unsigned b:3;
unsigned c:4;
int i;
}data;
這樣的話a,b,c會占去2字節中的前9位,而后7位會空閑下來,而i會從另一個新字節開頭開始。
在引用位域時,要特別注意其最大值范圍,如占2位,那么最大值為3.
位段成員的類型只能指定為unsigned int或int型。
若要強制一個域從新字節開始,那么可以這樣:
unsigned a:1;
unsigned b:2;
unsigned :0;
unsigned c:3;
此時c會從一個新字節開始存儲。
位段可以用%d來輸出。
可以定義無名位段,表示這些位我不用:
unsigned a:1;
unsigned :2; //這兩位空間我不用
unsigned c:3;
第四十六關:
在緩沖文件系統中,有一個概念叫做“文件指針”。
在stdio.h中有關FILE結構體類型的聲明:
typedef struct
{
short level;??? //緩沖區滿或空的程度
unsigned flags;??? //文件狀態標志
char fd;??? //文件描述符
unsigned char hold;??? //如無緩沖區不讀取字符
short bsize;??? //緩沖區的大小
unsigned char *buffer;??? //數據緩沖區的位置
unsigned char??? *curp;??? //指針、當前的指向
unsigned istemp;??? //臨時文件,指示器
short token;??? //用于有效性檢查
}FILE;
可見,其實FILE也是一個由typedef定義過的類型,其本質是一個結構體類型,其中有很多域,存儲著和這個文件相關的各種各樣的信息。
在進行文件讀寫操作時,建議不要使用fprintf和fscanf函數,而盡量使用fread和fwrite函數。
over~
總結
以上是生活随笔為你收集整理的C语言位于30到100之间的一个奇数,《帮你度过C语言新手阶段》系列之三的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 四季感冒片的功效与作用
- 下一篇: 疏肝解郁最好中成药