⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c primer plus

📁 系统地学习、撑握C语言的经典书。 这是我整理、加工过的《C Primer Plus》精简版
💻
📖 第 1 页 / 共 5 页
字号:
{
	float aboat = 32000.0;
	double abet = 2.14e9;
	long double dip = 5.32e-5;

	printf("%e = %f\n", aboat, aboat);	// 3.200000e+004 = 32000.000000
	printf("%e = %f\n", abet, abet);	// 2.140000e+009 = 2140000000.000000
	printf("%e = %f\n", dip, dip);		// 5.320000e-005 = 0.000053

	return 0;
}

例2、浮点值溢出
#include <stdio.h>
int main(void)
{
	float a;

	a = 2.0e39;	// 溢出
	printf("%e = %f \n", a, a);	// 1.#INF00e+000 = 1.#INF00

	a = 2.0e38;
	printf("%e = %f \n", a, a);	// 2.000000e+038 = 199999993605713850000000000000000000000.000000

	a = 2.0e15;
	printf("%e = %f \n", a, a);	// 2.000000e+015 = 1999999973982208.000000

	a = 1.12345671111e12;		// 1.123457e+012 = 1123456647168.000000
	printf("%e = %f \n", a, a);

	return 0;
}

例3、丢失部分数据
int cost = 12.99;		// 实际cost只保存了12
float pi = 3.1415926536;	// 实际pi只保存了3.121592,因为只有6位有效数字

例4、float与int同样32位,但解释出来的值绝然不同
#include <stdio.h>
int main(void)
{
	float f = 256.0;	// f的值为 256.0
	void *p= &f;
	int b = *(int*)p;	// b的值变成 1132462080
	printf("%d\n", b);
	return 0;
}


5、复数和虚数类型

C99标准支持这两种类型:
复数类型:float_Complex、double_Complex、long double_Complex
虚数类型:float_Imaginary、double_Imaginary、long double_Imaginary


6、其他类型

C从基本类型衍生出其他类型,包括数组、指针、结构、联合。



第四章 字符串和格式化输入

scanf()、printf()

// talkback.c -- nosy, informative program 
#include <stdio.h>
#include <string.h>	// 提供strlen()函数的原型	for strlen() prototype
			// 如果您使用的是ANSI C之前的编译器,可能不必包含 string.h,
			// 或者ANSI之前的UNIX系统使用 strings.h
#define DENSITY 62.4	// 人的密度(单位是:英镑/每立方英尺)	human density in lbs per cu ft

int main()
{
	float weight, volume;
	int size, letters;
	char name[40];         	// name是一个40个字符的数组	name is an array of 40 chars

	printf("Hi! What's your first name?\n");
	scanf("%s", name);	// 输入名字。字符数组名name是指针,不必加&
	printf("%s, what's your weight in pounds?\n", name);
	scanf("%f", &weight);	// 输入重量。&weight是指针,表示取变量weight的内存地址
	
	size = sizeof name;	// 数组name的长度是40
	letters = strlen(name);	// 取字符串长度
	volume = weight / DENSITY;
	
	printf("Well, %s, your volume is %2.2f cubic feet.\n", name, volume);
	printf("Also, your first name has %d letters,\n", letters);
	printf("and we have %d bytes to store it in.\n", size);

	return 0;
}

/* praise2.c */
#include <stdio.h>
#include <string.h>      /* provides strlen() prototype */
#define PRAISE "What a super marvelous name!"	// PRAISE是字符串常量,最终由编译器将PRAISE替换成实际字符串
int main(void)
{
    char name[40];

    printf("What's your name?\n");
    scanf("%s", name);
    printf("Hello, %s. %s\n", name, PRAISE);
    printf("Your name of %d letters occupies %d memory cells.\n",
	strlen(name), sizeof name);
    printf("The phrase of praise has %d letters ", strlen(PRAISE));
    printf("and occupies %d memory cells.\n", sizeof PRAISE);	// sizeof PRAISE 得出的字符串长度包括空字符'\0'
  
    return 0;
}


1、C没有为字符串定义专门的变量类型,可用char数组存放字符串,以'\0'作字符串结束标记。

2、使用%s的scanf()时,遇到第一个空白字符(空格、Tab、换行符)处停止读取,即只读一个单词,需要处理整句可以使用gets()。

3、strlen()用于运行时计算字符串长度,以'\0'为结束;sizeof指示编译器在编译时就计算容量。

4、sizeof对变量或常量可用省去圆括号,但数据类型如char、int不能省。例如sizeof char是不对,正确写法 sizeof(char)。

5、sizeof 常量字符串 可得出字符串的长度,此长度包含空字符'\0'的1字节。

6、'X' 是字符,占1字节;"X" 是字符串,以'\0'结束,所以占2字节。

7、#define 定义常量,例如:
	#define PI 3.14159
	#define BEEP '\a'
	#define TEE 'T'
	#define ESC '\033'
	#define OOPS "Now you have done it!"
   另外,在limits.h中定义有INT_MAX、INT_MAX、CHAR_BIT等常量;在float.h中定义了DBL_DIG、FLT_MAX、DBL_MIN等常量。

