C Primer Plus 第9章——第一篇

news2024/11/26 22:34:42

你该逆袭了

文章目录

  • 一、复习函数
    • 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语言小知识点”专栏中,有详细总结。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot redisTemplate hash 序列化探讨

前提提要&#xff1a;这个是个人小白总结&#xff0c;写完博客后开始厌蠢。 redisTemplate 有两种插入hash的方式 redisTemplate.opsForHash().putAll(key, map);redisTemplate.opsForHash().put(key, field, value);在使用的过程中&#xff0c;难免会疑问为什么 key field v…

Windows下部署autMan

一、安装autMan 下载autMan压缩包 https://github.com/hdbjlizhe/fanli/releases 解压安装包 二、运行&#xff08;注意&#xff0c;无论是交互运行还是静默运行&#xff0c;终端均不可关闭&#xff09; 基本运行 双击autMan.exe运行。 高级运行 在autMan文件夹&#xff0…

Sigrity Power SI Model Extraction模式如何提取电源网络的S参数和阻抗操作指导(一)

Sigrity Power SI Model Extraction模式如何提取电源网络的S参数和阻抗操作指导(一) Sigrity PowerSI是频域电磁场仿真工具,以下图为例介绍如果用它观测电源的网络的S参数以及阻抗的频域曲线. 观测IC端电源网络的自阻抗 1. 用powerSi.exe打开该SPD文件

工业相机详解及选型

工业相机相对于传统的民用相机而言&#xff0c;具有搞图像稳定性,传输能力和高抗干扰能力等&#xff0c;目前市面上的工业相机大多数是基于CCD&#xff08;Charge Coupled Device)或CMOS(Complementary Metal Oxide Semiconductor)芯片的相机。 一&#xff0c;工业相机的分类 …

sentinel原理源码分析系列(六)-统计指标

调用链和统计节点构建完成&#xff0c;进入统计指标插槽&#xff0c;统计指标在最后执行的&#xff0c;等后面的插槽执行完&#xff0c;资源调用完成了&#xff0c;根据资源调用情况累计。指标统计是最重要的插槽&#xff0c;所有的功能都依靠指标数据&#xff0c;指标的正确与…

你知道什么叫数控加工中心吗?

加工中心是一种高度机电一体化的数控机床&#xff0c;具有刀库&#xff0c;自动换刀功能&#xff0c;对工件一次装夹后进行多工序加工的数控机床。通过计算的控制系统和稳定的机械结构&#xff0c;加工中心能够实现高精度的加工&#xff0c;确保工件的尺寸精度和表面质量。通过…

实用好助手

在现代职场中&#xff0c;拥有高效且适用的工具能够显著提升我们的工作效率与质量。除了常见的办公软件&#xff0c;还有许多小众但非常实用的工具可以大幅度优化工作流程。以下是另外五个推荐的工作软件&#xff0c;它们各自具备独特的功能与优势&#xff0c;值得一试。 1 …

【Docker系列】在 Docker 容器中打印和配置环境变量

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

双十一有哪些值得买的东西?2024年最全双十一好物推荐榜单来了!

双十一能够入手的好东西那肯定是非常多的&#xff0c;不过要想买到性价比高、实用性强的好物&#xff0c;就必须得做些功课了。作为一个智能家居和数码领域的博主&#xff0c;自然知道每年双十一买什么是最划算的。如果有朋友正在为双十一不知道买什么而发愁&#xff0c;那就快…

python+大数据+基于热门视频的数据分析研究【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

登录后端笔记(一):注册、登录;基于MD5加密

一、注册 一、参数&#xff1a;lombok pom.xml里引入依赖&#xff1b; 二、响应数据&#xff1a;Result 原视频 两个注解对应有参无参生成构造方法&#xff1b; data类型是泛型T&#xff0c;即data在使用时可对应object可对应string字符串可对应bean对象可对应map等&#x…

微信碰一碰支付系统有哪些好的?教程详解抢先看!

支付宝“碰一碰支付”的风刚刚刮起来&#xff0c;它的老对手微信便紧随其后&#xff0c;推出了自己的碰一碰支付设备&#xff0c;再次印证了这个项目市场前景广阔的同时&#xff0c;也让与碰一碰支付系统相关问题的热度又上了一层楼&#xff0c;尤其是微信碰一碰支付系统有哪些…

炒股VS炒游戏装备,哪个更好做

这个项目&#xff0c;赚个10%都是要被嫌弃的 虽然天天都在抒发自己对股市的看法&#xff0c;但自己自始至终也没有买进任何一支股票。之所以对这个话题感兴趣&#xff0c;着实是因为手上的游戏搬砖项目也是国际性买卖&#xff0c;跟国际形势&#xff0c;国际汇率挂钩&#xff0…

RAG总结及前沿之Meta-Chunking切分思路及VisRAG多模态实现机制解读

今天我们来看两个工作&#xff0c;一个是关于RAG的切分策略&#xff0c;Meta-Chunking&#xff0c;里面基于数学常识提到的边际采样分块&#xff08;Margin Sampling Chunking&#xff09;通过LLMs对连续句子是否需要分割进行二元分类&#xff0c;基于边际采样得到的概率差异来…

基于SSM+微信小程序的房屋租赁管理系统(房屋2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的房屋租赁管理系统实现了有管理员、中介和用户。 1、管理员功能有&#xff0c;个人中心&#xff0c;用户管理&#xff0c;中介管理&#xff0c;房屋信息管理&#xff…

Nest.js 实战 (十五):前后端分离项目部署的最佳实践

☘️ 前言 本项目是一个采用现代前端框架 Vue3 与后端 Node.js 框架 Nest.js 实现的前后端分离架构的应用。Vue3 提供了高性能的前端组件化解决方案&#xff0c;而 Nest.js 则利用 TypeScript 带来的类型安全和模块化优势构建了一个健壮的服务端应用。通过这种技术栈组合&…

信雅纳Chimera 100G网络损伤仪助力Parallel Wireless开展5G RAN无线前传网络的损伤模拟

背景介绍 Parallel Wireless 为移动运营商提供唯一全覆盖的(5G/4G/3G/2G&#xff09;软件支持的本地 OpenRAN (ORAN) 解决方案。该公司与全球 50 多家领先运营商合作&#xff0c;并被 Telefonica 和 Vodafone 评为表现最佳的供应商。Parallel Wireless 在多技术、开放式虚拟化…

【多视图聚类】【ICCV 2023】基于交叉视图拓扑一致互补信息的深度多视图聚类

0.论文摘要 多视图聚类旨在从不同的来源或视角提取有价值的信息。多年来&#xff0c;深度神经网络在多视图聚类中展示了其优越的表示学习能力&#xff0c;并取得了令人印象深刻的性能。然而&#xff0c;大多数现有的深度聚类方法致力于合并和探索跨多个视图的一致潜在表示&…

Java网络编程的基础:计算机网络

在学习 Java 网络编程之前&#xff0c;我们先来了解什么是计算机网络。 计算机网络是指两台或更多的计算机组成的网络&#xff0c;在同一个网络中&#xff0c;任意两台计算机都可以直接通信&#xff0c;因为所有计算机都需要遵循同一种网络协议。 下面是一张简化的网络拓扑图…

工业以太网之战:EtherCAT是如何杀出重围的?

前言 EtherCAT 是一种开放的实时工业以太网协议&#xff0c;由德国倍福公司开发并在 2003 年 4 月的汉诺威工业博览会上首次亮相&#xff0c;目前由 EtherCAT 技术协会&#xff08;ETG&#xff09;进行维护和推广。经过 21 年的不断发展&#xff0c;EtherCAT 显示出极强的生命…