1. 程式人生 > >C Primer Plus 6 第三章程式設計練習

C Primer Plus 6 第三章程式設計練習

一、知識點複習

  • 程式離不開資料,C語言提供兩大資料型別:整數型別和浮點數型別。
  • 最初K&R給出的C語言關鍵字有int、long、short、unsigned、char、float、double,C90標準增加了signed和void,之後C99標準又添加了_Bool、_Complex、_Imaginary。

1.變數和常量

1.1定義

(1)變數:在程式執行期間可能會改變或被賦值的資料型別。 (2)常量:在整個程式執行過程中不會改變的資料型別。

1.2整型常量的寫法示例

型別 十六進位制 八進位制
十進位制
char \0x41 \0101
int 0x41 0101 65
unsigned int 0x41u 0101u 65u
long 0x41L 0101L 65L
unsigned long 0x41uL 0101uL 65uL
long long 0x41LL 0101LL 65LL
unsigned long long
0x41uLL 0101uLL 65uLL

1.3浮點型常量寫法示例

型別 十進位制
float 6.0f
double 2.3
long double 4.32L

2.整數和浮點數

(1)整數:沒有小數部分的數。

(2)浮點數:有小數部分。

注意:計算機把浮點數分成小數部分和指數部分且分開進行儲存;浮點數可以表示的範圍比整數大;一些算術運算裡浮點數損失的精度更多;浮點數通常只是實際值的近似值。

3.整數型別

3.1有符號整型

關鍵字 簡單定義 宣告舉例

在printf()中的對應轉換說明

(1.一般預設十進位制,

2.只用小寫)

八進位制和十六進位制的使用
int

可以是正整數、負整數、0;

C語言規定int型別不小於16位

int m;

signed int m;(一般不用特意強調說明,下同)

%d 見表1
short

佔用的儲存空間可能比int少;

C語言規定short型別至少佔16位

short m;

short int m;

%hd 見表1
long

佔用的儲存空間可能比int多;

C語言規定long型別至少佔32位

long m;

long int m;

%ld(%Ld) 見表1
long long

佔用的空間可能比long多;

long long型別至少佔64位

long long m;

long long int m;

%lld(%LLd) 見表1
表1 以八進位制數144和十六進位制數64為例的有符號整型轉換表示
  144 0144(帶字首) 64 0x64(帶字首)\0X64
int %o %#o %x %#x、%#X(下略)
short %ho %#ho %hx %#hx
long %lo %#lo %lx %#lx
long long %llo %#llo %llx %#llx

3.2無符號整型

無符號整型只用於非負值場合,可以表示更大的數。各關鍵字型別分類與宣告與有符號整型類似。在printf()函式中的對應轉換說明舉例如下表(與有符號整型十進位制int型別%d對應使用的是%u,其他進位制略):

表2 十進位制無符號轉換說明
  printf()中對應轉換說明
unsigned int %u
unsigned short %hu
unsigned long %lu
unsigned long long %llu

3.3字元型

char型

char型別實際上儲存的是整數而不是字元,計算機使用ASCII編碼處理字元,標準ASCII碼的範圍是0~127,C語言中char型別佔用一個位元組。用單引號括起來的單個字元被稱為字元常量。char型別的標準宣告和定義如下:

char m = 'T';

printf()函式用%c指明待列印的字元。

char型別除了列印字元'T'之外,也有非列印字元。單引號只適用於字元、數字、標點符號,而有些是ASCII字元打印不出來的,所以用一些特殊符號序列表示一些特殊字元,這些特殊符號序列成為轉義序列。第二章接觸到的換行符\n就屬於轉義序列。

注意:C語言將字元常量視為int型別而非char型別,char m = 65;這種定義方式也可以但不是一種好的程式設計風格。

關於char型別有無符號的問題視情況而定,若有符號,可表示的範圍是-128~127;若無符號,可表示的範圍是0~255;特別的,若只用char處理字元,則無需任何修飾符。

3.4布林型別

_Bool型

C99標準新增的型別,簡而言之就是邏輯值true和false,用1表示true,0表示false。布林型別屬於整數型別,原則上僅佔一位儲存空間。在有些資料中並不把它算作C中的資料型別。

4.浮點數型別

4.1實浮點型別

(1)float

可精確表示至少6位有效數字,浮點型常量後面跟f。

(2)double

能表示比float型別更多的有效數字(至少10位)和更大的指數。

(3)long double

能表示比double更多的有效數字和更大的指數,浮點型常量後跟L。

表3 在printf()中的對應轉換說明
  十進位制 指數記數法 十六進位制
float %f %e %a
double %f %e %a
long double %Lf %Le %La

4.2複數和虛數浮點數

虛數型別是可選型別。複數的實部和虛部型別都基於實浮點型別構成:

(1)複數

float_Complex

double_Complex

long double_Complex

(2)虛數

float_Imaginary

double_Imaginary

long double_Imaginary

二、程式設計練習

1.

