C Primer Plus 第9章——第一篇

你该逆袭了

文章目录

  • 一、复习函数
    • 1、定义带形式参数的函数
    • 2、声明带形式参数函数的原型
    • 3、使用 return 从函数中返回值
      • (1)、返回值不仅可以赋给变量,也可以被用作表达式的一部分。
      • (2)、返回值不一定是变量的值,也可以是任意表达式的值。
      • (3)、如果函数返回值的类型与函数声明的类型不匹配怎样?
      • (4)、return 用来终止函数并把控制返回给主调函数的下一条语句。
        • return; 的作用
    • 4、函数类型
      • (1)函数声明既可以在主调函数外面,也可以放在主调函数里面。
  • 二、ANSI C 函数原型
    • 1、无参数和未指定参数
    • 2、函数原型的优点
  • 三、递归
    • 1、演示递归
    • 2、递归的基本原理
    • 3、尾递归
    • 4、递归和倒序计算
    • 5、递归的优缺点
  • 四、编译多源代码文件的程序
    • 1、使用头文件
      • (1)示例程序的注意点
      • (2)示例程序
      • (3)示例程序的运行结果截图
  • 五、查找地址:&运算符


一、复习函数

1、定义带形式参数的函数

void dibs(x, y, z)
char x, y, z;

void dibss(x, y)  //这里,圆括号中只有参数列表,而参数的类型在后面声明。
int x;
char y;

//这是 ANSI C 之前的形式,现在已经将其废弃不用

在这里插入图片描述

2、声明带形式参数函数的原型

在这里插入图片描述

3、使用 return 从函数中返回值

#include <stdio.h>

int imin(int, int);

int main()
{
	int num1 = 0; 
	int num2 = 0;

	printf("enter a pair of integers (q to quit):\n");
	while (scanf("%d %d", &num1, &num2) == 2)
	{
		printf("the lesser of %d and %d is %d.\n",
			num1, num2, imin(num1, num2));
		printf("enter a pair of integers (q to quit):\n");
	}
	printf("bye\n");

	return 0;
}

int imin(int n, int m)
{
	int min = 0;

	if (n < m)
		min = n;
	else
		min = m;

	return min;
}

(1)、返回值不仅可以赋给变量,也可以被用作表达式的一部分。

answer = 2 * imin(z, zstar) + 25;
printf("%d\n", imin(-32 + answer, LIMIT));

(2)、返回值不一定是变量的值,也可以是任意表达式的值。

imin(int n, int m)
{
	return (n < m) ? n : m;
}

(3)、如果函数返回值的类型与函数声明的类型不匹配怎样?

在这里插入图片描述

(4)、return 用来终止函数并把控制返回给主调函数的下一条语句。

在这里插入图片描述

return; 的作用

在这里插入图片描述

4、函数类型

声明函数时必须声明函数的类型。带返回值的函数类型应该与其返回值类型相同,而没有返回值的函数应声明为 void。

在这里插入图片描述

(1)函数声明既可以在主调函数外面,也可以放在主调函数里面。

在这里插入图片描述

二、ANSI C 函数原型

1、无参数和未指定参数

在这里插入图片描述
在这里插入图片描述

2、函数原型的优点

在这里插入图片描述

三、递归

结束递归 是使用递归的难点,因为如果递归代码中没有终止递归的条件测试部分,一个调用自己的函数会无限递归。

1、演示递归

如果函数使用%p转换说明打印地址,如果你的系统不支持这种格式,请使用 %u 或者 %lu 代替 %p。

#include <stdio.h>

void digui(int n);

int main()
{
	digui(1);

	return 0;
}

void digui(int m)
{
	printf("%d 的地址是 %p\n", m, &m);  // #1

	if (m < 4)       //使递归停止的条件
	{
		digui(m + 1);
	}

	printf("%d 的地址是 %p\n", m, &m);  // #2

	return 0;
}

在这里插入图片描述

2、递归的基本原理

