C語言基礎 -7 常量

常量:在程序執行過程中值不會發生變化的量

分類:整型常量、字符常量、字符串常量、標識常量

整型常量: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宏是標識常量,執行過程中不可以放在賦值語句的左邊。

 

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