《C Primer Plus》 学习总结 第七八九章

条件运算符 ?:

条件运算符又称三目运算符。通用形式如下:
expression1?expression2:expression3
若expression1为真,则整个表达式值与expression2相同。
例:max=(a>b)?a:b;如果a>b,将a的值赋给max。条件运算符也可以用if else语句完成,但是使用条件运算符可以使代码更整洁。

#include "stdio.h"
#define COVERAGE 350  //通过宏定义设置常量
int main(void)
{
	int sq_feet,cans;
	printf("Enter number of square feet to be painted:");
	while(scanf("%d",&sq_feet)==1)//scanf是有返回值的
	{
		cans =  sq_feet/COVERAGE;
		cans+=(sq_feet%COVERAGE==0)?0:1;
		printf("You need %d %s of paint.\n",cans,cans==1?"can":"cans");
		printf("Enter next value(q to quit):");
	}
	return 0;
}

该程序很好的运用了条件运算符,当满足sq_feet%COVERAGE为0时,cans= cans+0;sq_feet%COVERAGE为1时,cans= cans+1;

循环语句

continue and break

continue 和break语句可以根据循环体中的测试结果来忽略一部分循环内容,甚至结束循环。当执行到continue语句时,会跳出本次迭代的剩余部分并开始下一轮迭代。当执行到break时跳出循环执行循环后的内容。图片来源于 C Primer Plus
图片来源于 C Primer Plus

switch语句

当程序中需要多个选项或条件时,if else语句可以完成任务,但是代码量会非常大且冗余。但使用switch语句会更加方便。
图片来源于 C Primer Plus
switch语句会检索输入的值和case中的那个相匹配,然后执行对应的statement。存在break语句时,执行完满足条件的语句后会跳出switch语句。当没有break语句时,会从匹配case执行到switch末尾。
break语句可用于循环和switch语句中,但是continue只能用于循环中。尽管如此,如果switch语句在一个循环中,continue便可作为switch语句的一部分。这种情况下,就像在其他循环中一样,continue让程序跳出循环的剩余部分,包括switch语句的其他部分。
那么什么时候使用switch,什么时候使用if else呢,首先switch的参数只能为整型,若参数为浮点数或表达式则使用if语句。若存在很多种case,则使用switch,程序运行会更快一些。

字符输入/输出和输入验证

缓冲区

图片来源于C Primer Plus
当用户输入字符后立即重复打印该字符属于无缓冲输入,大部分系统在用户按下Enter键之前不会重复打印输入的字符,属于缓冲输入。用户输入的字符被收集并储存在一个被称为缓冲区(buffer)的临时存储区。

完全缓冲:当缓冲区被填满时刷新缓冲区,大小取决于系统。

行缓冲:出现换行符时刷新缓冲区,键盘输入通常是行缓冲输入。

使用缓冲输入

重定向和文件

重定向输入让程序使用文件而不是键盘来输入,重定向输出让程序输出至文件而不是屏幕。
重定向输入运算符:<
重定向输出运算符:>

//echo_eof.c
#include "stdio.h"
int main(void)
{
	int ch;
	while((ch=getchar())!=EOF)//EOF(end of file)文件尾
		putchar(ch);
	return 0;
}
echo_eof<words  //编译后执行该语句表示将words中文本作为程序的输入
echo_eof>mywords//表示执行后的输出文本到mywords文件中
echo_eof<words>mywords//words文件作为输入,mywords作为输出

注意事项
1.在重定向时,输入文件名和输出文件名不能相同。
2.重定向运算符连接一个可执行程序。
3.使用重定向运算符不能读取多个文件的输入,也不能把输出定向至多个文件。

混合输入字符和数值


当第一次输入完数据之后会直接跳出程序,原因是因为getchar()读取每个字符,包括空格换行。而scanf()在读取数字时会跳过空格、制表符和换行符。
所以在数字3之后的换行符,scanf函数不会读取换行符,所以在下一轮getchar()函数读取了换行符。而ch是换行符则结束循环。


添加一个while语句将输入末端的换行符读取掉,while语句内部是continue,上文提到了,当执行continue时,会跳出循环从新执行while语句,消耗掉换行符保证程序正确执行。

函数

函数完成特定任务的独立程序代码单元,使用函数可以省去重复代码的部分,将某种类似情况抽象成一种类型,使程序更加模块化。
函数由函数类型、函数名、函数参数和函数主体组成。声明函数必须声明函数类型,若没有返回值则声明为void类型。传递参数时必须严格按照参数的类型传递。

void Test(void)//此函数的返回类型是void,表示没有返回值,括号中的void表示该函数无参数  函数中的参数为局部变量,只在该函数中有效。
{
	printf("hello world\n");
}//在主函数中使用该函数时,应在主函数前声明该函数。
void show_n_char(char ch,int num)//该函数需要传入一个char类型的变量和一个int 类型的变量
{
	for(int i = 0 ;i<num;i++)
		putchar(ch);
}
int MaxValue(int a,int b)//返回类型为int,所以函数最后需要返回int类型的值
{
	return (a>b?a:b);
}

从黑盒角度来看,函数带显示的字符和次数是输入,执行后的结果是打印指定数量的字符,这些在参数都是函数的局部变量,与main()中的无关,黑盒离发生的事对主函数是不可见的。

白盒测试和黑盒测试的区别

白盒:通过程序的源代码进行测试而不使用用户界面,通过从代码内部发现问题或错误。
黑盒:又称功能测试,通过观察输入数据看输出的结果,从而了解怎样工作,而不关注工作的内在过程。

递归函数

当函数在运行期间调用自己时,这种调用过程称为递归。可以使用循环的地方都可以使用递归。递归方案更简洁,但效率较低。递归函数必须包含让递归调用停止的语句。递归谨慎使用,每次递归都会创建一组函数内部的变量存放在栈中,十分占用内存。

每级函数调用都有自己的变量,第1级n和第2级的n不同。递归函数中为与递归调用之前的语句,均按照调用顺序执行,递归调用之后的语句,均按照相反顺序执行。
图片来源于C Primer Plus

查找地址:&运算符

指针是C语言最重要的概念之一,用于储存变量的地址。那么&运算符就是用来查看变量储存的地址。

#include <stdio.h>

int main(void)
{
	int a = 5;
    printf("value : %d, Address: %p\n",a,&a);//%p 是输出地址的转换说明
    return 0;
}
value:5,Address:0x7fff7c25eeb4

那么如何创建一个指针?星号(*)表明声明变量是一个指针。指针更详尽的讲解在下章提到。

int *p1;// p1是指向int类型变量的指针
char * p2; // p2是指向char类型变量的指针
float * p3; // p3都是指向float类型变量的指针
int main(void)
{
	int a = 5;
	int *p1;//创建int类型指针,指针存放地址,所以将a的地址赋值给p1
	p1 = &a;
	printf("value:%d",*a);//*为解引用运算符,*p1表示p1存放地址指向的值。
}

C Primer Plus
写于2023.4.28

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值