在这里插入图片描述

(1)每级函数调用都有自己的变量。
在这里插入图片描述

(2)每次函数调用都会返回一次。当函数执行完毕后,控制权将被传回上一级递归。且程序必须按顺序逐级返回递归。
在这里插入图片描述

(3)递归函数中位于 递归调用之前 的语句,均按被调函数的顺序执行。
在这里插入图片描述

(4)递归函数中位于 递归调用之后 的语句,均按被调函数相反的顺序执行。
在这里插入图片描述

(5)虽然每级递归都有自己的变量,但是并没有拷贝函数的代码。
在这里插入图片描述

(6)递归函数必须包含能让递归调用停止的语句。
在这里插入图片描述

3、尾递归

最简单的递归形式是把递归调用置于函数的末尾,即正好在 return 语句之前。这种形式的递归被称为 尾递归,因为递归调用在函数的末尾。

分别用 循环 和 递归 计算阶乘:


#include <stdio.h>

long recur(int x);  //阶乘
long xunhuan(int x);  //循环

int main()
{
	int input = 0;
	printf("请输入 12 以内的正整数(q to exit)\n");
	while ((scanf("%d", &input) == 1))
	{
		if (input > 12)
		{
			printf("请输入12以内的整数,你输入的数据太大。\n");
		}
		else if (input < 0)
		{
			printf("你输入的数据是负数,请重新输入数据。\n");
		}
		else
		{
			printf("递归:%d 的阶乘是 %d\n", input, recur(input));
			printf("循环:%d 的阶乘是 %d\n", input, xunhuan(input));
		}
	}
	printf("bye\n");

	return 0;
}

long recur(int x)
{
	long sum = 0;

	if (x > 0)
	{
		sum = x * recur(x - 1);
	}
	else
		sum = 1;  // 0 的阶乘 是 1  
	              // 0!= 1

	return sum;
}

long xunhuan(int x)
{
	long sum = 1;

	for (sum = 1; x >= 1; x--)
	{
		sum *= x;
	}

	return sum;
}

代码的关键点:
虽然递归调用不是函数的最后一行,但是当 x > 0 时,它是该函数执行的最后一条语句,因此它也是 尾递归。

long recur(int x)
{
	long sum = 0;

	if (x > 0)
	{
		sum = x * recur(x - 1);
	}
	else
		sum = 1;  // 0 的阶乘 是 1  
	              // 0!= 1

	return sum;
}

在这里插入图片描述
在这里插入图片描述

4、递归和倒序计算

用二进制形式打印整数

#include <stdio.h>                       

void binary(int n);

int main()
{
	int input = 0;

	printf("请输入一个整数:\n");
	while (scanf("%d", &input) == 1)
	{
		printf("以二进制的形式输出:");
		binary(input);
		putchar('\n');
		printf("请继续输入整数,q to exit\n");
	}
	printf("bye\n");
	return 0;
}

void binary(int n)
{
	int r = 0;

	r = n % 2;
	if (n >= 2)
	{
		binary(n / 2);
	}
	putchar(r == 0 ? '0' : '1');  //此处注意,输出 字符‘1’ 和 字符‘0’

	return;  //什么也不返回
}

注意点:

putchar(r == 0 ? '0' : '1');  
//此处注意,输出 字符‘1’ 和 字符‘0’

return;  //什么也不返回

5、递归的优缺点

优点:
递归为编程问题提供了最简单的解决方案。

缺点:
一些递归算法会快速消耗计算机的内存资源。
(举例:Fibonacci函数)

#include <stdio.h>

int fibonacci(int);


int main()
{
	int input = 0;

	printf("请输入整数:");
	scanf("%d", &input);
	fibonacci(input);
	printf("%d\n", fibonacci(input));

	return 0;
}

int fibonacci(int n)
{
	if (n > 2)
		return fibonacci(n - 1) + fibonacci(n - 2);
	else
		return 1;
}

在这里插入图片描述
在这里插入图片描述