/*overflow.c--整數上溢、浮點數上溢、浮點數下溢
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	int i = 2147483647;//32位的long最小取值範圍的正上限是2147483647
	unsigned int j = 4294967295;//unsigned long的最小取值範圍上限

	float m = 3.4e38f;//上溢
	float n = 0.1234e-10f;//下溢

	/*當前系統指定的各資料型別大小(位元組數)*/
	printf("Type int has a size of %d bytes.\n",sizeof(int));//sizeof是C內建運算子,以位元組為單位給出指定型別的大小
	printf("Type short has a size of %d bytes.\n",sizeof(short));
	printf("Type long has a size of %d bytes.\n",sizeof(long));
	printf("Type char has a size of %d bytes.\n",sizeof(char));
	printf("Type float has a size of %d bytes.\n",sizeof(float));
	printf("Type double has a size of %d bytes.\n\n",sizeof(double));

	printf("給出以下資料:\n");
	printf("有符號整型i=%d\n", i);
	printf("無符號整型j=%u\n", j);
	printf("浮點數m=%e\n", m);
	printf("浮點數n=%e\n\n", n);

	/*整數上溢*/
	printf("i+1=%d i+2=%d\n", i+1, i+2);
	printf("j+1=%u j+2=%u\n", j+1, j+2);
	
	/*浮點數上溢*/
	printf("m*100.0=%e or %f\n", m*100.0);
	
	/*浮點數下溢*/
	printf("n/10=%e or %f\n", n/10);
	return 0;
}

2.
/*character.c--輸入一個ASCII值,列印輸入的字元
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	int i;

	printf("Please enter a number between 0~127:");
	printf("___\b\b\b");
	scanf("%d", &i);
	printf("\n%d in ASCII is %c\n", i, i);
	return 0;
}

3.

/*alarm.c--警報聲響後列印一段文字
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	printf("\aStartled by the sudden sound, Sally shouted,\n");//轉義序列\a表示警報
	printf("\"By the Great Pumpkin, what was that!\"\n");
	return 0;
}

4.

/*display.c--讀取一個浮點數並分別以小數點形式、指數形式、十六進位制記數法(若可以)列印顯示
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	float i;

	printf("Please enter a floating number:");
	printf("_____\b\b\b\b\b");
	scanf("%f", &i);
	printf("\nfixed-point notation: %f\n", i);//形參裡的第一個\n經測試就算不要也能實現換行,猜測應當是緩衝區滿了,保留此問題,待議
	printf("exponential notation: %e\n", i);
	printf("p notation: %a\n", i);
	return 0;
}

5.

/*secong.c--輸入年齡,顯示對應的秒數
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	int i;

	printf("It's about 3.156e7 second a year.\n");
	printf("Do you wanna know what your age is in seconds?\n");
	printf("All right, let's do it!\n");
	printf("Please enter your age: ");
	printf("__\b\b");
	scanf("%d", &i);
	printf("\nWow! your age in seconds is %e!\n", i*3.156e7);//換行問題同第四題
	return 0;
}

6.
/*water.c--輸入水的夸脫數,顯示水分子數量
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	double i = 3.0e-23;//1個水分子的質量
	float j = 950;//1夸脫水的質量
	float m;//水的夸脫數
	double n;//水分子的數量

	printf("The mass of a water molecule is 3.0e-23 gram.\n");
	printf("The mass of a quart of water is 950 gram.\n");
	printf("Enter the number of quart of water: ");
	printf("__\b\b");
	scanf("%f", &m);
	n = m * j / i;
	printf("The number of water molecule is %e\n", n);
	return 0;
}

7.
/*inch.c--以英寸為單位輸入身高,以釐米為單位列印
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	float inch;
	float i = 2.54f;//1英寸有2.54釐米
	float cm;

	printf("Enter your height(in inch):");
	printf("_____\b\b\b\b\b");
	scanf("%f", &inch);
	cm = inch * i;
	printf("your height in cm is %f\n", cm);
	return 0;
}

8.

/*number.c--輸入杯數,分別顯示其他單位的等價容量
  author:Alice_12
  date:2018.2.18*/
#include<stdio.h>
int main(void)
{
	float j;//杯

	printf("Enter Cup number:");
	printf("___\b\b\b");
	scanf("%f", &j);

	//品脫
	printf("%f glass of water is %e pint.\n", j, 0.5*j);

	//盎司
	printf("%f glass of water is %e ounce.\n", j, j*8);

	//湯勺
	printf("%f glass of water is %e soup spoon.\n", j, j*8*2);

	//茶勺
	printf("%f glass of water is %e tea spoon.\n", j, j*8*2*3);
	return 0;
}

三、總結

1.程式設計中的部分資料問題需要了解一下二進位制、十進位制、八進位制、十六進位制之間的相互轉換。

2.printf()在本章的使用仍然是重點,體現在相關資料型別的列印轉換。

3.關於float和double如何選取:有一個說法是float以一個字32位顯示,7個有效位,double以2個字64位顯示,16個有效位;浮點數字面值在不做f和l字尾時都預設為double型別;進行浮點數運算時float型別損失的精度比double多。

4.在練習4往後我遇到了換行不確定的問題,原因在於書上例3.10的程式分析及重新整理輸出中提到當緩衝區滿、遇到換行符、需要輸入時會把printf傳送到緩衝區中的輸出傳送到螢幕上,我的實際練習情況有點不符。

5.在我使用的編譯器上並不支援long long型別,所以沒有做相關練習。