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 |
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,其他進位制略):
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。
十進位制 | 指數記數法 | 十六進位制 | |
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型別,所以沒有做相關練習。