預處理指令、構建大型程式

GQH1000發表於2024-10-28

練習:編寫程式從鍵盤得到一個包含多個考試成績的字串,字串格式如下

10,20,30,40,50

計算所有考試成績的和並把結果顯示在螢幕上

練習:編寫一個模擬登入練習,一共給使用者三次登入機會,每次要求使用者輸入使用者名稱和密碼如果輸入的使用者名稱是admin密碼是123456就是正確的。登陸三次之後要給出提示。

指標陣列

指標陣列裡每個儲存區的型別都是指標,字元指標陣列裡包含多個字元型別的指標,每個指標可以代表一個字串。字元指標陣列可以用來表示多個相關字串,二維陣列也可以用來表示多個相關字串,通常使用字元指標陣列來記錄多個字串防止儲存區浪費。

主函式引數

主函式的第二個引數是一個字元指標陣列,其中每個指標代表一個字串。所有這些字串的內容都來自使用者輸入命令。主函式第一個引數是一個整數,表示第二個引數裡的指標個數。

練習:編寫程式解決雞兔同籠問題

頭和腳的數量應該從命令中獲得

./a.out 40 100

預處理指令

#define”預處理指令可以用來定義宏,宏可以用來給數字起名字,定義宏的時候要把宏名稱寫在前面,把它所代表的數字寫在後面。宏名稱通常由全英文大寫字元構成,宏名稱裡不包含空格。

#define 		PI		3.14f

用宏給數字起名字的時候不可以用賦值運算子,編譯器會把程式裡的所有宏名稱替換成它所代表的數字,可以在編譯命令裡使用-D選項決定宏名稱代表的數字。

編寫程式的時候有些數字只能在編譯的時候才能知道具體數值,程式中應該用宏名稱代表這種數字。宏還可以用來給計算公式起名字,計算公式裡包含未知數字,宏的引數用來表示計算公式裡的未知數字。

編譯器採用二次替換的方式處理帶引數的宏,宏的引數不一定代表數字所以沒有型別名稱。如果宏有多個引數也應該用逗號把相鄰的引數名稱分隔開。

宏與函式區別

宏不能使用自己的儲存區和函式之間進行資料交換,宏沒有形式引數也沒有用來存放返回值的儲存區,能當作數字使用的宏必須編寫為表示式(因為宏沒有用來存放返回值的儲存區),宏的引數可以直接代表函式的儲存區,對宏引數內容的修改就是對函式儲存區內容的修改。

練習:編寫一個宏用來計算兩個整數之間的差

因為宏沒有用來記錄返回值的儲存區,所以不能保證優先計算宏裡面的運算子。所有能當作數字使用的宏必須編寫在一對小括號中間,宏沒有形式引數所以不能保證優先計算引數裡面的運算子。編寫宏的時候所有能當作數字使用的引數也必須寫在小括號裡。不要把自增自減的結果作為宏的引數使用

編寫宏的時候可以使用一些特殊的符號,他們叫做宏運算子。

#是一個宏運算子,它可以把宏的一個引數轉換成字串字面值

##也是一個宏運算子,它可以把一個代表識別符號的引數連線其他內容得到一個新的識別符號

練習:編寫宏實現字元的大小寫轉換

點選檢視程式碼
#if 0
/*
 *字串練習
 *
 * */
#include<stdio.h>
#include<string.h>
int main() {
	char buf[30] = {0},tmp[10] = {0};
	int grade = 0;
	while(1) {
		printf("請輸入一個考試成績:");
		scanf("%d",&grade);
		if(grade >= 0 && grade <= 100) {
			sprintf(tmp,"%d,",grade);
			strcat(buf,tmp);
		}
		else {
			break;
		}
	}
	buf[strlen(buf) - 1] = 0; 		//最後一個成績後的逗號刪除
	printf("%s\n",buf);
	return 0;
}
#elif 0
/*
 *
 *字串練習
 *
 * */
#include<stdio.h>
int main() {
	char buf[50] = {0};
	char *p_ch = buf;
	int sum = 0,tmp = 0;
	printf("請輸入字串:");
	fgets(buf,50,stdin);
	while(*p_ch) {
		if(*p_ch >= '0' && *p_ch <= '9') {
			tmp = (10 * tmp + *p_ch - '0');

		}
		else {
			sum += tmp;
			tmp = 0;
		}
		p_ch++;
	}
	printf("%d\n",sum);
	return 0;
}

#elif 0
/*
 *
 *字串函式練習
 *
 * */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
	char buf[50] = {0};
	char *p_ch= buf;
	int sum = 0;
	printf("請輸入字串:");
	fgets(buf,50,stdin);
	while(1) {
		sum += atoi(p_ch);
		p_ch = strstr(p_ch,",");
		if(!p_ch) {
			break;
		}
		else {
			p_ch++;
		}

	}
	printf("sum = %d\n",sum);
	return 0;
}

#elif 0
/*
 *
 *模擬登入
 *
 * */
#include<stdio.h>
#include<string.h>
int main() {
	char buf[10] = {0};
	int num = 0;
	for(num = 1;num <= 3;num++) {
		printf("請輸入使用者名稱:");
		fgets(buf,10,stdin);
		if(strlen(buf) == 9 && buf[8] != '\n') {
		scanf("%*[^\n]");
		scanf("%*c");
		}
		if (strcmp(buf,"admin\n")) {
			continue;
		}
		printf("請輸入密碼:");
		fgets(buf,10,stdin);
		if(strlen(buf) == 9 && buf[8] != '\n') {
			scanf("%*[\n]");
			scanf("%*c");
		}
		if(strcmp(buf,"123456\n")) {
			continue;
		}
		break;
	}
	if(num <= 3) {
		printf("登入成功\n");
	}
	else {
		printf("登入失敗\n");
	}
	return 0;
}

#elif 0
/*
 *
 *字元指標陣列演示
 *
 * */
#include<stdio.h>
int main (){
	/*char *strs[] = {"abc","def","xyz","iop","vbn"}; 		//字元指標陣列   */
	char strs[][10] = {"abc","ded","vbn","zxh","sfd"};
	int num = 0;
	for (num = 0;num <=  4;num++){
		printf("%s\n",strs[num]);
	}
	return 0;
}
#elif 0
/*
 *
 *主函式引數
 *
 * */
#include<stdio.h>
int main (int argc,char *argv[]){
	int num = 0;
	for (num = 0;num <= argc - 1;num++){
		printf("%s\n",argv[num]);
	}
	return 0;
}

#elif 0
/*
 *
 *雞兔同籠
 *
 * */
#include<stdio.h>
#include<stdlib.h>
int main (int argc,char *argv[]){
	int heads = 0,legs = 0,num = 0;
	if (argc < 3){
		printf("命令錯誤\n");
		return 0;
	}
	heads = atoi(argv[1]);
	legs = atoi(argv[2]);
	for (num = 0;num <= heads;num++){
		if (4 * num +2 * (heads - num) == legs){
			printf("兔子有%d雞有%d\n",num,heads - num);
			break;
		}
	}
	return 0;
}
#elif 0
/*
 *
 *宏定義
 *
 *
 * */
#include<stdio.h>
#define 	PI 			3.14f
#define 	CIRCLE(r) 	2 * PI *r
int main (){
	float radius = 0.0f;
	printf("請輸入半徑:");
	scanf("%g",&radius);
	printf("周長是%g\n",CIRCLE(radius));
	return 0;
}
#elif 0
/*
 *
 *宏演示
 * 
 * */

#include<stdio.h>
#include<stdlib.h>
#include<time.h>	
int main (){
	int arr[SIZE] = {0};
	int num = 0;
	srand(time(0));
	for (num = 0;num <= SIZE - 1;num++){
		arr[num] = rand() % MAX +1;
	}
	for (num = 0;num <= SIZE -1;num++){
		printf(" %d ",arr[num]);
	}
	printf("\n");
	return 0;
}
#elif 0
/*
 *
 *宏演示
 *
 * */
#include<stdio.h>
#define 	ABS(n) 		n >= 0 ? n : 0 - n		
#define 	NEG(n) 		n = 0 - n
int abs (int num){
	if (num >= 0){
		return num;
	}
	else{
		return (0 - num);
	}
	
}
void neg (int *p_num){
	*p_num = 0 - *p_num;
}
int main (){
	int num = 0;
	printf("請輸入一個數字:");
	scanf("%d",&num);
	printf("%d\n",abs(num));
	printf("%d\n",ABS(num));
	neg(&num);
	printf("%d\n",num);
	NEG(num);
	printf("%d\n",num);
	return 0;
}
#elif 0
/*
 *宏練習
 *
 * */
#include<stdio.h>
#define 	SUB(x,y) 			((x) -(y))
int main (){
	printf("%d\n",SUB(10,5));
	printf("%d\n",20 - SUB(10,5));
	printf("%d\n",20 - SUB(10,5));
	printf("%d\n",SUB(20,10 -5));
	return 0;
}

#elif 0
/*
 *
 *計算整數平方
 *
 * */
#include<stdio.h>
#define 	SQUARE(n) 		(n) * (n)
int main (){
	int num = 5;
	printf("%d\n",SQUARE(num));
	printf("%d\n",SQUARE(++num));
	return 0;
}
#elif 0
/*
 *
 *宏運算子演示
 *
 * */
#include<stdio.h>
#define 	STR(n) 		#n
#define 	PTR(n)      p_##n
int main (){
	STR(2+3);
	int num = 0;
	int *PTR(num) = &num;
	return 0;
}
#elif 1
/*
 *
 *宏轉換大小寫
 *
 * */
#include<stdio.h>
#define 	CASE(ch) 	((ch) >= 'a' && (ch) <= 'z' ? (ch) - 'a' + 'A' : (ch) - 'A' + 'a')
int main (){
	char ch = 0;
	printf("請輸入一個英文:");
	scanf("%c",&ch);
	printf("%c\n",CASE(ch));
	return 0;
}
#endif 


相關文章