8、const 定义常量,这是C90新增的关键字,可将一个变量声明转换成常量声明,例如:
	const int MONTHS = 12;	// MONTHS是一个只读值,运行时不能改变MONTHS值


9、printf()的转换说明符

	%d、%i	有符号十进制数
	%u	无符号十进制数
	%o	无符号八进制数
	%x、%X	无符号十六进制数字
	%c	一个字符
	%s	字符串
	%p	指针
	%a、%A	浮点数,十六进制数字和p-记数法(C99),p-notation
	%e、%E	浮点数,e/E-记数法,e-notation
	%f	浮点数,十进制记数法	
	%g、%G	自动选择%f或%e,其中%e是在指数小于-4或者大于等于精度时使用

  printf()的修饰符
	
	digit(s)	最小宽度,例如:"%4d"最小4个字符宽度,不够宽时自动增宽
	.digit(s)	精度,例如:"%5.2f"只打印两位小数,"%.5s"只打印字符串的5个字符,"%.3d"整数不足3位则在前面加0
	h		短整型,例如:"%hu"、"%hx"、"%6.4hd"
	hh		表示 signed char 、 unsigned char 值,例如:"%hhu"、"%hhx"、"%6.4hhd"
	j		表示一个 intmax_t 、 uintmax_t 值,例如:"%jd"、"%8jX"
	l		表示 long int 、 unsigned long int 、double 值,例如:"%ld"、"%8lu"、"%lf"
	ll		表示 long long int 、 unsigned long long int 值,例如:"%lld"、"%llu",(C99)
	L		表示一个 long double 值,例如:"%Lf"、"%10.4Le"
	t		表示一个 ptrdiff_t (两个指针的差)值,例如:"%td"、"%12ti",(C99)
	z		表示一个 size_t (sizeof的返回值,无符号整型) 值,例如:"%zd"、"%12zx",(C99)

  printf()的标志

	-	左对齐,例如:"%-20s"
	+	显示正负符号,例如:"%+6.2f"
	空格	有符号的值为正,则带前导空格(不带正号);若为负,则带减号。+标志会覆盖空格标志。例如:"% 6.2f"
	#	例如:"%#o"八进制数前面加0、"%#x"十六进制数前面加0x、"%#8.0f"即使无数字也打印小数点、"%+#10.E"、"%#g"防止尾0被删除
	0	前导0填充最小宽度,例如:"%010d"、"%08.3f"


10、pritnf()参数传递原理

/* floatcnv.c -- mismatched floating-point conversions */
#include <stdio.h>
int main(void)
{
    float n1 = 3.0;
    double n2 = 3.0;
    long n3 = 2000000000;
    long n4 = 1234567890;

    printf("%.1e %.1e %.1e %.1e\n", n1, n2, n3, n4);	// 3.0e+000 3.0e+000 3.1e+046 4.2e-314
    printf("%ld %ld\n", n3, n4);			// 2000000000 1234567890
    printf("%ld %ld %ld %ld\n", n1, n2, n3, n4);	// 0 1074266112 0 1074266112
   
    return 0;
}

参数不匹配打印出的结果不正确,下面以最后一句printf()为例,说明参数传递原量:

	(1) 调用printf()时,按参数的类型(如float),将参数值压入栈中
	(2) printf()执行时,根据说明符(如%ld),从栈取出参数值

		|-------|-
		|	|  } 4字节
		|-------|-
		|	|
		|-------| <--- n4 (long int 8字节)
		|	|
	%ld -->	|-------| <--- n3 (long int 8字节)
		|	|
	%ld -->	|-------| <--- n2 (double 8字节)
		|	|
	%ld -->	|-------|
		|	|
	%ld -->	|-------| <--- n1 (float 4字节)
		|	|
		|-------|


11、printf() 返回值:正常则返回打印的字符总数,出错则返回负数。


12、长字符串分行。

// 三种分行方式效果一样
/* longstrg.c -- printing long strings */
#include <stdio.h>
int main(void)
{
	printf("Here's one way to print a ");
	printf("long string.\n");

	printf("Here's another way to print a \
long string.\n");	// 注意,左边空白字符也会计算在内

	printf("Here's the newest way to print a "
		"long string.\n");      /* ANSI C */

	return 0;
}


13、scanf()输入

// input.c -- when to use & 
#include <stdio.h>
int main(void)
{
	int age;			// 变量 
	float assets;		// 变量
	char pet[30];		// 字符串

	printf("Enter your age, assets, and favorite pet.\n");
	scanf("%d %f", &age, &assets); // 此处用&      
	scanf("%s", pet);              // 对字符数组不需要使用&
	printf("%d $%.2f %s\n", age, assets, pet);

	return 0;
}

scanf()的转换说明符与printf()相似,主要区别在于
printf()把%f、%e、%E、%g、%G 同时用于float和double,
而scanf()只把它们用于float,对于double需要使用l修饰符。

