常量:在程序執行過程中值不會發生變化的量
分類:整型常量、字符常量、字符串常量、標識常量
整型常量:1,790,76,52
實型常量:3.14,4.78
字符常量:由單引號引起來的單個字符或轉義字符,如'a','X','\n','\t','\015','\x7f'
字符串常量:由雙引號引起來的一個或多個字符組成的序列,如空字符''","a","abXY","abc\n\021\016"
變量:用來保存一些特定內容,並且在程序執行過程中值隨時改變的量
字符常量:#define
wesley@ubuntu:~/c$ cat define.c
#include <stdio.h>
#include <stdlib.h>
#define PI 3.14 //井號在預處理的時候就會被解決掉
//定義時用宏名,預處理時宏名就會被宏體替代
int main()
{
int a,b,c
a * PI;
b + PI;
c / PI;
exit(0)
}
預處理後的結果
gcc -E define.c //發現預處理後,宏名就被宏體替代了
int main()
{
int a,b,c
a * 3.14;
b + 3.14;
c / 3.14;
exit(0)
}
define 宏的定義:只負責宏體替代宏名,但不檢查語法,如下例,如果宏定義宏體沒加括號,則會導致執行結果/順序與期待的不同
gcc -E define.c
加括號後,返回正確結果
gcc -E define.c,發現執行順序已經被限定
wesley@wesley-VirtualBox:~/c/CH01$ cat define.c
#include<stdio.h>
#include<stdlib.h>
#define MAX(a,b) (a > b ? a: b)
int main()
{
int i = 5,j = 3;
printf("%d\n",MAX(i,j));
exit(0);
}
wesley@wesley-VirtualBox:~/c/CH01$ make define
cc define.c -o define
wesley@wesley-VirtualBox:~/c/CH01$ ./define
5
wesley@wesley-VirtualBox:~/c/CH01$ gcc -E define.c
int main()
{
int i = 5,j = 3;
printf("%d\n",(i > j ? i: j));
exit(0);
}
wesley@wesley-VirtualBox:~/c/CH01$ cat define2.c
#include<stdio.h>
#include<stdlib.h>
#define PI 3.1415926
#define MAX(a,b) ((a) > (b) ? (a): (b))
#define ADD (2+3) // #包含的部分,在預處理時就會被處理完畢, # define佔用的是編譯時間;運行的時候,實際上已經把所有的內容替換到程序中去,不會再用多餘時間
// 宏比較節省運行時間,適合於內核開發,講求效率
//寫應用層面,系統層面開發時,多用函數。比較追求穩定
int max(int a,int b) //函數在調用的位置會對當前的狀態進行壓棧保存,去指定函數執行/跳往另一個入口地址,會經歷一個壓棧/出棧,恢復現場的時間
{
return a > b ? a : b;
}
int main()
{
int i = 5,j = 3;
printf("i = %d\tj = %d\n",i,j);
printf("%d\n",MAX(i++,j++)); //此處返回了i,i自增一次,j沒有自增。 跟預期不同,爲什麼? 較大值會被執行了兩次。在標準c下無解,慎用
printf("i = %d\tj = %d\n",i,j);
exit(0);
}
wesley@wesley-VirtualBox:~/c/CH01$ gcc -E define2.c
int max(int a,int b)
{
return a > b ? a : b;
}
int main()
{
int i = 5,j = 3;
printf("i = %d\tj = %d\n",i,j);
printf("%d\n",((i++) > (j++) ? (i++): (j++))); // 較大值,比較時執行了一次,返回的時候又執行了一次自加
printf("i = %d\tj = %d\n",i,j);
exit(0);
}
wesley@wesley-VirtualBox:~/c/CH01$ make define2
cc define2.c -o define2
wesley@wesley-VirtualBox:~/c/CH01$ ./define2
i = 5 j = 3
6
i = 7 j = 4
wesley@wesley-VirtualBox:~/c/CH01$ cat define3.c
#include<stdio.h>
#include<stdlib.h>
#define PI 3.1415926
#define MAX(a,b) ((a) > (b) ? (a): (b))
#define ADD (2+3) // #包含的部分,在預處理時就會被處理完畢, # define佔用的是編譯時間;運行的時候,實際上已經把所有的內容替換到程序中去,不會再用多餘時間
// 宏比較節省運行時間,適合於內核開發,講求效率
//寫應用層面,系統層面開發時,多用函數。比較追求穩定
int max(int a,int b) //函數在調用的位置會對當前的狀態進行壓棧保存,去指定函數執行/跳往另一個入口地址,會經歷一個壓棧/出棧,恢復現場的時間
{
return a > b ? a : b;
}
int main()
{
int i = 5,j = 3;
printf("i = %d\tj = %d\n",i,j);
printf("%d\n",max(i++,j++));
printf("i = %d\tj = %d\n",i,j);
exit(0);
}
wesley@wesley-VirtualBox:~/c/CH01$ make define3
cc define3.c -o define3
wesley@wesley-VirtualBox:~/c/CH01$ ./define3
i = 5 j = 3
5
i = 6 j = 4
Define佔用的是編譯時間,在預處理階段,特點是一改全改,缺點是不檢查預防,只是單純的宏體替換
define宏是標識常量,執行過程中不可以放在賦值語句的左邊。