四、编译多源代码文件的程序

1、使用头文件

(1)示例程序的注意点

以下程序注意点:

scanf("%*s");

处理非数值输入,跳至下一个空白字符。

(2)示例程序

usehotel.c ————房间费率程序

#include <stdio.h>
#include "hotel.h"    //定义符号常量,声明函数

int main()
{
	int nights;
	double hotel_rate;
	int code;

	while ((code = menu()) != QUIT)
	{
		switch (code)
		{
		case 1: hotel_rate = HOTEL1;
			break;
		case 2: hotel_rate = HOTEL2;
			break;
		case 3: hotel_rate = HOTEL3;
			break;
		case 4: hotel_rate = HOTEL4;
			break;
		default:hotel_rate = 0.0;
			printf("oops!\n");
			break;
		}
		nights = getnights();
		showprice(hotel_rate, nights);
	}
	printf("thank you and goodbye.\n");

	return 0;
}

hotel.c ————酒店管理函数

#include <stdio.h>
#include "hotel.h"

int menu(void)
{
	int code, status;

	printf("\n%s%s\n", STARS, STARS);
	printf("enter the number of the desired hotel:\n");
	printf("1) Fairfield Arms     2) Hotel olympic\n");
	printf("2) chertworthy plaza  4) the stockton\n");
	printf("5) quit\n");
	printf("%s%s\n", STARS, STARS);
	while ((status = scanf("%d", &code)) != 1 ||
		(code < 1 || code>5))
	{
		if (status != 1)
		{
			scanf("%*s");    //处理非整数输入
		}
		printf("enter an integer from 1 to 5,please.\n");
	}

	return code;
}

int getnights(void)
{
	int nights;

	printf("how many nights are needed? ");
	while (scanf("%d", &nights) != 1)
	{
		scanf("%*s");     //处理非整数输入
		printf("please enter an integer ,such as 2.\n");
	}

	return nights;
}

void showprice(double rate, int nights)
{
	int n;
	double total = 0.0;
	double factor = 1.0;

	for (n = 1; n < nights; n++, factor *= DISCOUNT)
		total += rate * factor;
	printf("the total cost will be $%0.0f.\n", total);
}

hotel.h ————符号常量 和 hotel.c 中所有函数的原型

//符号常量 和 hotel.c 中所有函数的原型

#define QUIT 5
#define HOTEL1 180.00
#define HOTEL2 225.00
#define HOTEL3 255.00
#define HOTEL4 355.00
#define DISCOUNT 0.95
#define STARS "***********************************"

//显示选择列表
int menu(void);

//返回预定天数
int getnights(void);

//根据费率,入住天数计算费用
//并显示结果
void showprice(double rate, int nights);

(3)示例程序的运行结果截图

在这里插入图片描述

五、查找地址:&运算符

主调函数不使用 return 返回的值,则必须通过地址才能修改主调函数中的值。

#include <stdio.h>

int main()
{
	int a = 0;
	int b = 9;
	printf("a=%d &a=%p\n", a, &a);
	printf("a=%d &a=%p\n", b, &b);
	acc(a);

	return 0;
}

int acc(int a)
{
	int b = 10;
	printf("a=%d &a=%p\n", a, &a);
	printf("a=%d &a=%p\n", b, &b);
}

在这里插入图片描述

总结:
从所得地址可以看出,这是 4 个不同的独立变量。
仅仅只是实现了值传递。

在这里插入图片描述
其余是指针的概念,在我的“C语言小知识点”专栏中,有详细总结。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/894343.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器视觉入门基础相关概念一 ——单目相机模型

机器视觉入门基础相关概念 相机模型 引言介绍&#xff1a;如果只是希望获取图像上的一些信息&#xff08;例如特征提取、拟合等&#xff09;&#xff0c;那么我们不会对三维空间中相机的位置有所要求。但如果希望通过二维的图像去理解三维空间中摄像机的信息&#xff0c;或者是…

简单三步完成 Telegram 生态的 Web3 冷启动

在竞争激烈的 Web3 领域&#xff0c;强有力的启动往往能决定成败。Telegram 无疑当下最火热的流量池&#xff0c;是很多 Web3 项目冷启动阶段的必选项。 但眼看着好多项目在 Telegram 生态火速获取百万级甚至千万级别的用户&#xff0c;自己的项目要怎么开始做增长&#xff0c;…

【记录】Django数据库的基础操作

数据库连接 在Django中使用 mysqlclient 这个包用于数据库的连接&#xff0c;切换至 Django环境中直接 pip install mysqlclient 安装此包 1 数据库连接配置 在项目目录下的setting.py中配置 DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: mini,#数据库名US…

nginx过滤模块怎么生效的

在nginx中&#xff0c;如果你要开发一个过滤模块&#xff0c;config中必须要加 HTTP_FILTER_MODULES$HTTP_FILTER_MODULES xxx 否则&#xff0c;即使在postconfiguration回调中加了ngx_http_top_header_filtermy_xxxx_filter_handle&#xff0c;最终my_xxxx_filter_handle也不…

PTA L1系列题解(C语言)(L1_081 -- L1_088)

L1-081 今天我要赢 题目内容&#xff1a; 2018 年我们曾经出过一题&#xff0c;是输出“2018 我们要赢”。今年是 2022 年&#xff0c;你要输出的句子变成了“我要赢&#xff01;就在今天&#xff01;”然后以比赛当天的日期落款。 输入格式&#xff1a; 本题没有输入。 输…

聊聊ASSERT处理在某些场景下的合理用法

先看看ASSERT的介绍&#xff1a; 编写代码时&#xff0c;我们总是会做出一些假设&#xff0c;ASSERT断言就是用于在代码中捕捉这些假设&#xff0c;可以将断言看作是异常处理的一种高级形式。断言表示为一些布尔表达式&#xff0c;程序员相信在程序中的某个特定点该表达式值为真…

数据结构编程实践20讲(Python版)—20并查集

本文目录 20 并查集&#xff08;Union-Find Set&#xff09;S1 说明并查集的定义并查集基本操作并查集优化并查集特点应用领域 S2 示例S3 问题1&#xff1a;朋友圈问题S4 问题2&#xff1a;网络连接恢复问题S5 问题3&#xff1a;随机生成迷宫 往期链接 01 数组02 链表03 栈04 …

【热门】用ChatGPT做智慧农业云平台——农业ERP管控系统

随着科技的进步,原有农业种植方式已经不能满足社会发展的需要,必须对传统的农业进行技术更新和改造。经过多年的实践,人们总结出一种新的种植方法——温室农业,即“用人工设施控制环境因素,使作物获得最适宜的生长条件,从而延长生产季节,获得最佳的产出”。这种农业生产方式…

vue3中监视 Reactive对象中的属性

watch 的第一个参数可以是不同形式的“数据源”&#xff1a;它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组 一、框架&#xff1a; <template><div class"divBox"><h2>姓名&#xff1a;{{ person.…

2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析

一、单选题 1、下列选项中关于 turtle.color(red) 语句的作用描述正确的是&#xff1f;&#xff08; &#xff09; A. 只设置画笔的颜色为红色 B. 只设置填充的颜色为红色 C. 设置画笔和填充的颜色为红色 D. 设置画笔的颜色为红色&#xff0c;设置画布背景的颜色为红色 正…

告别ELK,APO提供基于ClickHouse开箱即用的高效日志方案——APO 0.6.0发布

ELK一直是日志领域的主流产品&#xff0c;但是ElasticSearch的成本很高&#xff0c;查询效果随着数据量的增加越来越慢。业界已经有很多公司&#xff0c;比如滴滴、B站、Uber、Cloudflare都已经使用ClickHose作为ElasticSearch的替代品&#xff0c;都取得了不错的效果&#xff…

C#教程笔记

C#开发的程序依附.NET平台 编译器->IL中间语言->CLR->机器指令 .NET CORE平台 跨平台 .cs后缀名 快捷键 CtrlKD格式化CtrlL或CtrlX删除一行CtrlY反撤销cwTab快速生成命令行输出Ctrl空格或CtrlJ获取提示///方法注释CtrlMO代码全部折叠CtrlML代码全部展开 上升沿0变1 安…

【AIGC】优化长提示词Prompt:提升ChatGPT输出内容的准确性与实用性

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;长提示词的挑战&#x1f4af;谷歌的优化长提示词技术关键因素分析 &#x1f4af;长提示词的设计原则&#x1f4af;优化长提示词的新框架方法&#x1f4af;实验结果分析不…

Qt第十三天:网络编程:TCP和UDP的使用

我发现了有些人喜欢静静看博客不聊天呐&#xff0c; 但是ta会点赞。 这样的人呢帅气低调有内涵&#xff0c; 美丽大方很优雅。 说的就是你&#xff0c; 不用再怀疑哦 ❤️TCP&#xff1a; 一、创建项目&#xff0c;命名为Server&#xff0c;继承QWidget 二、添加Qt设计师…

【JavaEE初阶】深入透析文件-IO关于文件内容的操作(四种文件流)

前言 &#x1f31f;&#x1f31f;本期讲解关于CAS的补充和JUC中有用的类&#xff0c;这里涉及到高频面试题哦~~~ &#x1f308;上期博客在这里&#xff1a;【JavaEE初阶】文件-IO之实现文件系统的操作如何进行实现-CSDN博客 &#x1f308;感兴趣的小伙伴看一看小编主页&…

Server-Sent Event(SSE) GPT场景实现

关于SSE的基本概念可以看一下阮一峰老师的这篇文章&#xff1a;Server-Sent Events教程。 现在比较常见的场景是gpt回答的时候类似下图这种打字机的情况&#xff0c;因为AI一般响应时间会比较长&#xff0c;使用这种方式能让人别等那么久&#xff0c;是一个相对比较良好的用户…

JVM篇(学习预热 - JVM正式展开 - (实战课程学习总结))(持续更新迭代)

目录 除了了解JVM的一些基本常识&#xff0c;我们并没有提到JVM的架构&#xff0c;就像我们做项目之前的预热&#xff0c;还是有必要先了解好它的架构&#xff0c;让我们开始吧&#xff01; 一、JVM程序执行流程 1. 执行流程图 2. 热点代码 3. 热点检测方式 方法一&#x…

离散数学实验二c语言(输出关系矩阵,输出矩阵性质,输出自反闭包,对称闭包,传递闭包,判断矩阵是否为等价关系,相容关系,偏序关系)

离散数学实验二 一、算法描述&#xff0c;算法思想 &#xff08;一&#xff09;相关数据结构 typedef struct Set *S; //存放集合 struct Set {int size; //集合的元素个数char *A; //存放该集合的元素 }; Set存放有限集合A&#xff0c;该集合的元素个数为size&#xff0…

数据分析方法(回归分析,决策树与神经网络,提升树,时间序列分析,假设检验,用户画像,竞品分析)等

1.回归分析 回归分析是一种统计方法&#xff0c;用于探索自变量&#xff08;预测变量&#xff09;和因变量&#xff08;目标变量&#xff09;之间的关系。它可以帮助预测变量的变化对目标变量的影响大小。例如&#xff0c;简单线性回归用于分析两个变量之间的线性关系&#xf…

能源领域下暖通行业现状-研究

基于AI大语言模型的暖通行业能源管理系统构建研究 一、能源管理中的突出问题 1. **能源消耗监测不准确** 现有的监测系统在获取设备实时能耗数据方面存在精度不足的问题&#xff0c;难以准确反映能源的实际使用情况。这使得节能决策缺乏可靠的数据支持&#xff0c;无法精准定位…