scanf()的转换说明符

	%c		输入一个字符
	%d		输入一个十进制整数
	%u		输入一个无符号十进制整数
	%i		输入一个有符号十进制数
	%x、%X		输入一个有符号十六进制数
	%o		输入一个八进制数
	%p		输入一个指针(一个地址)
	%e、%f、%g、%a	输入一个浮点数(%a是C99新增的)
	%E、%F、%G、%A	输入一个浮点数(%a是C99新增的)
	%s		输入一个字符串,以输入的内容第一个非空白字符作为开始,直至下一个空白字符的作为结束,并添加'\0'给字符数组作结束标记

scanf()的修饰符
	digit(s)	最大字段宽度,例如:"%10s"最多输入10个字符
	d、i、o		int
	e、f、g		float
	hh		"%hhd" 表示 signed char ;"%hhu" 表示 unsigned char
	ll		"%lld" 表示 long long ;"%llu" 表示 unsigned long long
	h、l、L		"hd"、"%hi" 表示 short int ;"%ho"、"%hx"、"hu" 表示 unsigned short int
			"%ld"、"%li" 表示 long ;"%lo"、"lx"、"%lu" 表示 unsigned long
			"%le"、"%lf"、"%lg" 表示 double ;"%Le"、"%Lf"、"%Lg"  表示 long double

14、scanf()按格式输入

(1) scanf("%d, %d", &n, &m);

	输入方式1:
	77, 100

	输入方式2:
	77,   100

	输入方式3:
	77,
	100

(2) scanf("%d%d", &n, &m);

	输入方式1:
	77 100

	输入方式2:
	77
	100

这两个语句结果都一样。


15、scanf()的返回值:
	正常收返回成功读入的项目的个数;
	输入错误则返回0;
	到达文件结尾(end of file)时则返回EOF(EOF一般定义为-1)。


16、getchar()输入一个字符;putchar()输出一个字符;gets()输入一行字符串。


17、printf()和scanf()的*修饰符

/* varwid.c -- uses variable-width output field */
#include <stdio.h>
int main(void)
{
	unsigned width, precision;
	int number = 256;
	double weight = 242.5;

	printf("What field width?\n");
	scanf("%d", &width);
	printf("The number is :%*d:\n", width, number);		// "%*d"中的*对应变量width
	printf("Now enter a width and a precision:\n");
	scanf("%d %d", &width, &precision);
	printf("Weight = %*.*f\n", width, precision, weight);	// "%*.*f"中的两个*分别对应变量wdith和precision
	printf("Done!\n");

	return 0;
}

/* skip2.c -- skips over first two integers of input */
#include <stdio.h>
int main(void)
{
	int n;

	printf("Please enter three integers:\n");
	scanf("%*d %*d %d", &n);	// 跳过前面两个整数,取第三个整给n
	printf("The last integer was %d\n", n);

	return 0;
}
输入、输出结果:
Please enter three integers:
1 2 3
The last integer was 3


18、使用scanf(),假设输入行:

-13.45e12# 0

对于%d,读到-13
对于%f,读到-13.45e12
对于%s,读到-13.45e12#



第五章 运算符、表达式和语句


1、计算机不能真正用整数除浮点数,是编译器将整数转化为浮点数,再除。


2、语句中有语句
	int c, d;
	int d = 6 + (c=3+8);	// c被赋值为11,不建议这样使用
	for(c=1, d=0; c<10; c++, d=d+2)	// 逗号运算符
		printf("%d,%d\n", c, d);


3、类型转换

类型转换从高到低顺序是:
long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int
short 和 char 可能被提升为 int 或 unsigned int

#include <stdio.h>
int main(void)
{
	char ch;
	int i;
	float fl;

	fl = i = ch = 'C';	// 自动升级转换:int --> float
	printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);	// ch = C, i = 67, fl = 67.00

	ch = ch + 1;
	i = fl + 2 * ch;	// 自动降级转换:float --> int
	fl = 2.0 * ch + i;	// 自动降级转换:double --> float
	printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);	// ch = D, i = 203, fl = 339.00

	ch = 5212205.17;	// 自动降级转换:double --> char
	printf("Now ch = %c\n", ch);				// Now ch = -

	i = 1.6 + 1.7;		// 自动降级转换:double --> int
	printf("i = %i\n", i);					// i = 3

	i = (int)1.6 + (int)1.7;// 强制转换
	printf("i = %i\n", i);					// i = 2

	return 0;
}


4、运算符优先级

()
-  +  ++  --  sizeof		从右到左
*  /  %
+  -
<  >  <=  >=
==  !=
=				从右到左



第六章 C控制语句:循环

1、循环写法

initialize;
while(test)
{
	body;
	update;
}

initialize;
do
{
	body;
	update;
}
while(test);


for(initialize; test; update)
{
	body;
}


2、循环举例

#include <stdio.h>
int main(void)
{
	int i;

	// while
	i = 0;
	while(i<=10)
	{
		printf("%d ", i);
		i++;
	}

	printf("\n", i);

	// do...while
	i = 0;
	do
	{
		printf("%d ", i);
		i++;
	}
	while (i<=10);

	printf("\n", i);

	
	// for
	for(i=0; i<=10; i++)
	{
		printf("%d ", i);
	}

	printf("\n", i);

	return 0;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -