StudyTonight-C-C---中文教程-一-

龙哥盟 / 2024-11-20 / 原文

StudyTonight C/C++ 中文教程(一)

原文:StudyTonight

协议:CC BY-NC-SA 4.0

C

基础知识

C 语言概述

原文:https://www.studytonight.com/c/overview-of-c.php

欢迎来到 C 语言教程系列。这是网上最好的 C 语言教程集,会帮助你学习 C 语言。

C 语言是由丹尼斯·里奇于 1972 年在贝尔实验室开发的。1989 年,C 语言实现了标准化,在这里定义了 C 语言的特性,也称为 C 的 1989 ANSI 标准,也就是这个原因,你会看到 C 语言也称为 C89 ,因为 1989 ANSI 标准。

C 语言的最新版本是 C99 ,因为在 1999 中,一些新的特性被添加到了 C 语言中。

你一定在想,1999 年已经是 20 多年前的事了,但是 C 语言还是很相关的广泛使用的虽然还有很多其他的新语言像 C++、Java、Python、C#等。在市场上。

C 语言是一种中间层结构化编程语言,以至于需要一个编译器来运行用 C 语言编写的程序。不要担心这些术语,我们将在本教程中详细介绍它们。

C 语言的历史

C 语言已经从三种不同的结构化语言进化为 ALGOL、BCPL 和 B 语言。它使用了这些语言中的许多概念,同时引入了许多新概念,如数据类型、结构、指针等。

BCPL马丁·理查兹开发,在此基础上 B 语言肯·汤普森创建。然后 B 语言就是创造 C 语言的语言。

1989 年,该语言由美国国家标准协会正式确定。

1990 年,C 语言的一个版本被国际标准组织 (ISO)批准,那个版本的 C 也被称为 C89

History of C language

在 C 语言被全世界所接受,全世界的程序员都开始使用它之后,很快,为了进一步改进 C 语言,开发 C++ 语言的工作开始了。

创造 C 语言背后的想法是创造一种简单语言,它需要一个简单的编译器(将代码从英语翻译成计算机能理解的二进制(0 和 1)),并使程序员能够用接近英语的语言编写复杂的程序,因为早期的程序员不得不编写非常难记的机器指令。

C 语言编译器将可读的 C 语言代码转换成机器指令。

C 语言为什么这么受欢迎?

C 语言是向编程世界介绍自己的一种非常好的语言,因为它是一种简单易学的语言,能够创造奇迹。

用 C 语言编写的程序执行花费的时间很少,几乎以汇编语言指令的速度执行。(汇编级指令只不过是与计算机硬件通信的直接命令)

最初,C 语言主要用于编写系统级程序,如设计操作系统,因为在八十年代(1980-1989 年),制造一个稳定的、世界公认的操作系统的斗争正在进行。

但是 C 语言也可以用来开发其他应用,比如文本编辑器、编译器、网络驱动,很多传统的 PoS(销售点)软件比如餐厅计费系统等。

最新版本的 C

C 语言目前最新的版本是 C11 ,是 2018 年推出的。所有标准的 C 语言编译器都支持它,但是许多编译器仍然不支持它。

在这个版本中引入了许多新特性,并对提高 C 语言与 C++ 语言的兼容性进行了全面的尝试。在本教程系列的最后,一旦我们学习完 C 语言,我们将学习 C11 版本。

C 语言最广泛使用的版本仍然是 C89C99

在本教程系列中,我们将学习什么?

在本教程系列中,我们将通过代码示例、简单的解释来涵盖 C 编程语言的所有概念,并在学习时理解各种概念在现实世界中的使用。

除了教程之外,我们还为您提供了丰富的【C 程序】****C 面试 MCQs ,让您可以并行测试自己的知识。

你也可以试着写 C 程序,在我们的 在线 C 编译器 中运行,只要登录开始使用就可以了。

常见问题

这里有一些初学者在开始学习 C 语言时经常遇到的问题。

1.C 语言是什么?

这是一种计算机编程语言,由肯·汤普森和丹尼斯·里奇在贝尔实验室于 20 世纪 70 年代初开发。

它是一种编程语言,是为操作系统 UNIX 进行系统编程而开发的,但后来被用于开发日常使用的软件和程序。大型科技公司(FAANG 公司)仍在使用它来开发操作系统和创建系统级程序。

2.C 语言有什么特点?

c 是最流行的编程语言之一。它有许多特点:

  • 模块化:允许模块的复用。它有你可以使用的带有现成函数的头文件。

  • 中级语言:结合了低级语言和高级语言的优点。( C 数组、 C 指针等。)

  • 通用编程语言:可以用来实现任何一种应用,就像 Python 一样。( 学蟒 )

  • 可移植性: C 程序可以在任何操作系统(Unix、DOS、Windows)中编译或执行。你可以在 Windows 中编译这个程序,然后在 Unix 机器上运行它,它会毫无问题地运行。

  • 强大的编程语言:是一种非常高效、强大的编程语言。最好用于数据结构和设计系统软件。

  • C 是区分大小写的语言

我们已经在下一个教程中列出了 C 语言的所有特性-C 语言的特性

3.C 语言是用来做什么的?

它是最具可移植性的语言之一,主要用于创建系统应用程序,这些应用程序构成了 Windows、UNIX 和 Linux 操作系统的主要部分。

c 是一种通用编程语言。它用于企业应用程序、游戏、图形和需要计算或简单软件的应用程序等。T3】

4.今天 C 在哪里用?

c 用于开发操作系统和内核级程序。

它用于编译器的生产。我们可以借助 C 语言开发桌面和手机操作系统,例如安卓。

结论

本教程是关于 C 语言及其历史的概述。c 是丹尼斯·里奇于 1972 年在美国电话电报公司和贝尔实验室开发的。在下一个教程中,我们将详细了解 C 语言的特性。



C 语言的特点

原文:https://www.studytonight.com/c/features-of-c.php

这里我们列出了 C 语言的所有主要特性,给大家更多学习 C 语言的理由。

C 编程语言是一种功能丰富的编程语言。它具有开发人员(初学者或专家)希望编程语言具有的所有必需特性。

C 语言是从基础剑桥编程语言(BCPL)B 语言发展而来的。但是它比 BASIC 快很多倍,并且还有更多我们将在本教程中学习的特性。

下面是一个简单的图表,列出了 C 语言的主要特性。

features of C language

让我们逐一讨论所有这些特性。

1.简单高效

C 语言是一种简单的语言,即使对于初学者来说也很容易学习,并且在开发时间和执行时间方面都非常高效。是的,如果你想用 C 语言创建软件,你可以用很少的时间来完成,这取决于你想编码的软件的大小。

2.轻便

C 语言程序在任何地方都以同样的方式运行。意思是如果你已经在你的 Windows OS 笔记本电脑或电脑上写了一个简单的 C 程序像程序一样在 C 中找到 N 个数的和,然后编译运行,那么你就可以拿着编译好的代码在任何其他操作系统或机器上运行,像 Linux 或 macOS 等。,您的 C 程序将总是返回相同的结果。

如果你有用 C 语言编写的用于 Unix 操作系统的软件,而你现在想在 Windows 操作系统上运行它,你可以很容易地将软件适配到 Windows 操作系统上,这就是 C 语言的强大之处。

因此,我们可以说 C 语言是可移植的。

3.结构化程序设计语言

C 语言是一种结构化的编程语言,因为我们可以用 C 语言创建函数。使用函数,我们可以将特定的操作从主程序中分离出来,然后一次又一次地使用它。

结构化语言不仅仅是具有创建函数的能力,它还支持循环条件语句等。所有这些我们将在接下来的教程中详细介绍。

4.强大的

C 语言是一种非常强大的编程语言。它具有广泛的特性,如支持许多数据类型、运算符、关键字等。,允许使用函数循环决策语句来构造代码,然后是复杂的数据结构,如结构数组等。,以及指针,这使得 C 相当足智多谋和强大等。

使用 C 语言你可以轻松的读取、写入和创建文件。这听起来像是今天的一个基本特征,但在 20 世纪 90 年代初,这是一个游戏规则的改变者。

5.丰富的标准库

支持各种内置函数和库,可以快速创建开发。对 C 语言的标准库支持是极好的,你会看到你在用 C 语言写代码的时候会用到的很多关键字或者现成的操作都已经预定义好了。我们只需要使用它们,而不用担心它们是如何工作的。

这些库在 C 语言中称为头文件

6.图书馆支持

不仅仅是 C 语言的标准库,还有一个由世界各地的开发人员/编码人员创建的第三方库组成的大型生态系统,任何人都可以使用它们。

甚至你可以编写自己的 C 语言库,并通过你的 Github 配置文件在线分发。你永远不知道,世界各地的人们可能需要你的解决方案。

7.单独编译

C 语言代码被编译,然后运行。我们将在另一个教程中学习如何编译 C 语言代码。现在,假设代码已经编译好了。显然,代码的编译需要一些时间。一小部分代码会编译得更快,而大部分代码需要时间来编译。

在 C 语言中,你可以破解你的代码,并把它放到多个源代码文件中。C 语言将单独编译这些文件,然后将它们链接在一起执行。

这使得编译速度快了

这样做的另一个好处是,多个程序员/开发人员可以在处理单个项目的同时处理不同的代码文件。

8.中级语言

C 编程语言集两者之长。

一种低级语言一般速度快,功能强大,但是很难理解和编写代码。虽然高级语言对我们来说很容易理解和编写代码,但是它也是高度可移植的,但是它通常很慢,并且不能直接与系统硬件对话。

因此,C 编程语言被称为中级编程语言,允许对位、字节和地址进行操作,因此提供了对计算机系统的低级访问,同时易于使用、可移植,并支持高级语言的所有其他特性等。

9.基于语法的语言

像大多数高级语言一样,例如 Java、C++、C#, C 语言有语法,有适当的规则写代码,C 语言严格遵循。

如果您编写了任何不允许的内容,您将会得到一个编译时错误,当编译器因为一些不正确的代码语法而无法编译您的代码时,就会发生这种情况。

10.格式化自由语言

C 语言是一种无格式语言。C 语言代码中不需要行号,或者我们可以说行号没有任何意义。没有必要将语句放在一行的指定位置。

11.编译语言

C 语言使用编译器将代码编译成目标代码,这不过是计算机理解的机器码。因此,要运行一个 C 语言程序,我们必须先安装一个 C 语言编译器。

12.区分大小写的语言

在 C 语言中,大小写字母是不同的。也就是说if和 C 语言中的IF不一样。


常见问题解答

这里有一些常见的问题,初学者在学习 C 语言的特性时会遇到。

1.C 语言的主要特点是什么?

C 语言的主要特点是,简单(易学)但功能强大可移植中级语言,是结构化,需要一个编译器来执行。C 语言还有一个丰富的标准库,支持的是广泛的第三方库

**### 2.C 语言流行背后的主要原因是什么?

C 语言流行背后的主要原因是它拥有丰富的特性集,使其成为一种适合广泛用例的语言。您可以使用 C 语言或任何其他简单的软件来创建操作系统。C 语言是一种通用编程语言。

3.为什么 C 被认为是一种强大的编程语言?

它被认为是一种强大的语言,因为它提供了广泛的功能,如支持许多数据类型、运算符、关键字等。,允许使用函数循环决策语句来构造代码,然后是复杂的数据结构,如结构数组等。,以及指针,这使得 C 相当足智多谋和强大等。

4.C 语言可移植吗?

是的,C 语言代码是便携。如果你有用 C 语言编写的用于 Unix 操作系统的软件,而你现在想在 Windows 操作系统上运行它,你可以很容易地将软件适配到 Windows 操作系统上,这就是 C 语言的强大之处。

5.C 语言有什么优势?

下面给出了 C 语言的一些优点:

C 是一种可移植的语言。

b)提供丰富的内置功能支持。

c)它是一种强大而高效的语言。

C 语言是一种结构化语言,具有高级语言和低级语言的特点。


结论

在本教程中,我们介绍了 C 语言的特性,用一个例子解释了每个特性,以便您理解每个特性的含义。不要只学习 C 语言的特性,而是要努力理解这些特性的含义。



安装 C 编译器和集成开发环境(Turbo C++)

原文:https://www.studytonight.com/c/installing-c-compiler-ide.php

最受初学者欢迎的 C 语言 IDE 是 Turbo C/C++。在本教程中,我们将介绍 Turbo C 的安装步骤,还将分享一些您可以用于 C 编程的其他 IDE(集成开发环境)。

什么是 IDE?

IDE 或集成开发环境是一个软件,它有一个代码编辑器,还有编程语言的编译器,因此您不需要安装任何其他东西。

集成开发环境具有管理源代码所需的所有功能,如文件处理、编辑选项等。同时它也支持不同的编程语言环境,为此它安装了内置的编译器/解释器。

What is an IDE

许多重集合成开发环境允许安装第三方插件来进一步增强集成开发环境的功能。

Turbo C 是一个用 C 语言编写代码的 IDE。您也可以使用 Turbo C 本身编译和运行您的代码。 Turbo C++ 是 Turbo C 的升级版,也可以用于 C 语言编程。

C++ 编译器支持 C 语言语法,因为 C++ 语言是建立在 C 语言之上的。

还有其他的 ide 可以用于 C 编程,比如:

  1. Dev-C++(从这里下载:下载 Dev-C++ )
  2. Eclipse ( 下载 Eclipse IDE )

如果您是初学者,我们建议您使用 Turbo C 或 Turbo C++。

为 Windows 7/8/10 安装 Turbo C/C++

让我们看看如何安装 Turbo C 来编写 C 程序。

第一步。从下载 IDE 安装程序开始

可以从这个链接下载 Zip 文件:下载 Turbo C

Download and Install Turbo C

第二步。解压缩文件以查看安装程序文件

接下来,使用 WinRar 或任何其他软件来查看您下载的 zip 文件中有什么。

Download and install turbo C

第三步。开始安装

如果你是 Windows 操作系统用户,点击。开始安装的 msi 文件。

Download and instal Turbo C

你会看到 Turbo C/C++ 的 InstallShield 向导,点击下一步按钮。

Download and Install Turbo C

安装应该开始了。现在坐下来,等待安装完成。

Download and install Turbo C

安装完成后,您将看到以下窗口,勾选启动程序复选框(如果尚未勾选),然后点击完成启动 Turbo C/C++ IDE,开始编写 C 语言代码。

Download and install Turbo C++

第四步。启动 Turbo C/C++ IDE

要启动 IDE,您可以通过在桌面上创建快捷方式来轻松启动 IDE。或者打开开始菜单,搜索 Turbo C ,你会在那里看到应用程序。

start turbo c++

点击 Turbo C++ app 选项,会看到如下窗口。然后点击启动 Turbo C++ 按钮,启动 IDE 应用程序。

Download and install turbo C++

这就是它的样子。 Bluuueee!

Download and install Turbo C++

C 程序设计的其他集成开发环境

可以使用 Dev-C++ IDE 或者 Eclipse IDE 进行 C 编程。在集成开发环境的介绍中,我们已经分享了两者的下载链接。

如果您想要一个更现代的 C/C++ IDE 来编写 C 程序,那么您应该尝试 Dev-C++ 因为它不像 Eclipse IDE 那么复杂,同时具有基本的 Turbo C/C++ IDE 所缺乏的许多特性。

Use dev-c++ for c programs


结论:

在本教程中,我们学习了什么是 IDE 或 Integrated 开发环境,哪些 IDE 可以用于 C 编程,以及如何逐步安装最流行的 C 语言 IDE,即 Turbo C/C++。



第一个 C 程序及其结构

原文:https://www.studytonight.com/c/first-c-program.php

在本教程中,我们将学习创建第一个 C 程序,然后了解它的结构。首先来看看如何用 C 语言编写一个简单的最基础的 Hello World 程序。我们开始吧。

这是用 C 语言打印“你好世界”的程序。

#include <stdio.h>

int main()
{
    printf("Hello World");
    return 0;
}

你好,世界

运行代码→

要在本地计算机上运行上述代码,您必须在计算机/笔记本电脑上安装一个 C 语言编译器。我们将在下一个教程中学习如何做到这一点- 编译并运行 C 代码。

如果你不想在你的计算机上安装 C 编译器,不要担心。你可以使用我们的在线编译器运行 C 程序并练习。点击上面的运行程序按钮打开编译器。

理解 C 程序的结构

下面给出了 C 程序的一些不同部分:

  • 预处理器

  • 头文件

  • main() 功能

  • C 中的变量

  • 语句&C 中的表达式

所有这些都是 C 语言程序必不可少的部分。不要担心这一切,我们会一件一件地了解一切,也会清除你所有的困惑。

让我们从介绍我们在上面的 Hello World 程序中使用的各种代码语句开始。

1.预处理器

#include是任何 C 程序的第一个语句。它被称为预处理器。预处理器的任务是初始化程序的环境,即把程序和所需的头文件联系起来。

顾名思义,这一行代码是负责做预处理,在实际代码(逻辑)执行之前。

Pre-processor in C language

所以,当我们说#include<stdio.h>的时候,是通知编译器在执行程序之前把 stdio.h 头文件也就是标准 I/O 库包含到程序中。

标准 I/O 库让你从键盘读取输入(即标准输入),然后将输出写入控制台屏幕(即标准输出),这是一个非常有用的库。

这里所说的控制台屏幕,是指 Windows 操作系统下的 CMD 或命令提示符,使用 Linux/Ubuntu/macOS 下的终端

同样,我们可以包含任意数量的头文件。

#include不是唯一的预处理器。每当你看到任何一段以#符号开头的代码,这意味着它是一个 C 语言的预处理器。稍后我们将详细了解预处理器。

2.头文件

一个头文件是一组内置(现成)功能的集合,我们可以在程序中直接使用。

头文件包含函数的定义,可以通过使用预处理器#include语句和头文件的名称在任何 C 程序中使用。

有一些标准的头文件伴随着默认的 C 安装,比如 stdio.h 头文件。还有很多其他这样的文件,我们稍后会了解它们。

随着时间的推移,你会对头文件有一个清晰的了解,现在把它们看作是 C 语言打包的现成函数集合,你可以使用它们而不用担心它们是如何工作的,你所要做的就是把头文件包含在你的程序中。

Header files in C program

要使用任何标准库函数,必须包含适当的头文件。这是在 C 源代码的开头完成的。

例如,在 C 程序中使用printf()函数,该函数用于在控制台屏幕上显示任何东西,则需要行#include <stdio.h>,因为头文件 stdio.h 包含printf()函数定义。

所有头文件都会有。h 分机。

3.main()功能

main()功能是每个 C 程序都必须有的功能

C 程序中该函数内部的所有内容都将被执行,因此实际的逻辑或代码总是写在main()函数内部。

顾名思义,这是主(的首要或吸引中心)功能。

#include <stdio.h>

int main()
{
    printf("Hello World");
    return 0;
}

在上面的 Hello World 代码示例中,main()函数之前写了int,还记得吗?嗯,这就是main()功能的返回类型。我们稍后将详细讨论它。

main()函数后面的花括号{ }包含了main()函数的

我们将在即将到来的教程中学习 C 语言中的函数是什么。

4.printf()功能

printf()是一个用于在控制台上打印(显示)任何内容作为输出的功能。这个函数是在 stdio.h 头文件中定义的,我们已经把它包含在我们的 C 程序中了。

我们将在下一个教程中介绍如何获取输入和显示输出。

5.返回语句

return语句用于返回对调用者函数的响应。它通常是任何 C 语言函数的最后一条语句。不要担心这一点,当我们学习 C 语言中的函数时,我们将讨论这一陈述。

6.分号

需要注意的是,C 中的每个语句都应该以分号(;)。如果您错过添加任何分号,编译器将给出一个错误。

如何在我的电脑上写 C 程序?

所有的 C 程序都可以在记事本记事本++ 等普通文本编辑器中编写和编辑,必须用文件名和保存。c 延长。例如, helloworld.c 可以是 helloworld 程序的文件名。

如果不添加扩展名。c 那么编译器不会将其识别为 C 语言程序文件。


常见问题解答

1.说出 C 语言编程中不同的预处理程序?

C 语言中不同的预处理程序有#include#if#define#ifdef#undef等。还有更多。预处理器是在执行 C 程序的主代码之前执行的语句。

2.C 语言中的 main()函数能理解什么?

C 语言中的main()函数充当任何程序的入口点,或者我们可以说代码的执行从这里开始。执行main()函数内部的源代码。

3.如何给 C 程序添加注释?

要添加单行注释,可以在注释后面使用斜线**//**,对于多行注释,可以使用如下: /此处注释/

4.C 程序中的 stdio.h 是什么?

stdio 代表标准输入输出。h 是文件的扩展名,表示是头文件

这个头文件的主要用途是,它有助于从用户(键盘)获得输入,并将输出结果文本返回给监视器(屏幕)。这个头文件中有我们可以在程序中使用的现成函数,例如printf()scanf()函数在 stdio.h 头文件中定义。


结论

在本教程中,我们看到了一个简单的 C 语言 Hello World 程序,并介绍了它的结构。在下一个教程中,我们将在本地计算机/笔记本电脑上设置 C 编译器,这样您也可以在您的计算机上运行该程序。



编译并运行 C 程序

原文:https://www.studytonight.com/c/compile-and-run-c-program.php

要编译运行一个 C 语言程序,需要一个 C 编译器。一个编译器是一个用来编译和执行程序的软件。要在计算机/笔记本电脑中设置 C 语言编译器,有两种方法:

  1. 下载一个成熟的集成开发环境,如 Turbo C++ 或微软 Visual C++ 或 DevC++,它附带一个 C 语言编译器。

  2. 或者,您可以使用任何文本编辑器分别编辑程序文件和下载 C 编译器,然后使用命令行运行 C 程序。

如果你还没有为 C 语言安装 IDE 按照这个分步指南 为 C 语言安装 Turbo c++

使用集成开发环境-涡轮增压

我们会推荐你使用 Turbo C 或者 Turbo C++ IDE,这是 C 编程最古老的 IDE。它可以在网上免费获得,对初学者很有好处。

第一步:打开 turbo C IDE(集成开发环境),点击文件,然后点击新增

first c program with turbo C

第二步:写一个我们在上一篇文章中创建的 Hello World 程序- C Hello World 程序

Write a C program with turbo C

第三步:点击编译菜单,然后点击编译选项,或者按键按 Alt + F9 编译代码。

Compiling a C program with turbo C

第四步:点击运行或按 Ctrl + F9 运行代码。是的,首先编译 C 程序以生成目标代码,然后运行该目标代码。

Running a C program with turbo C

第五步:输出在这里。

Output of C program with turbo C

不使用任何集成开发环境运行 C 程序

如果你不想设置 IDE,更喜欢老派的方式,那就从 GCC 网站https://gcc.gnu.org/install/下载名为gcc的 C 编译器

一旦你下载并安装了gcc编译器,你所要做的就是,打开任意一个文本编辑器,复制并粘贴 C Hello World Program 的 C 程序代码,并将其以 helloworld.c 的名称保存,就像你以名称保存的任何其他文件一样。

现在,打开命令提示符或终端(如果使用的是 Ubuntu 或 Mac OS),转到保存 helloworld.c 程序文件的目录。

键入命令gcc hello.c编译代码。这将编译代码,如果没有错误,那么它将产生一个名为 a.out (默认名称)的输出文件

现在,要运行程序,输入./a.out你会看到你好,世界显示在你的屏幕上。

$ gcc hello.c
$ ./a.out

你好,世界

C 语言编译和运行的区别?

你一定在想为什么这是一个两步的过程,首先,我们编译代码,然后运行代码。我们对 Turbo C 做了同样的事情,对命令行或终端也是如此。

嗯,编译是编译器检查程序语法是否正确的过程,语法没有错误,如果代码没问题就把 C 语言源代码转换成机器可理解的目标代码。

当我们运行一个编译好的程序时,运行的只是已经编译好的代码。

当我们使用命令行运行一个 C 程序时,这种差异是显而易见的。当你编译代码时,一个。out 文件生成,然后运行执行程序。

一次。out 文件生成,然后你在源代码文件中对你的程序做任何的修改,你就要再次编译代码,否则,。out 文件将有旧的源代码并将继续运行旧程序本身。


常见问题解答

1.你通过编译的过程理解了什么?

这是一个编译器检查程序语法是否正确的过程。如果在语法中发现任何错误,那么它将抛出错误。编译时抛出的错误称为编译时错误

2.命名 Turbo C 中用来编译代码的键。

ALT + F9 在 turbo C 中为了编译代码而使用。

3.C 程序是如何运行的?

在 C 程序的编译和执行过程中,编译器生成与 C 程序文件同名但扩展名不同的输出文件。那个。c 扩展文件称为保存程序代码的源文件。现在,当我们编译文件时,然后 C 编译器寻找错误。

4.在哪里可以编写和运行 C 程序?

您可以按照以下步骤使用集成开发环境编写和运行 C 程序:

  • 第一步:打开 turbo C IDE(集成开发环境),点击文件,然后点击新建

  • 第二步:编写C 程序代码。

  • 第三步:点击编译或按 Alt + F9编译代码。

  • 第四步:点击运行或按 Ctrl + F9 运行代码。

  • 第五步:turbo C 将打开控制台,向您显示程序的输出。


结论

本教程讲述了如何使用一个名为 Turbo C 的集成开发环境运行和编译任何 C 程序。我们还介绍了如何在不使用任何集成开发环境的情况下完成这项工作。



C 源代码编译过程

原文:https://www.studytonight.com/c/c-compilation-process.php

C 源代码编译过程是一个多步骤的过程,涉及到预处理编译代码链接库等。在本教程中,我们将学习如何将 C 代码编译成目标代码。

将任何编程语言(一般为中级或高级语言)编写的源代码转换为计算机可理解的机器级语言的过程称为编译。用于该转换的软件被称为编译器

在 C 语言中,通过编译,将 C 语言源代码转换为目标代码

C language Source code to object code

编译器取输入源代码,以目标代码的形式提供输出。C 语言的完整编译过程进一步分为四个阶段:

  1. 预处理

  2. 编译

  3. 组装,以及

  4. 链接

编译器检查源代码中是否有任何语法结构错误,检查后,如果发现源代码没有错误,则生成扩展名为的目标代码。obj (适用于车窗)或。o (适用于 Linux)。

现在让我们看看 C 语言编译过程的不同阶段。

编译过程

如上所述,编译过程的不同阶段如下:

  • 预处理

  • 收集

  • 装配

  • 连接

在下面的流程图中,我们已经解释了编译过程是如何工作的,以及编译 C 语言源代码的不同阶段是什么。

C compilation process

让我们按照执行的顺序来讨论 C 语言源代码编译的所有这些阶段。

步骤 0:源文件的预处理

在这个阶段,源文件的预处理完成。预处理器是接受 C 源代码文件,然后执行以下任务的程序:

  • 它将从源代码中删除注释。

  • 如果使用了任何宏,它将执行宏扩展(不用担心宏,我们稍后会了解它们)

  • 它将执行包含的头文件的扩展。

第一步:预处理器

它是一个在将源程序传递给编译器之前对其进行处理的程序。在这一步,任何 C 程序中使用的预处理程序都将被处理,源代码也准备好进行编译。

  • 每个预处理语句必须以#开始,其中 # 被称为预处理器指令

  • 每个预处理指令都是单行代码语句。

  • #后的单词叫做预处理器命令

一些预处理器指令如下:

1。#包括

使用头文件的名称在 C 语言程序代码中包含特定的头文件。

2。#定义

这用于在 C 语言中定义一个宏。

3。#错误

这个预处理器命令用于打印错误信息。

就像上面三个一样,还有很多其他的预处理程序,我们将在单独的教程中详细介绍它们。

因此,预处理器扩展源代码(添加所需的信息),然后将扩展的源代码传递给编译器。

它给出了()。一、)扩展到最初带有()的源代码文件。c )延伸。

第二步:编译器

预处理器扩展的代码然后被传递给编译器。众所周知,编译器是将高级语言(或中级语言)代码转换成汇编代码的程序,再转换成机器能理解的机器码。

因此,预处理器给编译器的预处理代码然后被编译器转换成汇编代码,然后被传递给汇编器

获取了()的源文件。i )上一步的扩展转换为()。s )由编译器扩展。

第三步:汇编程序

汇编器将从编译器获得的汇编代码转换成目标代码。该步骤中文件的扩展名变为()。obj )。

不要认为汇编程序是生成目标代码的独立程序。汇编程序是 C 语言源代码编译过程的一部分。

当在外行语言中,我们说,C 代码被编译时,它意味着涵盖所有这些步骤的完整编译过程已经完成。

步骤 4:链接器

链接器是一种工具,用于将程序的所有部分按执行顺序链接在一起。该阶段后的代码成为可执行机器码

在某些情况下,我们的程序可能会引用其他文件中定义的函数。或者,如果某个程序的代码太大,我们可以将它分成两个文件,分别编译,然后使用 Linker 链接。

在 C 语言编译过程中,链接器起着非常重要的作用。

如果你的 C 程序包含一个头文件,并且你正在使用该头文件中定义的一些函数,那么链接器将将库内函数所需的目标代码链接到你的程序的目标代码并将它们打包在一起。

同样,如果您的程序代码太大,并且您将其分成两个文件,那么这两个源代码文件将分别转换为目标代码,然后链接器将链接它们,并使代码准备好执行。这也叫单独编译


常见问题

以下是一些与 C 语言编译过程相关的常见问题。

Q1。你对编译器这个术语有什么理解?

它是一种计算机程序,用于将高级编程语言或中级编程语言的源代码翻译成机器代码,机器代码可以执行,机器可以理解该做什么。

Q2。什么是预处理器?

预处理器是一个指令,用于指示编译器在实际编译开始之前对源代码进行预处理。C 语言程序的某些部分可以使用预处理器来指定,预处理器只不过是要在编译开始时执行的语句。

Q3。的另一个名字是什么?c 文件?

扩展名为的 C 语言代码文件。c 也被称为源代码文件

Q4。链接器的作用是什么?

链接器用于将程序的所有部分链接在一起,以便执行。

如果你的 C 程序包含一个头文件,并且你正在使用该头文件中定义的一些函数,那么链接器将将库内函数所需的目标代码链接到你的程序的目标代码并将它们打包在一起。

同样,如果您的程序代码太大,并且您将其分成两个文件,那么这两个源代码文件将分别转换为目标代码,然后链接器将链接它们,并使代码准备好执行。这也叫单独编译

Q5。C 语言的编译步骤有哪些?

以下是用 C 语言编译的步骤:

  1. 预处理器(预处理)

  2. 编译器(编译)

  3. 汇编程序

  4. 链接器(链接)


结论

在本教程中,我们学习了如何编译我们将在即将到来的教程中编写的 C 语言代码。编译中遵循的各种步骤是什么,在这些步骤中会发生什么?

如果你在这之后感到困惑,不要担心,只要阅读它,当我们继续学习教程时,你就会明白一切。



C 语言基本语法规则

原文:https://www.studytonight.com/c/c-syntax.php

C 语言语法指定了用 C 语言编写代码的规则。简而言之,这些规则告知如何在 C 语言程序中形成语句——代码行应该如何开始,它应该如何结束,在哪里使用双引号,在哪里使用花括号,在哪里使用括号,等等。

什么是语法?

任何语言,无论是英语、印地语还是西班牙语,都有一个语法,定义了使用语言的规则,例如如何组成句子,不同的单词意味着什么等等。

在正常的口语或计算机编程语言中,语法意味着如何排列单词、字符、特殊字符,以做出有意义的陈述或表达等。

如果有人说程序中有一个语法错误,意味着您没有正确编写程序,您可能在为程序键入代码时遗漏了一些分号或其他一些一般性错误。

有一个语法错误并不意味着你的代码逻辑不正确,它意味着你写错了。一旦语法正确,那么只编译代码,然后运行

代币

C 程序中最小的单个单元被称为 C Token 。令牌可以是 关键字或标识符常量变量 ,或任何其他在 C 语言中有某种意义的符号。C 程序也可以称为各种代币的集合

因此,C 语言的语法定义了在编写 C 语言代码时如何一起使用这些标记。

让我们举个例子,

#include <stdio.h>
int main()
{
    printf("Hello,World");
    return 0;
}

在上面的代码中,如果我们采用printf语句:

printf("Hello,World");

那么本声明中的代币为:printf("Hello,World");

所以 C 令牌基本上是 C 程序的构建模块。

下图显示了整个 Hello World 程序中的 token。

C tokens and syntax

现在让我们看看一些重要的语法规则,在用 C 语言编写代码时,您必须始终记住这些规则。

语句以分号(;)结束

分号 ; 在 C 语言中用来标记一个语句的结束和另一个语句的开始。

任何语句末尾没有分号,都会误导编译器认为该语句尚未完成,会在其后添加下一个连续语句,可能导致编译(语法)错误

#include <stdio.h>
int main()
{
    printf("Hello,World")
    return 0;
}

错误:应为“;”在‘返回’
之前返回 0;
^
命令终止,退出代码为 1

在上面的程序中,我们省略了printf("...")语句中的分号,因此编译器会认为从printf开始直到return 0语句之后的分号都是一条语句,这将导致编译错误。

向代码添加注释

注释是 C 程序中简单的纯文本,在编译过程中不进行编译。

我们可以在程序中写注释,来解释程序的各个部分。虽然写评论不是强制性的,但是建议让你的程序更有描述性,也更容易被别人理解。

添加注释使代码更易读。

两种方式我们可以写评论。

  1. 使用 // :这是用来写一个单行评论

  2. 使用 /* */ :任何包含在/**/中的内容,将被视为多行注释

您甚至可以使用这两种技术注释掉代码,并且该语句或部分代码不会被编译和执行。

C 语言注释示例:

这里有一个简单的程序来展示如何使用注释:

/* 
    This is my first program.
    I am very excited!
*/

#include <stdio.h>
int main()
{
    // Printing Hello World
    printf("Hello,World");
    // printf("Useless piece of code.");
    return 0;
}

从上面的代码中可以看到,我们添加了注释,并且还注释了一个printf()语句,这个语句不会被执行。

C 语言的更多语法规则

这只是一个开始,因为我们将在 C 语言中学习更多的概念,我们将学习使用它们的语法以及例子。

在编写代码时,任何东西都有一种编写和使用的方式,这就是它的语法。

  • C 是一种区分大小写的语言,所以所有的 C 指令都必须用小写字母写。不一样。

  • 所有 C 语句必须以分号结束。

  • 空格在 C 中用于添加空格和制表符。

  • 您不必担心代码的缩进。

  • 当我们编写一个函数时,它的主体被包含在花括号中,就像对于main()函数一样。我们将在讨论函数时详细了解这一点。

下图展示了 C 程序的结构。

C program structure


常见问题解答

以下是一些与 C 语言语法相关的常见问题。

Q1。用 C 语言的代币能理解什么?

C 程序中最小的单个单元被称为 C Token 。令牌可以是 关键字或标识符常量变量 ,或任何其他在 C 语言中有某种意义的符号。C 程序也可以称为各种代币的集合

Q2。如果我们忘记在 C 语言的语句末尾使用分号,会发生什么?

如果我们忘记在 C 语言的任何语句的末尾放置分号,那么它将导致语法错误。在这种情况下,编译器会发出一条错误消息,指出应为分号

Q3。什么是编译错误?

编译错误或编译时错误是指如果 C 程序的语法不正确,编译器返回的错误。当你试图编译一个有语法错误的程序时,编译器会给出一个错误,这被称为编译时错误

Q4。如何在 C 语言中添加注释?

我们可以在注释文本的开头使用//来添加单行注释,在 C 程序中将文本包含在/**/中来添加多行注释。

Q5。C 语言中没有main()功能的程序能运行吗?

在 C 语言中,main()函数定义了执行的起点。如果一个 C 程序没有main()函数,那么该程序中不会执行任何代码语句。在大多数情况下,如果编译器找不到main()函数,它会给出一个错误。


结论

本教程是关于 C 语言的基本语法规则。我们已经讨论了分号的重要性,C 语言中的标记,以及如何用 C 语言编写单行和多行注释。



关键字和标识符

原文:https://www.studytonight.com/c/keywords-and-identifier.php

C 语言中的关键字和标识符是任何程序的构造块。关键字是预定义的,这意味着 C 语言有一个关键字列表,而标识符是用户定义的,这意味着您在编写 C 语言程序时可以指定标识符。让我们看看这两个是什么。

什么是关键字?

每种编程语言都有一些内部使用的、对语言有一定意义的保留词,这样的词被称为保留关键字或者只是关键字

以现实世界为例,当有人说:你有我的笔记本电脑吗?你立即想象一台笔记本电脑,如果要求得到他/她的笔记本电脑的人有一只名叫“笔记本电脑”的狗(并且正在询问这只狗的情况),你不会明白,除非你知道他/她有一只名叫“笔记本电脑”的狗。这会导致混乱,对吧。

因此,任何像 C 语言这样的编程语言为了某种特定的目的而在内部使用的单词,除了这个目的之外是不允许使用的,否则,语言编译器将会混淆。

在上一个教程中,我们学习了 C 语言语法 ,我们了解到 C 程序中的一切都是一个 Token

因此,我们可以说单词或关键字也是记号

什么是标识符?

标识符是用于标识 C 语言中任何内容的单词或文本。

就像你有一个名字,用它大家都叫你,可以是约翰、罗恩、斯佳丽、莫妮卡等。,同样在 C 语言中,当我们定义一个变量或者一个函数,或者一个结构等。我们给它们命名,以便我们更容易识别它们,并在需要时使用它们。这些名称被称为标识符

标识符也是代币。再次,因为每一个有意义的符号、单词等。在 C 语言中是 C 标记,因此标识符也是标记。

C keywords and Tokens

关键字

现在我们知道,关键字是在 C 语言中有特殊含义的保留词。

C 语言关键字的含义已经在 C 编译器中描述过了,这意味着 C 编译器知道这些词的含义以及它们之间的关系。

这些含义是不能改变的。因此,关键字不能用作变量名称或函数名称(简称为标识符),因为这将试图改变关键字的现有含义,这是不允许的。

不能使用关键字作为标识符。这意味着您不能使用关键字来命名您的变量、函数、结构或指针或任何其他东西。

C 语言总共有 32 个关键字。

C 中的关键字列表:

以下是 C 语言中可用的关键字表。

| 汽车 | 两倍 | (同 Internationalorganizations)国际组织 | 结构 |
| 破裂 | 其他 | 长的 | 转换 |
| 情况 | 列举型别 | 注册 | 类型定义 |
| 常量 | 走读生 | 返回 | 联合 |
| 茶 | 漂浮物 | 短的 | 无符号的 |
| 继续 | 为 | 签名 | 不稳定的 |
| 系统默认值 | 转到 | 西泽夫 | 空的 |
| 做 | 如果 | 静电 | 正在… |

所有这些关键字都是在 C89 标准中定义的,C89 标准是 C 语言的第一版,而一些更多的关键字是在后来的 C99 标准中加入的。

C99 增加的关键字有:

| _Bool | _ 虚数 | 限制 |
| _ 复杂 | 在一条直线上的 |   |

每个关键字都有自己的含义,例如int关键字用于定义整数数据类型值,if / else用于定义条件语句等等。随着本教程的深入,我们将学习其中的大部分内容。

需要注意的要点:

关于关键字,这里有一些有用的要点需要记住。

  • 关键字不能用作标识符(永远记住这一点)。

  • 关键字必须用小写字母书写。除了一些基于 C99 的关键字,所有其他关键字都是小写的。

  • 关键字对 C 编译器有特殊的意义,所以尊重它,否则你会得到一个编译时错误。

main()不是关键字,但你应该只把它当成关键字。因为这个函数是一个特殊的函数。如果你把任何变量命名为 main ,你可能会混淆编译器。

标识符

在 C 语言中,标识符是变量、常量、函数、结构、指针或任何其他用户定义的数据的名称,用于标识它们。

因为定义标识符是由用户决定的,所以有一些规则必须遵守,这些规则是由 C 语言定义的,以避免编译器中不必要的错误。

定义标识符的规则:

  • 标识符只能有字母数字字符 (a-z,a-z,0-9)和下划线 ( _)。

  • 标识符的第一个字符只能包含字母 (a-z,a-z)或下划线 ( _)。

  • 标识符在 C 语言中区分大小写。例如,名称名称将被视为两个不同的标识符。

  • 关键字不允许用作标识符。

  • 不允许在标识符中使用特殊字符,如分号句号空格斜线逗号

使用标识符和关键字:

让我们看几个使用关键字和标识符的例子。我们将定义一个 C 变量,所以不要混淆,我们很快就会学习变量。

当我们在任何 C 语言程序中声明一个变量或任何函数时,要使用它,我们必须为它提供一个名称,然后这个名称在整个程序中使用,例如:

int myvariable = "Studytonight";

这里myvariable是存储值“今夜研究”的变量的名称或标识符。而int是关键字。它们都是信物。

我们再举一个例子,

int money;
double salary;

有效标识符的示例:

这里有一些有效的标识符,

total, avg1, difference_1;

无效标识符的示例:

这里有一些无效的标识符,

$myvar; // incorrect
x!y;  // again incorrect

使用关键字作为标识符

当我们使用关键字作为标识符时会发生什么?

#include <stdio.h>

int main() {
   // using void as name of variable (identifier)
   int void = 0;

   return 0;
}

错误:声明说明符
中有两个或多个数据类型 int void = 0;
^

运行代码→

C 语言编译器会认为我们错误地一起使用了两种数据类型,会给出一个错误。因为void在 C 语言中也是一个数据类型(因此是一个关键字)。

常见问题

以下是一些与关键字和标识符相关的常见问题。

Q1。标识符和变量有什么区别?

标识符只是变量的名称,而变量代表一个存储字段,根据其数据类型存储一些数据。就像你和你的名字有什么区别。你的名字只是人们称呼你的一个词,而你是一个人。

结论

本教程是关于 C 语言中的关键字和标识符的。它们都是令牌的一部分。C 语言中的标记被定义为 C 语言中最小的独立元素,是创建程序的基本构件。我们已经详细介绍了关键字和标识符以及它们的有效语法。



理解 C 数据类型

原文:https://www.studytonight.com/c/datatype-in-c.php

顾名思义,数据类型定义了正在使用的数据类型。每当我们定义一个变量或者在 C 语言程序中使用任何数据时,我们都必须指定数据的类型,这样编译器就知道需要什么类型的数据。

例如,您可能想要使用像 12100 这样的数字,或者像 99.9510.5 这样的小数点数字,或者像【今晚学习】这样的文本,所有这些值都是由 C 语言编译器以不同方式处理的****

在本教程中,我们已经解释了数据类型,对于代码示例,使用 C 数据类型教程来检查。

数据类型

大体上,在 C 语言中有 5 种不同的数据类型,它们是:

类型 例子
基础 字符、整数、浮点、双精度。
得到 数组、结构、并集等。
列举 枚举数
布尔类型 对还是错
空的 空值

C datatype categories

主要数据类型:

C 语言有 5 种基本数据类型,它们是:

  1. 字符 - ASCII 字符集或一般单个字母表,如【a】****【B】等。

  2. 整数 -用于存储整数,如 121001000 等。

  3. 浮点 -小数点或实数值,如 99.910.5 等。

  4. -整数或浮点类型中不允许的非常大的数值。

  5. Void -这表示没有值。这种数据类型在我们定义函数时最常用。

有不同的关键字来指定这些数据类型,关键字有:

数据类型 关键字
性格;角色;字母 char
整数 int
浮点 float
两倍 double
空的 void

primary datatypes in c

每个数据类型都有一个以位/字节定义的大小,并且这些数据类型可以保存的值有一个范围

不同数据类型的大小

不同数据类型的大小取决于编译器和处理器类型,简而言之,它取决于运行 C 语言的计算机和安装的 C 编译器版本。

字符是 1 字节

char数据类型为 1 字节8 位。这基本上是一样的,不受处理器或所用编译器的影响。

int 可以是 2 字节/4 字节

有一个非常简单的方法来记住int数据类型的大小。int数据类型的大小通常等于程序执行环境的字长。简单来说,对于 16 位环境int16 位2 字节,对于 32 位环境int32 位4 字节

浮点是 4 字节

float数据类型为 4 字节32 位大小。是单精度数据类型,用于保存十进制值。它用于存储大值。

double相比,float是一个更快的数据类型,因为double数据类型处理非常大的值,因此速度很慢。

double 是 8 字节

double数据类型为 8 字节64 位大小。它可以存储的值是浮点数据类型可以存储的值的两倍,因此被称为double

在这 64 位中, 1 位用于符号表示, 11 位用于指数,其余 52 位用于尾数

double数据类型大约可以容纳 15 到 17 位数字,在小数之前和小数之后。

void 为 0 字节

void数据类型没有任何意义,因此它没有大小。

| 好阅读:理解什么是位和字节 |

在讨论这些数据类型的取值范围之前,还有一个更重要的概念需要学习,那就是数据类型修饰符

数据类型修饰符:

在 C 语言中,有 4 个数据类型修饰符,它们与基本数据类型一起使用来进一步对它们进行分类。

比如你说,有操场,对方就知道有操场,但是你可以具体一点说,有板球操场或者足球操场,这样对对方来说就更清楚了。

同样,C 语言中也有修饰符,以使主数据类型更具体

以下是修饰语:

  1. 签名

  2. 无符号的

  3. 长的

  4. 短的

顾名思义,有符号和无符号用于表示任何数据类型的有符号(+和-)无符号(仅+)值。而会影响任何数据类型的值的范围。

例如,有符号 int无符号 int短 int长 int 等。都是 C 语言中有效的数据类型。

现在让我们看看不同数据类型的范围,这些数据类型是由 5 种主要数据类型以及上面指定的修饰符形成的。

数据类型值范围

在下表中,我们有 C 语言中不同数据类型的范围。

类型 典型位大小 最小范围 格式规范
char eight -127 到 127 %c
unsigned char eight 0 到 255 %c
signed char eight -127 到 127 %c
int 16 岁或 32 岁 -32,767 至 32,767 %d%i
unsigned int 16 岁或 32 岁 0 至 65,535 %u
signed int 16 岁或 32 岁 与 int 相同 %d%i
short int Sixteen -32,767 至 32,767 %hd
unsigned short int Sixteen 0 至 65,535 %hu
signed short int Sixteen 与短整型相同 %hd
long int Thirty-two -2,147,483,647 至 2,147,483,647 %ld%li
long long int Sixty-four -(2 63 - 1)至 2 63 - 1(由 C99 标准增加) %lld%lli
signed long int Thirty-two 与 long int 相同 %ld%li
unsigned long int Thirty-two 0 至 4,294,967,295 %lu
unsigned long long int Sixty-four 2 64 - 1(由 C99 标准增加) %llu
float Thirty-two 1E-37 至 1E+37,精度为六位数 %f
double Sixty-four 1E-37 至 1E+37,精度为十位数 %lf
long double Eighty 1E-37 至 1E+37,精度为十位数 %Lf

如上表所示,数据类型和修饰符的不同组合会改变值的范围。

当我们想要打印任何数据类型的任何变量的值时,我们必须在printf()语句中使用格式说明符

如果该值超出范围会发生什么?

嗯,如果你试图给任何超过允许值范围的数据类型赋值,那么 C 语言编译器会给出一个错误。下面是一个简单的代码示例来说明这一点,

#include <stdio.h>

int main() {
   // allowed value up to 65535
   unsigned short int x = 65536;

   return 0;
}

警告:大整数隐式截断为无符号类型[-Overflow]
无符号短 int x = 65536
^

运行代码→

当使用一个类型修饰符而没有任何数据类型时,则int数据类型被设置为默认数据类型。所以,unsigned表示unsigned``int``signed表示signed``int``long表示long``int``short表示short int

signed``unsigned是什么意思?

这解释起来有点棘手,但让我们试试。

简单来说,unsigned修饰词表示所有正值,而signed修饰词表示正负值

当编译器获得一个数值时,它将该值转换为二进制数,这意味着 0 和 1 的组合。比如二进制的 32767 就是011111111 111111,二进制的 1 就是 01(或者 0001)2 就是 0010 等等。

有符号整数的情况下,最高位或左边第一个数字(二进制)用作符号标志。如果标志为 0 ,则数字为,如果为 1 ,则数字为

因为一位用于显示数字是正的还是负的,所以少了一位来表示数字本身,因此范围更小。

对于符号 int11111111111 111111 表示-32,767 ,由于第一位是符号标志,将其标记为负数,其余表示数字。鉴于在无符号整数的情况下,1111111111是指 65,535

派生数据类型:

虽然有 5 种主要的数据类型,但是在 C 语言中也有一些派生的数据类型用于存储复杂的数据。

派生数据类型只不过是主数据类型,但有点扭曲或组合在一起,就像一个 数组结构并集指针 。这些将在后面详细讨论。

结论:

在下一个教程中,我们将学习变量,在这里,您将学习数据类型的实际用法,以及 man 代码示例。所以我们继续吧。



使用 C 数据类型的示例

原文:https://www.studytonight.com/c/using-datatypes-examples.php

数据类型定义了正在使用的数据类型。在上一个教程中,我们已经详细介绍了 C 数据类型

C 语言有 5 种基本数据类型,它们是:

  1. 人物 - char

  2. 整数 - int

  3. 浮点 - float

  4. - double

  5. 虚空 - void

让我们一个一个地了解它们。

要了解数据类型的大小数据类型的值范围以及各种类型修饰符,如signedunsignedlongshort -详细访问 C 数据类型

1. 字符数据类型

char数据类型是指用单引号括起来的字符值,范围为 -127 到 127

从这个范围可以清楚地看到,我们甚至可以在char数据类型中使用小整数值

例如,

char status = 'Y';

第 2 个整数数据类型

int数据类型用于存储整数,整数是没有任何小数部分或指数部分的值。

int数据类型可以存储十进制(十进制)、八进制(八进制)和十六进制(十六进制)值。

// simple int value
int a = 100;

// negative value
a = -100;

// unsigned int value - with suffix U or u
int x = 1000U;

// long int value
long int long_val = 3500L;

对于int数据类型的值,我们可以使用后缀Uu,告诉编译器该值是针对unsigned int数据类型的,后缀Ll是针对一个long int值的。

了解有关类型标识符(signedunsignedlongshort)及其使用时如何更改主要数据类型的更多信息-访问 初学者 C 数据类型指南

3.浮点数据类型

float数据类型用于存储实数,实数可能有小数(分数)部分或指数部分。这是一个单精度数字。

我们来看一些float值的例子,

float x = 127.675;

// with suffix F or f
float y = 1000.5454F;

就像int数据类型一样,float也可以与类型修饰符一起使用-了解更多信息,访问 C 数据类型初学者指南

4.双重数据类型

大到不能存储在float数据类型中的实数被存储为double数据类型。这是一个双精度数字。双数据类型值可以在小数点前保留 15 到 17 位,在小数点后保留 15 到 17 位。

这里有一个例子,

double x = 424455236424564.24663224663322;

当我们需要这么大的数字时,我们应该只使用double数据类型,否则不会,因为使用double数据类型会使程序变慢

结论:

在本教程中,我们看到了一些 C 语言中不同数据类型的例子。要详细了解 C 数据类型,请访问 【初学者 C 数据类型指南】



变量示例

原文:https://www.studytonight.com/c/variables-in-c.php

在本教程中,我们将学习什么是变量,如何在 C 语言中声明和定义变量,以及在 C 语言中什么是常量和字面值

变量就像一个容器(存储空间),它有一个名称,您可以在其中存储数据。

C variable example

就像你家有地址(门牌号/公寓号),所以无论什么时候你在网上点东西,只要提供你家地址,送货主管就能找到。

在 C 语言中,如果我们想在我们的程序中使用一些数据值,该怎么做呢?这是用变量完成的。

当我们在 C 程序中创建一个变量时,C 编译器根据变量的数据类型分配一个存储空间(8 位用于char,16/32 位用于int等)。),然后该存储空间被赋予一个名称,即变量名

c variable concept

一旦创建了一个变量,我们就可以在其中存储值。我们可以根据需要多次更改变量中存储的值,但是我们应该确保存储正确的数据类型值。

使用变量的语法:

下面是如何在 C 语言中创建或声明一个新的变量,

data_type var_name;

其中,数据类型是一个有效数据类型(如果需要的话,还有数据类型修饰符),而 var_name 是变量的名称。

例如,

int marks;

这里,marks是变量的名称,可以存储int类型的值。

一旦我们声明或创建了变量,我们就可以给它赋值。这叫做变量定义

// variable declaration
int marks;
// variable definition
marks = 10;

我们也可以在一个步骤中完成的声明和定义,就像这样(推荐)。

int marks = 10;

C Variable declaration and definition

您可以随时更改变量的值。但是要确保值是正确的数据类型

// variable defined
int marks = 10;
// assign a new value
marks = 33;

变量的数据类型

C 语言中的一个变量必须给定一个类型,这个类型定义了变量中可以存储什么类型的数据。如果不提供任何数据类型,那么 C 编译器会给出编译时错误或语法错误。

数据类型可以是charintfloatdoubleshortintlongint等。数据类型以及修饰符。

可以了解 C 数据类型 查看 C 语言支持的各种数据类型列表。

让我们举个例子,

// char type variable
char status = 'Y';

// int type variable
int marks = 95;

// float type variable
float percentage = 94.6;

// double type variable
double long = 76.997429;

如果你试图给一个变量分配一个不正确的数据类型值,那么编译器可能会给出错误,或者它会自动将该值转换成变量的数据类型。

**例如,

#include <stdio.h>

int main() {
   // assign incorrect value
   int x = 10.58;
   printf("Value is %d", x);
   return 0;
}

值为 10

运行代码→

正如您在输出中看到的,C 编译器删除了小数之后的部分,因为int数据类型只能存储整数。

我们将在下一个教程中学习printf()函数和%d(用于打印int数据类型的值),并提供更多的代码示例。

不能更改数据类型

一旦我们用某种数据类型定义了一个变量,那么我们就不能改变该变量的数据类型。

例如,

// int variable
int marks = 10;

float marks;    // error 

命名变量的规则

当您创建一个变量时,您应该总是给这个变量一个有意义的名称。并遵循以下规则命名变量:

  1. 变量名不能以数字开头。

  2. 变量名可以由字母、数字和特殊符号组成,如下划线_

  3. 变量名中不允许有空格。

  4. 关键字不允许作为变量名。

  5. 大小写名称视为不同,因为 C 区分大小写,建议变量名保留小写。

根据上面的规则,让我们看几个错误名称的例子:

int 1var;    // incorrect - should not start with number
int var1;    // correct

int my$var    // incorrect - special characters not allowed
int my_var1;    // correct

int my var;    // incorrect - spaces not allowed

char else;    // can't use Keywords

int count;    // valid variable name
int Count;    // new variable
int COUNT;    // new variable

创建变量-幕后

变量的声明必须在程序中使用之前完成。声明做了以下事情。

  1. 它告诉编译器变量名是什么。

  2. 它指定变量将保存什么类型的数据。

  3. 在定义变量之前,编译器不必担心给变量分配内存空间。

  4. 该声明更像是通知编译器程序中使用了具有以下数据类型的变量。

  5. 我们甚至可以在main()函数之外声明一个变量,使用extern关键字。

extern int a;
extern float b;
extern double c, d;

定义初始化一个变量意味着编译器现在必须为该变量分配存储空间,因为它将在程序中使用。

我们甚至可以通过使用逗号将同一数据类型的多个变量分开,在一行中声明它们。

例如,

int a;
float b, c;

初始化一个变量意味着给它提供一个值。

int a = 10;

变量和标识符的区别?

标识符是编程语言中任何变量、函数、结构、指针或任何其他实体的名称。正如我们在本教程中刚刚学到的,变量是一个命名的内存位置,用于存储程序中使用的数据。

| 标识符 | 可变的 |
| 标识符是赋予变量、函数等的名称。 | 而变量用于命名存储数据的内存位置。 |
| 标识符可以是变量,但不是所有的标识符都是变量。 | 所有变量名都是标识符。 |
| 示例:

// studytonight is identifier for a variable
int studytonight;

// studytonight is identifier for a function
int studytonight() { 
    ... 
}

| 示例:

// int variable
int a;
// float variable
float a;

|

理解标识符和变量之间区别的另一个很好的类比是:

你可以认为标识符int x是一个变量的名称,但是它也可以是一个函数的名称int x() { },并且仍然是一个标识符。

就像奥巴马是一个人的名字,也是一个基金会的名字。

结论

在本教程中,我们学习了 C 变量,如何创建变量,给变量赋值,以及创建变量后会发生什么。我们还了解了创建新变量时数据类型的重要性。



字面值/常量

原文:https://www.studytonight.com/c/c-literals.php

如果我们想在 C 程序中使用一些数据值,我们也可以直接使用一个值,而不是创建一个变量来存储该值。当我们在 C 程序中直接使用一个值而不创建变量时,它被称为字面值

当我们想在程序中使用固定值时,使用字面值,因此字面值也被称为常量

1100Y '10.5 等。然而,当我们在 C 中使用一个变量时,我们可以改变存储在变量中的值。

在语言中,字面值可以有 5 种类型,它们是:

  1. 整数字面值

  2. 字符字面值

  3. 浮点字面值

  4. 字符串字面值

  5. 反斜杠字符字面值(转义序列)

1.整数字面值

C 程序中使用的任何没有小数或指数部分的数值都是整数。

整数字面值有三种类型:

  1. 小数位数(基数 10)

  2. 八进制数(基数 8) -使用数字 0 到 7 。对于八进制,数字 10 与 8 相同。

  3. 十六进制数(以 16 为基数)-使用数字 0 到 9 ,以及字母 A 到 F 。(A、B、C、D、E、F 代表 10、11、12、13、14 和 15)

例如,

Decimal: 7, -10 etc
Octal: 023, 045 etc
Hexadecimal: 0x2a, 0x521 etc

在 C 语言中,八进制数字以 0 开头,十六进制数字以 0x 开头。

也可以在整数值上使用类型后缀,让编译器更容易理解整数值的类型。如果在值后加上L,编译器会将其视为long值,如果在值后加上U,编译器会将其视为无符号

例如,

3500L, 14l    // long value

99U, 89u    // unsigned int value

2.浮点字面值

任何有效的浮点值,当直接在 C 程序中使用时,都称为浮点字面值。

浮点数有小数部分(分数)或指数部分。

例如,

100.50
0.000127
-0.77E-5

E-5 代表 10 -5

如果我们在值后添加类型后缀 Ff,那么编译器默认会将该值视为float类型。

例如,

127.7F, 40f etc.

3.字符字面值

当在 C 程序中直接使用时,有效的字符数据类型值称为字符字面值。

字符值包含在单引号中。

例如,

'A', 'B', 'c', '#', etc.

4.字符串字面值

字符序列被称为字符串。我们将在本教程系列的后面部分详细了解 C 弦。

字符串字面值是用双引号括起来的多个字符的值。

例如,

"study", "tonight", "c programming", etc.

5.反斜杠字符字面值

也称为转义序列,这些字符与反斜杠字符\的组合对 C 编译器有特殊的意义。

反斜杠字符用于转义特殊含义的字符,使其成为编译器的正常字符。

例如,如果您使用单引号,编译器会认为它是字符值的开始或结束,但是如果您想要单引号字符怎么办。

'\''    \\ this is character with value '

在上例中的第一个和最后一个单引号标记了字符值的开始和结束,而反斜杠转义字符通知编译器将其后面的单引号视为正常字符。

密码 意义
\b 退格
\f 换页
\n 换行
\r 回车
\t 横表
" 双引号
' 单引号
\ 反斜线符号
\v 垂直标签
\a 警报
? 问号
\N 奥克塔高兴
\xN 十六进制常量

换行符水平标签代码是非常常用的,当你开始用 C 语言编码时,你会经常用到它们。所以记住\n代表换行符\t代表水平制表符

结论:

至此,我们已经涵盖了 C 语言中使用的所有常量,它们也被称为字面值。不要忽略反斜杠转义字符,因为它们也非常重要,并且在 C 程序中广泛使用。



常量值变量——const关键字

原文:https://www.studytonight.com/c/c-const-variable.php

如果要创建一个值不能更改的变量,那么可以使用const关键字创建一个常量值变量。

类型为const的变量不能被程序改变。我们可以在定义变量时提供一个值,然后,在整个程序中,该变量将保持相同的值。

使用const关键字

这里有一个使用 const 关键字的简单例子,

const int totalmarks = 100;

在上面的代码中,我们定义了一个名为totalmarks的变量,并为其赋值 100 。因为我们在定义变量时使用了const关键字,因此我们不能更改totalmarks变量的值。

更改const变量值

如果在程序中const变量被定义后,你试图改变它的值,那么编译器会给出一个错误。

例如,

#include <stdio.h>

int main() {
   // initialize a constant variable 
   const int total_marks = 10;

   // try changing value
   total_marks = 80;

   return 0;
}

错误:赋值只读变量‘total _ marks’
total _ marks = 80;
^

运行代码→

正如您在错误消息中看到的,编译器表示该变量是一个只读变量,因此其值不能更改

因为常量变量是只读变量,所以编译器可以将这些变量放入只读存储器 ( ROM )。

当我们将一个变量定义为const时,那么该程序中的任何东西都不能改变该变量的值。

因此,如果const变量的值改变了,那么你可以说程序之外的东西改变了值,它可以是硬件设备或者任何外部事件。

结论:

在本教程中,我们学习了如何创建常值变量,这些变量的值不能被程序更改。



输入和输出

原文:https://www.studytonight.com/c/c-input-output-function.php

输入表示为程序提供一些数据用于程序中,输出表示在屏幕上显示数据或将数据写入打印机或文件。

C 编程语言提供标准库函数来读取任何给定的输入,并在控制台上显示数据。

在继续使用 C 语言进行输入和输出之前,请检查以下主题,以便更好地理解这个概念:

  • C 语法规则

  • 编译运行 C 程序

  • C 中的数据类型

  • C 中的变量

用于标准输入和输出的功能存在于 stdio.h 头文件中。因此,为了使用这些函数,我们需要在程序中包含 stdio.h 头文件,如下所示。

#include <stdio.h>

以下是用于标准输入和输出的函数:

  1. printf()功能-显示输出

  2. scanf()功能-获取输入

  3. getchar()putchar()功能

  4. gets()puts()功能

C 语言,电脑显示器,打印机等。输出设备被视为文件,将输出写入这些设备的过程与将输出写入文件的过程相同。

printf()功能-显示输出

printf()函数是 C 语言中使用最多的函数。该功能在 stdio.h 头文件中定义,用于在控制台上显示输出(标准输出)。

此功能用于打印任何变量的简单文本句子或值,该变量可以是intcharfloat或任何其他数据类型。

printf()示例-打印语句

让我们使用 printf()函数打印一个简单的句子。

#include <stdio.h>

int main() {
   // using printf()
   printf("Welcome to Studytonight");

   return 0;
}

欢迎今晚来学习

运行代码→

在本教程中,到目前为止,我们已经看到了许多像上面这样的代码示例。

要了解一个基本 C 语言程序的完整代码和结构,请查看 C 语言中的【Hello World Program】

printf()示例-打印整数

我们可以使用printf()函数,使用%d格式说明符打印来自变量的整数值。

例如,

#include <stdio.h>

int main() {
   int x = 10;
   // using printf()
   printf("Value of x is: %d", x);

   return 0;
}

x 的值为:10

运行代码→

在上面的程序中,我们使用了%d说明符来指定将要添加到那里的值的类型。格式说明符%d%i用于整数值。

printf()示例-打印字符

%c格式说明符用于使用printf()功能打印字符变量值。

#include <stdio.h>

int main() {
   // using printf()
   char gender = 'M';

   printf("John's Gender is: %c", gender);
   return 0;
}

约翰的性别是:M

运行代码→

printf()函数内部,我们使用了一个单引号,它会工作得很好,因为我们在外部使用了双引号。我们也可以使用反斜杠字符像这样转义单引号\'

printf()示例-打印浮点和双精度

在下面的代码示例中,我们使用了printf()函数来打印一个floatdouble变量的值。

对于float值,我们使用%f格式说明符,对于double值,我们使用%lf格式说明符。

#include <stdio.h>
int main() {
   // using printf() 
   float num1 = 15.50;
   double num2 = 15556522.0978678;

   printf("Value of num1 is: %f \n", num1);
   printf("Value of num2 is: %lf", num2);

   return 0;
}

num 1 的值为:15.500000
num 2 的值为:15556522.097868

运行代码→

我们在第一个printf()语句的末尾使用了用于换行符的\n转义序列,这样下一个printf()语句输出就是下一行中显示的

printf()示例-打印多个输出

我们可以使用单个printf()函数来显示多个变量的值。

#include <stdio.h>

int main() {
   // using printf() for multiple outputs 
   int day = 20;
   int month = 11;
   int year = 2021;

   printf("The date is: %d-%d-%d", day, month, year);

   return 0;
}

日期:2021 年 11 月 20 日

运行代码→

正如您在上面的代码示例中看到的,我们可以在使用printf()函数打印多个变量的值时也可以进行格式化

格式规范

要使用printf()语句打印不同数据类型的值,我们需要使用格式说明符,就像我们在上面的代码示例中使用的那样。

此外,当我们使用scanf()功能从用户处获取输入时,我们还必须使用这些格式说明符来指定用户期望什么类型的输入。

这是所有格式说明符的列表。

数据类型 格式规范
int %d%i
char %c
float %f
double %lf
short int %hd
unsigned int %u
long int %li
long long int %lli
unsigned long int %lu
unsigned long long int %llu
signed char %c
unsigned char %c
long double %Lf

scanf()功能-获取输入

当我们想要从用户那里获取输入时,我们使用scanf()功能。当我们接受用户的输入时,我们将输入值存储到变量中。

scanf()函数可用于从用户处获取任何数据类型输入,我们需要注意的是,存储值的变量具有相同的数据类型。

让我们看几个代码示例。

scanf()示例-输入整数值

如果我们必须从用户输入整数值,我们必须定义一个整数变量,然后使用scanf()函数。

#include <stdio.h>
int main() {
   // using scanf() 
   int user_input;

   printf("Please enter a number: ");
   scanf("%d", &user_input);
   printf("You entered: %d", user_input);

   return 0;
}

运行代码→

请输入一个数字:7
您输入的是:7

在上面的代码示例中,我们使用了%d格式说明符来通知scanf()函数,用户输入将是整数类型。

我们还在变量名称前使用了&符号,因为&user_input指的是user_input变量的地址,用户输入值将存储在该地址。

scanf()示例-采用浮点值输入

就像整数值一样,我们可以接受任何不同数据类型的输入。让我们看一个浮点型值的例子。

#include <stdio.h>
int main() {
   // using scanf() 
   float user_input;

   printf("Please enter a decimal number: ");
   scanf("%f", &user_input);
   printf("You entered: %f", user_input);

   return 0;
}

请输入一个小数:7.007
您输入的是:7.007

我们使用了%f格式说明符并定义了一个float类型变量。尝试将double类型的值作为用户输入。double的格式说明符是%lf

scanf()示例-输入字符值

让我们看看如何从用户那里获取简单的字符输入。

#include <stdio.h>
int main() {
   // using scanf() 
   char gender;

   printf("Please enter your gender (M, F or O): ");
   scanf("%c", &gender);
   printf("Your gender: %c", gender);

   return 0;
}

请输入您的性别(男、女或男):男
您的性别:男

scanf()示例-获取多个输入

#include <stdio.h>
int main() {
   // using scanf() for multiple inputs
   char gender;
   int age;

   printf("Enter your age and then gender(M, F or O): ");
   scanf("%d %c", &age, &gender);
   printf("You entered: %d and %c", age, gender);

   return 0;
}

输入你的年龄然后性别(M,F 或 O): 32 M
你输入的是:32 和 M

*一些额外信息

printf()函数返回其打印的字符数,scanf()返回其读取的字符数。

int i = printf("studytonight");
printf("Value of i is: %d", i);

研究 I 的 t 值为:12

在本程序中printf("studytonight");将返回12作为结果,该结果将存储在变量i中,因为今晚学习一词有 12 个字符。

第一个printf()语句也将在输出上打印语句今晚学习

getchar() & putchar()功能

getchar()函数从终端读取一个字符,并将其作为整数返回。这个函数一次只读取一个字符。

如果你想读一个以上的字符,你可以在循环中使用这个方法。

putchar()功能在屏幕上显示传递给它的字符,并返回相同的字符。这个函数一次也只显示一个字符。

如果要显示多个字符,循环使用putchar()方法。

#include <stdio.h>

void main( )
{
    int c;
    printf("Enter a character");
    /*
        Take a character as input and 
        store it in variable c
    */
    c = getchar();
    /*
        display the character stored 
        in variable c 
    */
    putchar(c);
}

输入字符:今晚学习
S

当您编译上述代码时,它会要求您输入一个值。当您输入值时,它将显示您输入的值。

gets() & puts()功能

gets()函数将一行从标准输入(标准输入)读入由str 指针指向的缓冲区,直到出现终止换行符或 EOF(文件结束)。

puts()函数将字符串str和一个尾随换行符写入标准输出

str是指向存储 C 字符串的字符数组的指针。(如果现在不能理解,忽略。)

#include <stdio.h>

void main()
{
    /* character array of length 100 */
    char str[100];
    printf("Enter a string: ");
    gets(str);
    puts(str);
    getch();
    return 0;
}

输入字符串:今晚学习
今晚学习

当你编译上面的代码时,它会要求你输入一个字符串。当您输入字符串时,它将显示您输入的值。

scanf()gets()的区别

这两个函数的主要区别是scanf() 遇到空格时停止读字符,但是gets() 也把空格作为字符来读

如果使用scanf()输入名称为今晚学习,它只会读取并存储学习,并在空格后留下部分。但是gets()功能会完全读取。

结论

在本教程中,我们学习了 C 语言的输入和输出。通过很多代码示例,我们了解了如何使用printf()函数和scanf()函数向用户显示输出,并从用户那里获取输入。

我们还了解了一些用于显示输出和获取用户输入的其他功能。



运算符示例

原文:https://www.studytonight.com/c/operators-in-c.php

C 语言支持一组丰富的内置运算符。运算符是一个符号,它告诉编译器根据提供给运算符的值执行某种数学或逻辑运算。

运算符在程序中用于操作数据和变量。

在继续使用 C 语言的运算符之前,我们建议您了解 C 变量和数据类型:

  • C 变量

  • C 字面值

  • C 数据类型

  • 使用 C 数据类型(示例)

  • 编译运行 C 程序

运算符

c 运算符可分为以下类型:

  • 算术运算符

  • 关系运算符

  • 逻辑运算符

  • 按位运算符

  • 赋值运算符

  • 条件运算符

  • 特殊运算符

让我们通过工作代码示例,一个接一个地了解这些运算符类型。

什么是操作数?

操作数是任何运算符都可以使用的值。例如,当我们说 4+5 时,这里,数字 45 是操作数,而 + 是运算符。

不同的运算符处理不同数量的操作数,就像+运算符需要两个操作数或值一样。

算术运算符

C 语言支持加法减法乘法除法等所有基本算术运算符。

下表显示了所有基本算术运算符及其说明。

| 运算符 | 描述 |

例子

(其中ab是具有某个整数值的变量)

|
| --- | --- | --- |
| + | 将两个操作数(值)相加 | a+b |
| - | 从第一个操作数中减去第二个操作数 | a-b |
| * | 将两个操作数相乘 | a*b |
| / | 分子除以分母,即左边的操作数除以右边的操作数 | a/b |
| % | 这是模运算 r,它返回两个操作数除法的余数作为结果 | a%b |
| ++ | 这是增量运算符 -将整数值增加 1。该运算符只需要一个单操作数。 | a++++a |
| -- | 这是递减运算符 -将整数值减少 1。该运算符只需要一个单操作数。 | --bb-- |

要了解算术运算符的执行顺序,请访问 C 运算符优先级。

示例:基本算术运算符

让我们看一个代码示例来理解 C 程序中基本算术运算符的使用。

#include <stdio.h>

int main() {

    int a = 50, b = 23, result;

    // addition
    result = a+b;
    printf("Addition of a & b = %d \n",result);

    // subtraction
    result = a-b;
    printf("Subtraction of a & b = %d \n",result);

    // multiplication
    result = a*b;
    printf("Multiplication of a & b = %d \n",result);

    // division
    result = a/b;
    printf("Division of a & b = %d \n",result);

    return 0;

}

a 的加法&b = 73
a 的减法&b = 27
a 的乘法&b = 1150
a 的除法& b = 2

运行代码→

示例:使用模数运算符(%)

模数运算符在对提供的值进行除法运算后返回余数。

#include <stdio.h>

int main() {

   int a = 23, b = 20, result;

   // Using Modulus operator
   result = a%b;

   printf("result = %d",result);

   return 0;

}

结果= 3

运行代码→

示例:使用递增和递减运算符

递增运算符用于将任何数值的值增加 1,而递减运算符用于将任何数值的值减少 1。

#include <stdio.h>

int main() {

   int a = 10, b = 20, c, d;

   /* 
      Using increment operator
   */
   printf("Incrementing value of a = %d \n", ++a);

   /* 
      Using decrement operator
   */
   printf("Decrementing value of b = %d \n", --b);

   // first print value of a, then decrement a
   printf("Decrementing value of a = %d \n", a--);
   printf("Value of a = %d \n", a);

   // first print value of b, then increment b
   printf("Incrementing value of b = %d \n", b++);
   printf("Value of b = %d \n", b);

   return 0;

}

a = 11 的递增值
b = 19 的递减值
a = 11 的递减值
a = 10 的递增值
b = 19 的递增值
b = 20 的值

运行代码→

在上面的代码示例中,我们使用了增量运算符作为++ab++,而使用了减量运算符作为--ba--

当我们使用增量和减量操作符作为前缀(在操作数之前的意思),然后首先进行增量操作并使用该值,就像在前两个printf()函数中一样,我们得到了ab的更新值。

而当我们使用递增和递减运算符作为后缀(表示在操作数之后)时,则首先计算较大的表达式,在这种情况下为printf(),然后更新操作数的值。

关系运算符

关系运算符(或比较运算符)用于检查两个操作数之间的关系。检查两个操作数是否相等不相等小于大于等。

如果关系检查通过,则返回 1 ,否则返回 0

例如,如果我们有两个数字 14 和 7 ,如果我们说 14 大于 7 ,这是,因此该检查将返回 1 作为关系运算符的结果。另一方面,如果我们说 14 小于 7 ,这就是,因此会返回 0

下表显示了 C 语言支持的所有关系运算符。

| 运算符 | 描述 |

例子

(a``b,其中a = 10,b = 11)

|
| --- | --- | --- |
| == | 检查两个操作数是否相等 | a == b,返回 0 |
| != | 检查两个操作数是否不相等。 | a != b,返回 1,因为a不等于b |
| > | 检查左边的操作数是否大于右边的操作数 | a > b,返回 0 |
| < | 左边的检查操作数小于右边的操作数 | a < b,返回 1 |
| >= | 检查左操作数是否大于或等于右操作数 | a >= b,返回 0 |
| <= | 检查左边的操作数是否小于或等于右边的操作数 | a <= b,返回 1 |

要了解关系运算符的执行顺序,请访问 C 运算符优先级。

示例:关系运算符

当我们使用关系运算符时,那么根据比较的结果,如果是,那么输出就是 1 ,如果是,那么输出就是 0 。我们将在下面的例子中看到同样的情况。

#include <stdio.h>

int main() {

   int a = 10, b = 20, result;

   // Equal
   result = (a==b);
   printf("(a == b) = %d \n",result);

   // less than
   result = (a<b);
   printf("(a < b) = %d \n",result);

   // greater than
   result = (a>b);
   printf("(a > b) = %d \n",result);

   // less than equal to
   result = (a<=b);
   printf("(a <= b) = %d \n",result);

   return 0;

}

(a = = b)= 0
(a<b)= 1
(a>b)= 0
(a<= b)= 1

运行代码→

在上面的代码示例中,a有值 10b有值 20 ,然后对它们进行不同的比较。

在 C 语言中, true 是除零以外的任何值。而就是

逻辑运算符

C 语言支持以下 3 种逻辑运算符。

| 运算符 | 描述 |

例子

(a``b,其中a = 1,b = 0)

|
| --- | --- | --- |
| && | 逻辑“与” | a && b,返回 0 |
| &#124;&#124; | 逻辑或 | a &#124;&#124; b,返回 1 |
| ! | 逻辑非 | !a,返回 0 |

这些运算符用于执行逻辑运算,并与条件语句一起使用,如 C if-else 语句。

  1. 对于运算符,只有当两个操作数都为真时,结果才为真

  2. 使用运算符,如果一个单操作数为真,则结果为真

  3. NOT 操作符变真为假变假为真

示例:逻辑运算符

在下面的代码示例中,我们使用了逻辑运算符。

#include <stdio.h>

int main() {

   int a = 1, b = 0, result;

   // And
   result = (a && b);
   printf("a && b = %d \n",result);

   // Or
   result = (a || b);
   printf("a || b = %d \n",result);

   // Not
   result = !a;
   printf("!a = %d \n",result);

   return 0;

}

(a&&b)= 0
(a | | b)= 1
(!a) = 0

运行代码→

C 语言中的按位运算符

按位运算符在位级别执行数据操作。这些运算符还执行从右向左的比特移位。按位运算符不适用于floatdoublelongdoublevoid等。(了解 C 浮点和双数据类型)。

下表包含按位运算符。C 语言中有 6 位运算符

运算符 描述 例子
& 按位“与”
&#124; 按位“或”
^ 按位异或(异或)
~ 补语
>> 右移
<< 左移位

按位“与”、“或”和“非”运算符的工作方式与逻辑“与”、“或”和“非”运算符相同,只是按位运算符一点一点地工作

下面我们有一个真值表**来展示这些操作符如何在不同的值下工作。

a b a & b a | b
Zero Zero Zero Zero Zero
Zero one Zero one one
one Zero Zero one one
one one one one Zero

按位运算符可以生成任意值。结果不是必须为 0 或 1。

逐位>><<运算符

按位移位运算符将位值向左或向右移位。左操作数指定要移位的,而右操作数指定该值中的位必须移位的位置数。两个操作数具有相同的优先级。

理解,比特如何从左向右移动,反之亦然。

a = 00010000
b = 2
a << b = 01000000 
a >> b = 00000100

a << b的情况下, 2 位00010000 中左移,另一个零加到另一端,也就是右边,因此该值变为 01000000

对于a >> b2 位从右侧移位,因此从右侧移除两个零,在左侧添加两个零,因此该值变为 00000100

请注意,移位不像旋转一样工作,这意味着移位的位不会在另一端添加。移位的位丢失

按位一补码(~)运算符

一的补码运算符会将操作数中的所有 1 更改为 0,并将所有 0 设置为 1。

例如,如果原始字节是 00101100 ,那么补码后就会变成 11010011

示例:按位左移和右移运算符

让我们看一个例子来理解 C 程序中的按位运算符。

#include <stdio.h>

int main() {

   int a = 0001000, b = 2, result;

   // <<
   result = a<<b;
   printf("a << b = %d \n",result);

   // >>
   result = a>>b;
   printf("a >> b = %d \n",result);

   return 0;

}

a<T3】b = 2048
a>T5】b = 128

运行代码→

赋值运算符

sssignation 运算符用于为变量赋值。例如,如果我们想要将值 10 赋给变量x,那么我们可以通过使用赋值运算符来实现,如:x = 10;这里,=(等于)运算符用于赋值。

在 C 语言中,=(等于)运算符是用于赋值的,然而它还有其他几个变体,如+=-=在一个语句中组合两个操作。

**您可以在下表中看到所有赋值运算符。

| 运算符 | 描述 |

例子

(ab是两个变量,其中 a=10,b=5)

|
| --- | --- | --- |
| = | 从右侧操作数向左侧操作数赋值 | a=ba取值 5 |
| += | 将右操作数加到左操作数,并将结果赋给左操作数 | a+=b,与a=a+b相同,a值变为 15 |
| -= | 从左操作数中减去右操作数,并将结果分配给左操作数 | a-=b,与a=a-b相同,a值变为 5 |
| *= | 将左操作数与右操作数相乘,并将结果赋给左操作数 | a*=b,与a=a*b相同,a值变为 50 |
| /= | 用右操作数除左操作数,并将结果分配给左操作数 | a/=b,与a=a/b相同,a的值变为 2 |
| %= | 使用两个操作数计算模数,并将结果分配给左操作数 | a%=b,与a=a%b相同,a的值变为 0 |

当我们将算术运算符与赋值运算符=组合在一起时,我们得到了所有算术运算符的简写形式

示例:使用赋值运算符

下面我们有一个代码示例,其中我们使用了所有不同形式的赋值运算符,从基本赋值开始。

#include <stdio.h>

int main() {

   int a = 10;

   // Assign
   int result = a;
   printf("result = %d \n",result);

   // += operator
   result += a;
   printf("result = %d \n",result);

   // -= operator
   result -= a;
   printf("result = %d \n",result);

   // *= operator
   result *= a;
   printf("result = %d \n",result);

   return 0;

}

结果= 10
结果= 20
结果= 10
结果= 100

运行代码→

c 三元运算符(?)

三元运算符,在 C 语言中也称为条件运算符,可用于 if-then-else 形式的语句。

使用三元运算符的基本语法是:

(Expression1)? Expression2 : Expression3;

以下是它的工作原理:

  • 语法中的问号?代表 if 部分。

  • 第一个表达式(表达式 1)返回,基于此决定是执行(表达式 2)还是(表达式 3)

  • 如果(表达式 1)返回,则执行(表达式 2)。

  • 如果(表达式 1)返回,则执行:右侧的表达式,即(表达式 3)。

示例:使用三元运算符

下面是一个代码示例,演示如何使用三元运算符。

#include <stdio.h>

int main() {

   int a = 20, b = 20, result;

   /* Using ternary operator
      - If a == b then store a+b in result
      - otherwise store a-b in result
   */
   result = (a==b)?(a+b):(a-b);

   printf("result = %d",result);

   return 0;

}

结果= 40

运行代码→

c 特殊运算符- &*sizeof等。

除了算术、关系、逻辑、赋值等。运算符,C 语言使用一些其他运算符,例如:

  1. sizeof运算符

  2. &运算符

  3. *运算符

  4. .(点)和->(箭头)操作器

  5. []运算符等。

sizeof查找任意实体(变量、数组等)的大小。),&运算符查找一个变量的地址等。您可以在下表中看到此类运算符的列表。

运算符 描述 例子
sizeof 返回实体的大小(以字节为单位),例如变量或数组等。 sizeof(x)将返回变量的大小x
& 返回变量的内存地址 &x将返回变量x的地址
* 表示指向对象的指针。*运算符返回存储在存储器地址的值。 m = &x(变量x的内存地址)*m将返回存储在内存地址m的值
.(点)运算符 用于访问 C 结构或 C 联合的单个元素。 如果emp是包含元素int age的结构,那么emp.age将返回年龄值。
->(箭头)操作符 用于使用指向结构或联合的指针来访问结构或联合元素。 如果p是指向emp结构的指针,那么我们可以使用p->age访问age元素
[]运算符 用于使用索引访问数组元素 如果arr是一个数组,那么我们可以使用arr[index]来访问它的值,其中index代表从零开始的数组索引

在本教程系列中,我们将继续学习*、点运算符、箭头运算符和[]运算符,现在让我们看看如何使用sizeof&运算符。

示例:使用sizeof&运算符

下面是一个代码示例,尝试使用运行代码按钮在实时代码编译器中运行。

#include <stdio.h>

int main() {

   int a = 20;
   char b = 'B';
   double c = 17349494.249324;

   // sizeof operator
   printf("Size of a is: %d \n", sizeof(a));
   printf("Size of b is: %d \n", sizeof(b));
   printf("Size of c is: %d \n", sizeof(c));

   // & operator
   printf("Memory address of a: %d \n", &a);

   return 0;

}

a 的大小为:4
b 的大小为:1
c 的大小为:8
a 的内存地址:1684270284

运行代码→


常见问题

下面是一些 C 运算符的常见问题。

Q1。C 语言中的运算符是什么?

运算符是 C 编译器已知的符号,用于对数据执行操作。运算符可用于直接对某些值( C 字面值)或对 C 变量执行运算。在 C 语言中,我们可以执行算术运算、逻辑和关系运算、按位运算等。对数据使用 C 运算符。

Q2。C 支持哪些不同类型的运算符?

C 语言支持以下类型的运算符:

  • 算术运算符

  • 关系运算符

  • 逻辑运算符

  • 按位运算符

  • 赋值运算符

  • 三元算子

  • 特殊操作符如sizeof&*.(点)操作符、->(箭头)操作符、[](方括号)操作符等。

Q3。*运算符在 C 中做什么?

C 语言中的*运算符是一元运算符,它返回位于地址的对象的值,该地址在*运算符之后指定。例如q = *m会将存储在内存地址m的值存储在q变量中,如果m包含内存地址的话。

*运算符也用于执行两个值的乘法,在这里它充当算术运算符

Q4。!=在 C 中是什么意思?

是不等于(!=)运算符的符号,用于检查两个值是否相等。它是一个关系运算符,它的相反运算符是一个等号(==)运算符,用于检查两个值或变量之间的相等性。

如果两个值不相等,那么我们将得到 1 作为比较的结果。

Q5。C 中的&*运算符是什么?

两者都是特殊类型的运算符,用于执行与内存相关的操作。&运算符用于获取变量的地址,*运算符是&运算符的补码,用于获取位于内存地址的对象的值。

Q6。%d 在 C 语言中做什么?

它是格式说明符,用于将格式化输出打印到控制台。在 C 语言中,与printf()功能( C 输入输出一起使用,向控制台显示整数值。打印float,C 提供%f,对于char我们用%c,对于double我们用%lf等。


结论:

在本教程中,我们详细学习了所有的 C 语言操作符,并通过大量的代码示例来查看所有的操作符。



C 语言中的决策

原文:https://www.studytonight.com/c/decision-making-in-c.php

决策是根据特定条件决定语句的执行顺序,或者重复一组语句,直到满足特定条件。C 语言通过支持以下语句来处理决策,

  • if声明
  • switch声明
  • 条件运算符语句(? :运算符)
  • goto声明

if语句进行决策

if语句可以根据测试条件的复杂程度以不同的形式实现。不同的形式是,

  1. 简单if语句
  2. if....else声明
  3. 嵌套if....else 语句
  4. 使用else if语句

简单if语句

简单if语句的一般形式是,

if(expression)
{
    statement inside;
}
    statement outside;

如果表达式返回真,则执行语句-内部,否则跳过语句-内部,只执行语句-外部

示例:

#include <stdio.h>

void main( )
{
    int x, y;
    x = 15;
    y = 13;
    if (x > y )
    {
        printf("x is greater than y");
    }
}

x 大于 y


if...else声明

简单if...else语句的一般形式是,

if(expression)
{
    statement block1;
}
else
{
    statement block2;
}

如果表达式为真,则执行语句-区块 1 ,否则跳过语句-区块 1 ,执行语句-区块 2

示例:

#include <stdio.h>

void main( )
{
    int x, y;
    x = 15;
    y = 18;
    if (x > y )
    {
        printf("x is greater than y");
    }
    else
    {
        printf("y is greater than x");
    }
}

y 大于 x


嵌套if....else语句

嵌套if...else语句的一般形式是,

if( expression )
{
    if( expression1 )
    {
        statement block1;
    }
    else 
    {
        statement block2;
    }
}
else
{
    statement block3;
}

如果表达式为假,则执行语句-块 3 ,否则继续执行并进入第一个if内部执行下一个if块的检查,其中如果表达式 1 为真,则执行语句-块 1 ,否则执行语句-块 2

示例:

#include <stdio.h>

void main( )
{
    int a, b, c;
    printf("Enter 3 numbers...");
    scanf("%d%d%d",&a, &b, &c);
    if(a > b)
    { 
        if(a > c)
        {
            printf("a is the greatest");
        }
        else 
        {
            printf("c is the greatest");
        }
    }
    else
    {
        if(b > c)
        {
            printf("b is the greatest");
        }
        else
        {
            printf("c is the greatest");
        }
    }
} 

else if梯子

else 的一般形式——如果梯子是,

if(expression1)
{
    statement block1;
}
else if(expression2) 
{
    statement block2;
}
else if(expression3 ) 
{
    statement block3;
}
else 
    default statement;

这个表达式是从(梯子的)顶部向下测试的。一旦发现一个条件,与之相关的语句就被执行。

示例:

 #include <stdio.h>

void main( )
{
    int a;
    printf("Enter a number...");
    scanf("%d", &a);
    if(a%5 == 0 && a%8 == 0)
    {
        printf("Divisible by both 5 and 8");
    }  
    else if(a%8 == 0)
    {
        printf("Divisible by 8");
    }
    else if(a%5 == 0)
    {
        printf("Divisible by 5");
    }
    else 
    {
        printf("Divisible by none");
    }
}

需要记住的要点

  1. In if statement, a single statement can be included without enclosing it into curly braces { ... }

    int a = 5;
    if(a > 4)
        printf("success");
    

    上面的情况不需要花括号,但是如果我们在if条件里面有一个以上的语句,那么我们必须把它们括在花括号里面。

  2. if条件的表达式中必须使用==进行比较,如果使用=,表达式将始终返回 true ,因为它执行赋值而不是比较。

  3. Other than 0(zero), all other values are considered as true.

    if(27)
        printf("hello");
    

    在上例中,将打印你好



C 语言中的switch语句

原文:https://www.studytonight.com/c/switch-statement-in-c.php

当你想解决多个选项类型的问题时,比如:菜单类程序,每个选项关联一个值,一次只需要选择一个,那么,使用switch语句。

Switch 语句是一个控制语句,它允许我们在众多给定的选项中只选择一个。switch中的表达式计算得出一个整数值,然后将其与不同情况下的值进行比较。它执行与大小写值匹配的代码块。如果没有匹配,则执行默认的块(如果存在)。switch语句的一般形式是,

switch(expression)
{
    case value-1:
    	block-1;
    	break;
    case value-2:
    	block-2;
    	break;
    case value-3:
    	block-3;
    	break;
    case value-4:
    	block-4;
   	    break;
    default:
   	    default-block;
    	break;
}

使用switch语句的规则

  1. 表达式(在 switch 关键字之后)必须产生一个整数值,即该表达式应该是一个整数或一个变量或一个计算结果为整数的表达式。
  2. 案例标签值必须唯一。
  3. 案例标签必须以冒号(:)结尾
  4. 下一行,在情况下语句之后,可以是任何有效的 C 语句。

需要记住的要点

  1. 我们不使用这些表达式来计算 switch case,它可能返回浮点值或字符串或字符。

  2. break statements are used to exit the switch block. It isn't necessary to use break after each block, but if you do not use it, then all the consecutive blocks of code will get executed after the matching block.

    int i = 1;
    switch(i)
    {
        case 1:    
            printf("A");        // No break
        case 2:
            printf("B");        // No break
        case 3:
            printf("C");
            break;
    }
    

    英国广播公司

    输出应该只有 A ,因为只有第一个案例匹配,但是由于在那个块之后没有break语句,接下来的块也被执行,直到它遇到一个break语句或者执行到达switch块的末尾。

  3. 默认案例,当上述案例都不符合switch表达式时执行。默认案例可以放在switch案例中的任何地方。即使我们不包括违约案例,switch的说法也行得通。

  4. 允许嵌套switch语句,这意味着您可以在另一个switch块中拥有switch语句。但是,应该避免嵌套的switch语句,因为它会使程序更加复杂,可读性更差。


switch语句示例

#include<stdio.h>
void main( )
{
    int a, b, c, choice;
    while(choice != 3)
    {
        /* Printing the available options */
        printf("\n 1\. Press 1 for addition");
        printf("\n 2\. Press 2 for subtraction");
        printf("\n Enter your choice");
        /* Taking users input */
        scanf("%d", &choice);

        switch(choice)
        {
            case 1:
                printf("Enter 2 numbers");
                scanf("%d%d", &a, &b);
                c = a + b;
                printf("%d", c);
                break;
            case 2:
                printf("Enter 2 numbers");
                scanf("%d%d", &a, &b);
                c = a - b;
                printf("%d", c);
                break;
            default:
                printf("you have passed a wrong key");
                printf("\n press any key to continue");
        }
    } 
} 

switchif的区别

  • [if](decision-making-in-c.php)语句可以评估float条件。switch语句无法评估float条件。
  • if语句可以求值关系运算符。switch语句不能计算关系运算符,即它们在switch语句中是不允许的。


C 语言中的循环

原文:https://www.studytonight.com/c/loops-in-c.php

在包括 C 语言在内的任何编程语言中,循环用于重复执行一组语句,直到满足特定条件。


它是如何工作的

下图描述了循环执行,

loopflow diagram in C

根据上图,如果测试条件为真,则执行循环,如果为假,则执行脱离循环。循环成功执行后,再次从循环条目开始执行,并再次检查测试条件,并继续重复。

要执行的语句序列被保存在花括号{ }中,花括号被称为循环体。每次执行循环体后,验证条件,如果发现为,则再次执行循环体。当条件检查返回时,不执行循环体,执行脱离循环。


循环的类型

C 语言中有 3 种类型的循环,即:

  1. while循环
  2. for循环
  3. do while循环

while循环

while循环可以作为入口控制循环来处理。它分三步完成。

  • 变量初始化。(例如int x = 0;)
  • 条件(例如while(x <= 10))
  • 可变增量或减量(x++x--x = x + 2

语法:

variable initialization;
while(condition)
{
    statements;
    variable increment or decrement; 
}

示例:打印前 10 个自然数的程序

#include<stdio.h>

void main( )
{
    int x;
    x = 1;
    while(x <= 10)
    {
        printf("%d\t", x);
        /* below statement means, do x = x+1, increment x by 1*/
        x++;
    }
}

1 2 3 4 5 6 7 8 9 10


for循环

for循环用于重复执行一组语句,直到满足特定条件。我们可以说它是一个开环。。一般格式是,

for(initialization; condition; increment/decrement)
{
    statement-block;
}

for循环中,我们正好有两个分号,一个在初始化之后,第二个在条件之后。在这个循环中,我们可以有多个初始化或增量/减量,用逗号运算符分隔。但是它只能有一个条件

for循环执行如下:

  1. 它首先评估初始化代码。
  2. 然后检查条件表达式。
  3. 如果为,则执行 for 循环体。
  4. 然后,它评估增量/减量条件,并再次从步骤 2 开始。
  5. 当条件表达式变为时,退出循环。

示例:打印前 10 个自然数的程序

#include<stdio.h>

void main( )
{
    int x;
    for(x = 1; x <= 10; x++)
    {
        printf("%d\t", x);
    }
}

1 2 3 4 5 6 7 8 9 10


嵌套for循环

我们也可以有嵌套的for循环,即一个for循环在另一个for循环内。基本语法是,

for(initialization; condition; increment/decrement)
{
    for(initialization; condition; increment/decrement)
    {
        statement ;
    }
}

示例:打印半个数字金字塔的程序

#include<stdio.h>

void main( )
{
    int i, j;
    /* first for loop */
    for(i = 1; i < 5; i++)
    {
        printf("\n");
        /* second for loop inside the first */
        for(j = i; j > 0; j--)
        {
            printf("%d", j);
        }
    }
}

1 21 321 4321 54321


do while循环

在某些情况下,有必要在测试条件之前执行循环体。这种情况可以借助do-while循环来处理。do语句首先评估循环体,最后使用while语句检查条件。这意味着循环体将至少执行一次,即使while内的起始条件被初始化为。一般语法是,

do
{
    .....
    .....
}
while(condition)

示例:打印前 10 个 5 的倍数的程序。

#include<stdio.h>

void main()
{
    int a, i;
    a = 5;
    i = 1;
    do
    {
        printf("%d\t", a*i);
        i++;
    } 
    while(i <= 10);
}

5 10 15 20 25 30 35 40 45 50


跳出循环

有时,在执行循环时,一旦某个条件变为,就需要跳过循环的一部分或离开循环。这就是所谓的跳出循环。

1)break语句

当在循环中遇到break语句时,循环立即退出,程序继续执行紧接着循环的语句。

break statement in loops in c language

2)继续语句

它使控件直接进入测试条件,然后继续循环过程。遇到continue时,光标离开当前循环,从下一个循环开始。

continue statement in loops in c language



C 语言中的数组

原文:https://www.studytonight.com/c/arrays-in-c.php

在 C 语言中,arrays被引用为结构化的数据类型。数组被定义为存储在连续存储单元中的同质数据的有限有序集合。

这里的话,

  • 有限 意味着数据范围必须定义。
  • 有序 意味着数据必须存储在连续的内存地址中。
  • 同质 意味着数据必须是相似的数据类型。

使用数组的例子,

  • 要存储员工或学生姓名列表,
  • 存储学生的分数,
  • 或者存储数字或字符列表等。

由于数组提供了一种简单的表示数据的方式,因此它被归入 C 语言中的数据结构中。C 语言中的其他数据结构有结构列表队列等。数组不仅可以用来表示简单的数据列表,还可以用来表示二维或三维的数据表。


声明数组

像任何其他变量一样,数组必须在使用前声明。数组声明的一般形式是,

data-type variable-name[size];

/* Example of array declaration */

int arr[10];

array declaraction in c

这里int是数据类型,arr是数组的名称,10 是数组的大小。意思是数组arr只能包含 10 个int类型的元素。

数组的索引0开始到大小-1 ,即arr数组的第一个元素将存储在arr[0]地址,最后一个元素将占用arr[9]


数组的初始化

声明数组后,必须对其进行初始化。否则将包含垃圾值(任意随机值)。数组可以在编译时运行时初始化。

编译时数组初始化

数组元素的编译时初始化与普通变量初始化相同。数组初始化的一般形式是,

data-type array-name[size] = { list of values };

/* Here are a few examples */
int marks[4]={ 67, 87, 56, 77 };    // integer array initialization

float area[5]={ 23.4, 6.8, 5.5 };   // float array initialization

int marks[4]={ 67, 87, 56, 77, 59 };    // Compile time error

需要记住的一件重要的事情是,当你给出的初始值设定项(数组元素)比声明的数组大时,编译器会给出一个错误。

#include<stdio.h>

void main()
{
    int i;
    int arr[] = {2, 3, 4};      // Compile time array initialization
    for(i = 0 ; i < 3 ; i++) 
    {
        printf("%d\t",arr[i]);
    }
}

2 3 4

运行时数组初始化

也可以在运行时使用scanf()函数初始化数组。这种方法通常用于初始化大型数组,或者用用户指定的值初始化数组。例如,

#include<stdio.h>

void main()
{
    int arr[4];
    int i, j;
    printf("Enter array element");
    for(i = 0; i < 4; i++)
    {
        scanf("%d", &arr[i]);    //Run time array initialization
    }
    for(j = 0; j < 4; j++)
    {
        printf("%d\n", arr[j]);
    }
}

二维数组

C 语言也支持多维数组。多维数组最简单的形式是二维数组。行和列的索引都从0开始。

二维数组声明如下:

data-type array-name[row-size][column-size] 

/* Example */
int a[3][4];

two dimensional array in c

数组也可以一起声明和初始化。例如,

int arr[][3] = {
    {0,0,0},
    {1,1,1}
};

注意:在上面的示例中,我们没有为数组分配任何行值。这意味着我们可以初始化任意数量的行。但是,我们必须始终指定列数,否则会产生编译时错误。这里,创建了一个2*3多维矩阵。

二维数组的运行时初始化

#include<stdio.h>

void main()
{
    int arr[3][4];
    int i, j, k;
    printf("Enter array element");
    for(i = 0; i < 3;i++)
    {
        for(j = 0; j < 4; j++)
        {
            scanf("%d", &arr[i][j]);
        }
    }
    for(i = 0; i < 3; i++)
    {
        for(j = 0; j < 4; j++)
        {
            printf("%d", arr[i][j]);
        }
    }
}


字符串和字符数组

原文:https://www.studytonight.com/c/string-and-character-array.php

字符串是被视为单个数据项的字符序列,以空字符'\0'结束。记住 C 语言不支持字符串作为数据类型。A 字符串实际上是 C 语言中的一维字符数组。这些通常用于创建有意义和可读的程序。

如果不知道 C 语言中的数组是什么意思,可以查看 C 数组教程,了解 C 语言中的数组。在继续之前,请查看以下文章:

  • C 函数调用

  • C 变量

  • C 数据类型

  • C 语法规则

例如:字符串“home”包含 5 个字符,包括编译器在字符串末尾自动添加的'\0'字符。

string in C

声明和初始化字符串变量:

// valid
char name[13] = "StudyTonight";        
char name[10] = {'c','o','d','e','\0'};      

// Illegal
char ch[3] = "hello";    
char str[4];
str = "hello"; 

字符串输入和输出:

  • %s 格式说明符读取从终端输入的字符串。

  • 但是 scanf() 函数会在遇到的第一个空格处终止输入。

  • 编辑设置转换代码%[..】可用于读取包含多种字符的行,包括空格。

  • gets()功能也可以用来读取带有空格的字符串

char str[20];
printf("Enter a string");
scanf("%[^\n]", &str); 
printf("%s", str); 
char text[20];
gets(text);
printf("%s", text);

字符串处理函数:

C 语言支持大量的字符串处理功能,可以用来执行许多字符串操作。这些功能封装在 string.h 库中。因此,您必须在程序中包含 string.h 头文件才能使用这些功能。

以下是最常用的字符串处理函数。

| 方法 | 描述 |
| strcat() | 它用于连接(组合)两个字符串 |
| strlen() | 它用于显示字符串的长度 |
| strrev() | 它用于显示字符串的反转 |
| strcpy() | 将一个字符串复制到另一个字符串中 |
| strcmp() | 它用于比较两个字符串 |

strcat()功能在 C:

strcat() function in C

语法:

strcat("hello", "world");

strcat()将把字符串“世界”添加到“你好”即 ouput = helloworld。

strlen()strcmp()功能:

strlen()将返回传递给它的字符串的长度,strcmp()将返回两个字符串的第一个不匹配字符之间的 ASCII 差异。

 int j = strlen("studytonight");
 int i=strcmp("study ", "tonight");
printf("%d %d",j,i);

12 -1

strcpy()功能:

它将第二个字符串参数复制到第一个字符串参数。

srtcpy() function in C

strcpy()功能示例:

#include<stdio.h>
#include<string.h>

int main()
{
    char s1[50], s2[50];

    strcpy(s1, "StudyTonight");     
    strcpy(s2, s1);     

    printf("%s\n", s2);

    return(0);
}

今晚学习

strrev()功能:

它用于反转给定的字符串表达式。

strrev() function in C

strrev()的代码片段:

#include <stdio.h>

int main()
{ 
    char s1[50]; 

    printf("Enter your string: "); 
    gets(s1);  
    printf("\nYour reverse string is: %s",strrev(s1)); 
    return(0); 
}

输入你的字符串:今晚学习
你的反串是:thginotyduts

相关教程:

  • C 阵

  • C 功能

  • C 指针

  • 碳结构



C 语言中的存储类

原文:https://www.studytonight.com/c/storage-classes-in-c.php

在 C 语言中,每个变量都有一个存储类,它决定了以下事情:

  • 作用域即程序中变量值可用的地方。
  • 缺省初始值也就是说,如果我们没有明确初始化那个变量,它的缺省初始值会是什么。
  • 该变量的寿命,即该变量将存在多长时间。

以下存储类最常用于 C 编程,

  1. 自动变量
  2. 外部变量
  3. 静态变量
  4. 注册变量

自动变量:auto

作用域:auto存储类定义的变量对于定义它们的功能块是本地的。

默认初始值:任意随机值,即垃圾值。

生存期:直到定义变量的函数/方法块结束。

在没有任何存储类规范的函数内部声明的变量,默认情况下是一个自动变量。它们在函数被调用时被创建,并在函数执行完成时被自动销毁。自动变量也可以称为局部变量,因为它们是函数的局部变量。默认情况下,编译器会为它们分配垃圾值

#include<stdio.h>

void main()
{
    int detail;
    // or 
    auto int details;    //Both are same
}

外部或全局变量

范围:全局,即程序中的任何地方。这些变量不受任何函数的约束,它们无处不在。

默认初始值: 0(零)。

生存期:直到程序没有完成执行,可以访问全局变量。

在任何函数之外声明的变量是全局变量。全局变量在整个程序执行过程中保持可用。默认情况下,全局变量的初始值为 0(零)。关于全局变量要记住的一件重要的事情是,它们的值可以被程序中的任何函数改变。

#include<stdio.h>

int number;     // global variable

void main()
{
    number = 10;
    printf("I am in main function. My value is %d\n", number);
    fun1();     //function calling, discussed in next topic
    fun2();     //function calling, discussed in next topic
}

/* This is function 1 */
fun1()
{
    number = 20;
    printf("I am in function fun1\. My value is %d", number);
}
/* This is function 1 */
fun2()
{
    printf("\nI am in function fun2\. My value is %d", number);
}

我在主功能。我的值是 10,我在函数 fun1 中。我的值是 20,我在函数 fun2 中。我的值是 20

这里,全局变量number对所有三个函数都可用,因此,如果一个函数改变了变量的值,它在每个函数中都会改变。

注意:对于程序中的所有变量,将存储类声明为全局或外部会浪费大量的内存空间,因为这些变量在程序结束之前都是有生命周期的。因此,直到程序结束之前都不需要的变量仍然会占用内存,从而浪费内存。


extern关键字

extern关键字与一个变量一起使用,以通知编译器该变量在其他地方声明。extern声明不为变量分配存储。

extern keyword in c

不使用 extern 时出现问题

int main()
{
    a = 10;     //Error: cannot find definition of variable 'a'
    printf("%d", a);    
}

在同一文件中使用 extern 的示例

int main()
{
    extern int x;   //informs the compiler that it is defined somewhere else
    x = 10;      
    printf("%d", x);    
}
int x;      //Global variable x

静态变量

范围:定义变量的块的本地

默认初始值: 0(零)。

生存期:直到整个程序没有执行完。

一个static变量告诉编译器将变量保存/保存到程序结束。static变量只初始化一次,并一直存在到程序结束,而不是每次进入和退出范围时都创建和销毁变量。static变量可以是内部变量,也可以是外部变量,具体取决于申报地点。内部静态变量的范围保留在定义它的函数中。外部静态变量仍然被限制在声明它们的文件范围内。

编译器将它们指定为 0(零)默认值。

#include<stdio.h>

void test();    //Function declaration (discussed in next topic)

int main()
{
    test();
    test();
    test();
}

void test()
{
    static int a = 0;       //a static variable
    a = a + 1;
    printf("%d\t",a);
}

1 2 3


寄存器变量

作用域:对声明它的函数是局部的。

默认初始值:任意随机值,即垃圾值

寿命:直到定义变量的函数/方法块结束。

寄存器变量通知编译器将变量存储在 CPU 寄存器中,而不是内存中。寄存器变量比普通变量具有更快的可访问性。通常,经常使用的变量保存在寄存器中。但是只有少数变量可以放在寄存器中。寄存器存储类的一个应用是使用循环,在很短的时间内,变量在程序中被多次使用。

注:我们永远无法得到这类变量的地址。

语法:

register int number;

注意:即使我们已经将变量number的存储类声明为寄存器,我们也不能肯定地说变量的值会存储在寄存器中。这是因为中央处理器中寄存器的数量是有限的。此外,中央处理器寄存器意味着要做很多重要的工作。因此,有时他们可能不自由。在这种情况下,变量的工作方式就好像它的存储类是auto


应该使用哪个存储类别以及何时使用

为了提高程序的执行速度并谨慎使用变量占用的内存空间,在使用存储类时应记住以下几点:

  • 只有当我们希望变量的值在每次使用不同的函数调用时保持不变时,我们才应该使用static存储类。
  • 我们应该只对那些经常在程序中使用的变量使用register存储类。中央处理器寄存器是有限的,因此应该谨慎使用。
  • 我们应该只对那些被程序中几乎所有函数使用的变量使用外部或全局存储类。
  • 如果我们没有任何上述存储类的目的,那么我们应该使用自动存储类。


函数

C 语言中的函数

原文:https://www.studytonight.com/c/user-defined-functions-in-c.php

函数是执行特定任务的代码块。

在许多情况下,我们可能需要在一个程序中多次编写同一行代码。这可能会导致不必要的代码重复、bug,甚至对程序员来说变得无聊。因此,C 语言提供了一种方法,在这种方法中,您可以以函数的形式声明和定义一组语句,并且可以在任何需要的时候调用和使用它。

用户定义的这些功能也称为用户自定义功能

c 函数可以分为两类,

  1. 库函数
  2. 用户自定义功能

types of functions in C

库函数是已经在 C 库中定义的函数,例如printf()scanf()strcat()等。您只需要包含适当的头文件来使用这些功能。这些已经在 C 库中声明和定义了。

另一方面,用户自定义函数是用户在编写程序时定义的那些函数。这些功能是为了代码的可重用性和节省时间和空间。


使用函数的好处

  1. 它为你的程序结构提供了模块化。
  2. 它使您的代码可重用。您只需要通过函数的名称来调用它,就可以在任何需要的地方使用它。
  3. 对于有数千行代码的大型程序,如果使用函数,调试和编辑会变得更容易。
  4. 它使程序更易读和容易理解。

函数声明

函数声明的一般语法是,

returntype functionName(type1 parameter1, type2 parameter2,...);

像任何变量或数组一样,函数在使用前也必须声明。函数声明通知编译器函数名、接受的参数及其返回类型。函数的实际主体可以单独定义。也叫功能原型。函数声明由 4 部分组成。

  • 返回类型
  • 函数名
  • 参数列表
  • 终止分号

返回类型

当一个函数被声明执行某种计算或任何操作,并期望在最后提供某种结果时,在这种情况下,在函数体的末尾添加一个return语句。返回类型指定函数期望返回到调用该函数的程序的值类型(intfloatchardouble)。

注意:如果你的函数没有返回值,返回类型为void


函数名

函数名是一个标识符,它指定了函数的名称。函数名是任何有效的 C 标识符,因此必须遵循与 C 语言中其他变量相同的命名规则。


参数列表

参数列表声明了调用函数时所需的参数类型和数量。此外,当调用函数时,参数列表中的参数接收参数值。它们通常被称为形式参数


举个例子

让我们编写一个简单的程序,带有一个main()函数,和一个用户定义的函数来相乘两个数字,这将从main()函数调用。

#include<stdio.h>

int multiply(int a, int b);     // function declaration

int main() 
{
    int i, j, result;
    printf("Please enter 2 numbers you want to multiply...");
    scanf("%d%d", &i, &j);

    result = multiply(i, j);        // function call
    printf("The result of muliplication is: %d", result);

    return 0;
}

int multiply(int a, int b)
{
    return (a*b);       // function defintion, this can be done in one line
}

函数定义语法

就像上面的例子一样,函数定义的一般语法是,

returntype functionName(type1 parameter1, type2 parameter2,...)
{
    // function body goes here
}

第一行返回类型 功能名称(类型 1 参数 1,类型 2 参数 2,...)称为函数头,花括号内的语句称为函数体

注意:定义函数时,函数头括号后没有分号(;),不像声明函数或调用函数时。

功能体

函数体包含执行所需任务所需的声明和语句(算法)。正文包含在花括号{ ... }内,由三部分组成。

  • 局部变量声明(如果需要)。
  • 功能语句执行功能内部的任务。
  • 一个 return 语句返回函数求值的结果(如果返回类型为void,则不需要 return 语句)。

调用函数

当一个函数被调用时,程序的控制权转移到该函数。

functionName(argument1, argument2,...);

在上例中,main()函数内部的语句multiply(i, j);是函数调用。


向函数传递参数

参数是在函数调用期间指定的值,在定义函数时为其声明形式参数。

passing arguments to functions in C

可以有一个带有参数但没有返回类型的函数。如果函数接受参数,它也必须返回一个结果,这不是必须的。

Passing argument to function in C

在声明函数时,我们声明了两个类型为int的参数ab。因此,在调用该函数时,我们需要传递两个参数,否则我们会得到编译错误。传递的两个参数应该在函数定义中接收,这意味着函数定义中的函数头应该有两个参数来保存参数值。这些接收到的参数也被称为形式参数。声明、调用和定义函数时变量的名称可以不同。


从函数返回值

函数可能返回结果,也可能不返回结果。但是如果是这样,我们必须使用return语句来输出结果。return语句也结束函数执行,因此它必须是任何函数的最后一条语句。如果在return语句之后写任何语句,都不会被执行。

Return statement in C functions

使用return语句返回的值的数据类型应该与函数声明和定义中提到的返回类型相同。如果其中任何一个不匹配,您将得到编译错误。

在下一个教程中,我们将学习 C 语言中不同类型的用户定义函数,以及递归中使用的函数嵌套概念。



C 语言中用户定义函数的类型

原文:https://www.studytonight.com/c/type-of-functions-and-recursion.php

用户自定义的功能可以有 4 种不同的类型,它们是:

  1. 没有参数和返回值的函数
  2. 没有参数和返回值的函数
  3. 带参数且无返回值的函数
  4. 带有参数和返回值的函数

下面,我们将讨论所有这些类型,以及程序示例。


没有参数和返回值的函数

这些功能可以用来显示信息,也可以完全依赖于用户输入。

下面是一个函数的例子,它从用户那里得到 2 个数字作为输入,并显示哪个数字更大。

#include<stdio.h>

void greatNum();       // function declaration

int main()
{
    greatNum();        // function call
    return 0;
}

void greatNum()        // function definition
{
    int i, j;
    printf("Enter 2 numbers that you want to compare...");
    scanf("%d%d", &i, &j);
    if(i > j) {
        printf("The greater number is: %d", i);
    }
    else {
        printf("The greater number is: %d", j);
    }
}

没有参数和返回值的函数

我们修改了上面的例子,使函数greatNum()返回两个输入数字中较大的数字。

#include<stdio.h>

int greatNum();       // function declaration

int main()
{
    int result;
    result = greatNum();        // function call
    printf("The greater number is: %d", result);
    return 0;
}

int greatNum()        // function definition
{
    int i, j, greaterNum;
    printf("Enter 2 numbers that you want to compare...");
    scanf("%d%d", &i, &j);
    if(i > j) {
        greaterNum = i;
    }
    else {
        greaterNum = j;
    }
    // returning the result
    return greaterNum;
}

带参数且无返回值的函数

我们一次又一次地使用同一个函数作为例子,来证明解决一个问题可以有许多不同的方法。

这一次,我们修改了上面的例子,让函数greatNum()取两个int值作为参数,但是它不会返回任何东西。

#include<stdio.h>

void greatNum(int a, int b);       // function declaration

int main()
{
    int i, j;
    printf("Enter 2 numbers that you want to compare...");
    scanf("%d%d", &i, &j);
    greatNum(i, j);        // function call
    return 0;
}

void greatNum(int x, int y)        // function definition
{
    if(x > y) {
        printf("The greater number is: %d", x);
    }
    else {
        printf("The greater number is: %d", y);
    }
}

带有参数和返回值的函数

这是最好的类型,因为这使得函数完全独立于输入和输出,并且只有逻辑被定义在函数体内部。

#include<stdio.h>

int greatNum(int a, int b);       // function declaration

int main()
{
    int i, j, result;
    printf("Enter 2 numbers that you want to compare...");
    scanf("%d%d", &i, &j);
    result = greatNum(i, j); // function call
    printf("The greater number is: %d", result);
    return 0;
}

int greatNum(int x, int y)        // function definition
{
    if(x > y) {
        return x;
    }
    else {
        return y;
    }
}

函数的嵌套

C 语言也允许函数嵌套,即在另一个函数体内使用/调用一个函数。我们在使用嵌套函数时必须小心,因为它可能会导致无限嵌套。

 function1()
{
    // function1 body here

    function2();

    // function1 body here
}

如果 function2()内部也有对 function1()的调用,那么在这种情况下,它将导致无限嵌套。他们会一直互相呼叫,程序永远不会终止。

不能够理解?让我们考虑一下在main()函数内部,函数 1()被调用,它的执行开始,然后在函数 1()内部,我们调用函数 2(),所以程序的控制将转到函数 2()。但是由于 function2()的主体中也有对 function1()的调用,所以它将调用 function1(),而 function 1()将再次调用 function2(),并且这将持续无限次,直到您强制退出程序执行。


什么是递归?

递归是嵌套函数的一种特殊方式,函数在其中调用自己。我们必须在函数中有一定的条件才能打破递归,否则递归会发生无限次。

function1()
{   
    // function1 body
    function1();
    // function1 body
}

示例:使用递归对数字进行阶乘

#include<stdio.h>

int factorial(int x);       //declaring the function

void main()
{
    int a, b;

    printf("Enter a number...");
    scanf("%d", &a);
    b = factorial(a);       //calling the function named factorial
    printf("%d", b);
}

int factorial(int x) //defining the function
{
    int r = 1;
    if(x == 1) 
        return 1;
    else 
        r = x*factorial(x-1);       //recursion, since the function calls itself

    return r;
}

同样,递归在 C 语言中还有更多的应用。转到程序部分,了解更多使用递归的程序。

既然我们已经了解了数据结构中的栈,您也可以查看以下主题:

  • 函数调用类型
  • 将数组传递给函数


C 语言中函数调用的类型

原文:https://www.studytonight.com/c/types-of-function-calls.php

函数都是用名字来称呼的,我们都知道,那这个教程是为了什么呢?如果函数没有任何参数,那么要调用一个函数,你可以直接使用它的名字。但是对于带参数的函数,根据我们如何指定参数,我们可以用两种不同的方式调用函数,这两种方式是:

  1. 按值调用
  2. 引用调用

按值调用

通过值调用函数意味着,我们将存储或复制的参数值传递到函数的形式参数中。因此,原始值不变,只有函数内部的参数发生变化。

#include<stdio.h>

void calc(int x);

int main()
{
    int x = 10;
    calc(x);
    // this will print the value of 'x'
    printf("\nvalue of x in main is %d", x);
    return 0;
}

void calc(int x)
{
    // changing the value of 'x'
    x = x + 10 ;
    printf("value of x in calc function is %d ", x);
}

计算函数中 x 的值是 20,主函数中 x 的值是 10

在这种情况下,实际的变量 x不变。这是因为我们是通过值传递参数的,因此x的副本被传递给函数,函数在执行过程中会更新,当函数结束(超出范围)时,函数中复制的值会被破坏。因此main()函数中的变量x从未改变,因此仍然保持10的值。

但是我们可以改变这个程序,让函数修改原来的x变量,方法是让函数calc()返回值,并将该值存储在 x 中。

#include<stdio.h>

int calc(int x);

int main()
{
    int x = 10;
    x = calc(x);
    printf("value of x is %d", x);
    return 0;
}

int calc(int x)
{
    x = x + 10 ;
    return x;
}

x 的值是 20


引用调用

在按引用调用中,我们将变量的地址(引用)作为参数传递给任何函数。当我们将任何变量的地址作为参数传递时,函数将可以访问我们的变量,因为它现在知道变量存储在哪里,因此可以轻松地更新它的值。

在这种情况下,形式参数可以作为一个引用或一个 指针 (不用担心指针,我们很快就会知道),在这两种情况下,它们都会改变原始变量的值。

#include<stdio.h>

void calc(int *p);      // functin taking pointer as argument

int main()
{
    int x = 10;
    calc(&x);       // passing address of 'x' as argument
    printf("value of x is %d", x);
    return(0);
}

void calc(int *p)       //receiving the address in a reference pointer variable
{
    /*
        changing the value directly that is 
        stored at the address passed
    */
    *p = *p + 10; 
}

x 的值是 20

注意:如果你没有任何关于指针的先验知识,一定要先学习指针。或者,一旦你了解了指针,就复习一下这个话题,然后再回来修改。



如何用 C 语言将数组传递给函数

原文:https://www.studytonight.com/c/array-in-function-in-c.php

每当我们需要将一个元素列表作为参数传递给 C 语言中的任何函数时,最好使用array来实现。但是我们如何将数组作为参数传递给函数呢?让我们看看它是如何完成的。


用数组作为参数声明函数

有两种可能的方法,一种是使用按值调用,另一种是使用按引用调用。

  1. 我们可以有一个数组作为参数。

    int sum (int arr[]);
    
  2. Or, we can have a pointers in the parameter list, to hold the base address of our array.

    int sum (int* ptr);
    

    我们将在稍后研究指针时详细研究第二种方法。


从函数返回数组

我们不从函数中返回数组,而是返回一个指针,该指针保存要返回的数组的基址。但是我们必须确保函数结束后数组存在,即数组不是函数的本地数组。

int* sum (int x[])
{
    // statements
    return x ;
}

我们将在研究带数组的指针时讨论这个问题。


将数组作为参数传递给函数

现在让我们看几个例子,其中我们将把单个数组元素作为参数传递给函数,一维数组传递给函数,多维数组传递给函数。


将单个数组元素传递给函数

让我们编写一个非常简单的程序,在这里我们将在我们的main()函数中声明并定义一个整数数组,并将数组元素之一传递给一个函数,该函数将只打印元素的值。

#include<stdio.h>

void giveMeArray(int a);

int main()
{
    int myArray[] = { 2, 3, 4 };
    giveMeArray(myArray[2]);        //Passing array element myArray[2] only.
    return 0;
}

void giveMeArray(int a)
{
    printf("%d", a);
}

four


将完整的一维数组传递给函数

为了理解这是如何实现的,让我们编写一个函数来找出数组中所有元素的平均值并打印出来。

我们将只发送数组的名称作为参数,它只不过是数组起始元素的地址,或者我们可以说是起始内存地址。

#include<stdio.h>

float findAverage(int marks[]);

int main()
{
    float avg;
    int marks[] = {99, 90, 96, 93, 95};
    avg = findAverage(marks);       // name of the array is passed as argument.
    printf("Average marks = %.1f", avg);
    return 0;
}

float findAverage(int marks[])
{
    int i, sum = 0;
    float avg;
    for (i = 0; i <= 4; i++) {
        sum += marks[i];
    }
    avg = (sum / 5);
    return avg;
}

Ninety-four point six


将多维数组传递给函数

这里,我们将只传递数组的名称作为参数。

#include<stdio.h>

void displayArray(int arr[3][3]);

int main()
{
    int arr[3][3], i, j;
    printf("Please enter 9 numbers for the array: \n");
    for (i = 0; i < 3; ++i)
    {
        for (j = 0; j < 3; ++j)
        {    
            scanf("%d", &arr[i][j]);
        }
    }
    // passing the array as argument
    displayArray(arr);
    return 0;
}

void displayArray(int arr[3][3])
{
    int i, j;
    printf("The complete array is: \n");
    for (i = 0; i < 3; ++i)
    {
        // getting cursor to new line
        printf("\n");
        for (j = 0; j < 3; ++j)
        {       
            // \t is used to provide tab space
            printf("%d\t", arr[i][j]);
        }
    }
}

请为数组输入 9 个数字:1 2 3 4 5 6 7 8 9 完整的数组是:1 2 3 4 5 6 7 8 9



结构

结构

原文:https://www.studytonight.com/c/structures-in-c.php

结构是 C 语言中用户定义的数据类型,它允许我们将不同类型的数据组合在一起。结构有助于构造更有意义的复杂数据类型。它有点类似于数组,但是数组只保存相似类型的数据。但是另一方面,结构可以存储任何类型的数据,这更实用更有用。

比如:如果我要写一个程序来存储 Student 信息,里面会有 Student 的名字、年龄、分支、永久地址、父亲的名字等等,里面包含了字符串值、整数值等等,这个问题怎么用数组呢,我会要求一些可以把不同类型的数据放在一起的东西。

在结构上,数据以记录的形式存储。


定义结构

struct关键字用于定义结构。struct定义一个新的数据类型,它是主数据类型和派生数据类型的集合。

语法:

struct [structure_tag]
{
    //member variable 1
    //member variable 2
    //member variable 3
    ...
}[structure_variables];

正如你在上面的语法中看到的,我们从struct关键字开始,然后它可以选择为你的结构提供一个名称,我们建议你给它一个名称,然后在花括号里面,我们必须提到所有的成员变量,这些变量只不过是不同类型的普通 C 语言变量,比如intfloatarray等。

在结束大括号之后,我们可以指定一个或多个结构变量,这也是可选的。

注意:结构类型声明中的右花括号后面必须跟一个分号(;)。

结构示例

struct Student
{
    char name[25];
    int age;
    char branch[10];
    // F for female and M for male
    char gender;
};

这里struct Student声明了一个保存学生详细信息的结构,该结构由 4 个数据字段组成,即nameagebranchgender。这些字段被称为结构元素或成员

每个成员可以有不同的数据类型,比如在这个例子中,name是一个char类型的数组,ageint类型的数组等等。学生是结构的名称,被称为结构标签


声明结构变量

可以声明结构的变量,可以与结构定义一起声明,也可以在结构定义之后声明。结构 变量的声明类似于任何其他数据类型的任何普通变量的声明。结构变量可以通过以下两种方式声明:


1)分别声明结构变量

struct Student
{
    char name[25];
    int age;
    char branch[10];
    //F for female and M for male
    char gender;
};

struct Student S1, S2;      //declaring variables of struct Student

2)用结构定义声明结构变量

struct **Student**
{
    char name[25];
    int age;
    char branch[10];
    //F for female and M for male
    char gender;
}S1, S2;

这里S1S2是结构的变量Student。然而,这种方法不太推荐。


访问结构成员

可以通过多种方式访问结构成员并为其赋值。没有结构,结构成员就没有单独的意义。为了给任何结构成员赋值,必须使用点.运算符(也称为句点成员访问运算符)将成员名称与结构变量链接起来。

例如:

#include<stdio.h>
#include<string.h>

struct Student
{
    char name[25];
    int age;
    char branch[10];
    //F for female and M for male
    char gender;
};

int main()
{
    struct Student s1;

    /*
        s1 is a variable of Student type and 
        age is a member of Student
    */
    s1.age = 18;
    /*
        using string function to add name
    */
    strcpy(s1.name, "Viraaj");
    /*
        displaying the stored values
    */
    printf("Name of Student 1: %s\n", s1.name);
    printf("Age of Student 1: %d\n", s1.age);

    return 0;
}

学生 1 的姓名:维拉杰学生 1 的年龄:18 岁

我们也可以使用scanf()通过终端给结构成员赋值。

scanf(" %s ", s1.name);
scanf(" %d ", &s1.age);

结构初始化

像任何其他数据类型的变量一样,结构变量也可以在编译时初始化。

struct **Patient**
{
    float height;
    int weight;  
    int age; 
};

struct Patient p1 = { 180.75 , 73, 23 };    //initialization

或者,

struct Patient p1;
p1.height = 180.75;     //initialization of each member separately
p1.weight = 73;
p1.age = 23;

结构数组

我们也可以声明一个结构变量的数组。其中数组的每个元素将代表一个结构变量。示例: struct employee emp[5];

下面的程序定义了一个大小为 5 的数组emp。数组emp的每个元素都属于Employee类型。

#include<stdio.h>

struct Employee
{
    char ename[10];
    int sal;
};

struct Employee emp[5];
int i, j;
void ask()
{
    for(i = 0; i < 3; i++)
    {
        printf("\nEnter %dst Employee record:\n", i+1);
        printf("\nEmployee name:\t");
        scanf("%s", emp[i].ename);
        printf("\nEnter Salary:\t");
        scanf("%d", &emp[i].sal);
    }
    printf("\nDisplaying Employee record:\n");
    for(i = 0; i < 3; i++)
    {
        printf("\nEmployee name is %s", emp[i].ename);
        printf("\nSlary is %d", emp[i].sal);
    }
}
void main()
{
    ask();
}

嵌套结构

C 语言也允许嵌套结构。嵌套结构是指一个结构有另一个结构作为成员变量。

示例:

struct Student
{
    char[30] name;
    int age;
    /* here Address is a structure */
    struct Address
    {
        char[50] locality;
        char[50] city;
        int pincode;		
    }addr;
};

作为函数参数的结构

我们可以将结构作为函数参数传递,就像我们将任何其他变量或数组作为函数参数传递一样。

示例:

#include<stdio.h>

struct Student
{
    char name[10];
    int roll;
};

void show(struct Student st);

void main()
{
    struct Student std;
    printf("\nEnter Student record:\n");
    printf("\nStudent name:\t");
    scanf("%s", std.name);
    printf("\nEnter Student rollno.:\t");
    scanf("%d", &std.roll);
    show(std);
}

void show(struct Student st)
{
    printf("\nstudent name is %s", st.name);
    printf("\nroll is %d", st.roll);
}


C 语言中的typedef

原文:https://www.studytonight.com/c/typedef.php

typedef是一个关键字,在 C 语言中用来给现有的数据类型指定替代名称。它主要用于用户定义的数据类型,当数据类型的名称在程序中使用变得稍微复杂时。以下是使用typedef的一般语法,

typedef <existing_name> <alias_name>

让我们举个例子看看typedef实际上是如何工作的。

typedef unsigned long ulong;

上面的陈述定义了术语unsigned long的术语ulong。现在这个ulong标识符可以用来定义unsigned long类型变量。

ulong i, j;

typedef 的应用

typedef也可以用来给用户定义的数据类型命名。让我们看看它在结构中的应用。

 typedef struct
{
    type member1;
    type member2;
    type member3;
} type_name;

这里 type_name 代表与之相关的结构定义。现在这个类型名称可以用来声明这个结构类型的变量。

type_name t1, t2;

使用 typedef 的结构定义

让我们举一个简单的代码例子来理解如何使用typedef关键字在 C 语言中定义一个结构。

#include<stdio.h>
#include<string.h>

typedef struct employee
{
    char name[50];
    int salary;
}emp;

void main( )
{
    emp e1;
    printf("\nEnter Employee record:\n");
    printf("\nEmployee name:\t");
    scanf("%s", e1.name);
    printf("\nEnter Employee salary: \t");
    scanf("%d", &e1.salary);
    printf("\nstudent name is %s", e1.name);
    printf("\nroll is %d", e1.salary);
}

typedef和指针

typedef也可以用来给指针取别名。这里有一个例子,在指针声明期间使用typedef是有益的。

在指针中*绑定到右边而不是左边。

int* x, y;

通过这个声明语句,我们实际上是将x声明为类型为int的指针,而y将声明为普通的int变量。

typedef int* IntPtr;
IntPtr x, y, z;

但是如果我们像上面的例子一样使用typedef,我们可以在一条语句中声明任意数量的指针。

注意:如果你没有任何关于指针的先验知识,一定要先学习指针。



联合

原文:https://www.studytonight.com/c/unions-in-c.php

联合在概念上类似于 结构 。声明/定义联合的语法也类似于结构的语法。唯一的区别是在存储方面。在结构中每个成员都有自己的存储位置,而联合的所有成员都使用一个共享内存位置,该位置等于其最大数据成员的大小。

Union and Structure comparison C language

这意味着尽管联合可能包含许多不同类型的成员,却不能同时处理所有成员。使用union 关键字声明一个联合

union item
{
    int m;
    float x;
    char c;
}It1;

这声明了类型为union item的变量It1。这个union包含三个成员,每个成员都有不同的数据类型。然而,一次只能使用其中一个。这是因为所有union变量只分配了一个位置,而不管它们的大小如何。编译器分配的存储足够大,可以容纳联合中最大的变量类型。

在上面声明的联合中,成员x需要 4 字节,这在 16 位机器的成员中是最大的。联盟的其他成员将共享相同的内存地址。


访问 C 语言中的联合成员

访问任何union成员的语法与访问结构成员相似,

union test
{
    int a;
    float b;
    char c;
}t;

t.a;    //to access members of union t
t.b;     
t.c;

举个例子

 #include <stdio.h>

union item
{
    int a;
    float b;
    char ch;
};

int main( )
{
    union item it;
    it.a = 12;
    it.b = 20.2;
    it.ch = 'z';

    printf("%d\n", it.a);
    printf("%f\n", it.b);
    printf("%c\n", it.ch);

    return 0;
}

-26426 20.1999 z

从这里可以看到,ab的值被破坏,只有变量c打印出预期的结果。这是因为在联合中,内存在不同的数据类型之间共享。因此,当前存储其值的唯一成员将拥有内存。

在上面的例子中,变量c的值最终被存储,因此其他变量的值丢失。



指针

C 指针介绍

原文:https://www.studytonight.com/c/pointers-in-c.php

C 语言中的指针是一个保存另一个相同数据类型变量地址的变量。

指针用于访问内存和操作地址。

指针是 C 语言最鲜明、最令人兴奋的特征之一。它为语言提供了力量和灵活性。虽然指针在一开始可能会显得有些混乱和复杂,但是相信我,一旦你理解了这个概念,你就能够用 C 语言做更多的事情。

在我们开始理解指针是什么以及它们能做什么之前,让我们先来理解“内存位置的地址”是什么意思?


C 语言中的地址

每当用 C 语言定义一个变量时,就给它分配一个存储位置,它的值将存储在这个位置。我们可以使用&符号轻松检查该内存地址。

如果var是变量的名称,那么&var会给出它的地址。

让我们编写一个小程序来查看我们在程序中定义的任何变量的内存地址。

#include<stdio.h>

void main()
{
    int var = 7;
    printf("Value of the variable var is: %d\n", var);
    printf("Memory address of the variable var is: %x\n", &var);
}

变量 var 的值为:7 变量 var 的内存地址为:bcc7a00

你一定也看到了在功能 scanf()中,我们提到&var来为任何变量var进行用户输入。

scanf("%d", &var);

这用于将用户输入的值存储到变量var的地址。


指针的概念

每当在程序中声明一个变量时,系统在内存中为该变量分配一个位置,即一个地址,以保存分配的值。这个位置有自己的地址号码,我们刚刚在上面看到了。

让我们假设系统已经为变量a分配了内存位置80F

int a = 10;

storage of variable in C

我们可以通过使用变量名a或者通过使用其地址80F来访问值10

问题是我们如何使用变量的地址来访问它?由于内存地址也只是数字,它们也可以分配给其他变量。用于保存内存地址的变量称为指针变量

因此指针变量只不过是一个保存其他变量地址的变量。一个指针变量的值被存储在另一个内存位置。

Pointer to a variable


使用指针的好处

下面我们列出了使用指针的一些好处:

  1. 指针在处理数组和结构时更有效。
  2. 指针允许引用函数,从而有助于将函数作为参数传递给其他函数。
  3. 它减少了程序的长度和执行时间。
  4. 它允许 C 语言支持动态内存管理。

在下一个教程中,我们将学习指针的语法,如何声明和定义指针,以及如何使用指针。下一课再见。



C 语言中指针变量的声明、初始化和使用

原文:https://www.studytonight.com/c/declaring-and-initializing-pointer.php

在本教程中,我们将学习如何声明、初始化和使用指针,以及空指针及其用法。

继续阅读前,请检查以下主题:

  • 碳数组

  • 循环入 C

  • 功能在 C

C 指针变量的声明

指针声明的一般语法是,

datatype *pointer_name;

指针的数据类型和指针变量所指向的变量必须相同。

C 指针变量的初始化

指针初始化是将变量的地址分配给指针变量的过程。它包含相同数据类型的变量的地址。在 C 语言中地址运算符 &用于确定一个变量的地址。&(紧接在变量名之前)返回与之关联的变量的地址。

int a = 10;
int *ptr;       //pointer declaration
ptr = &a;       //pointer initialization 

initialize pointer variable in C

指针变量总是指向相同数据类型的变量。例如:

float a;
int *ptr = &a;       // ERROR, type mismatch 

在声明指针变量时,如果它没有被赋给任何东西,那么它包含垃圾值。因此,建议为其赋值NULL

set pointer variable value

在 C 中,被赋予NULL值的指针称为 空指针。

 int *ptr = NULL;

使用指针或指针的解引用

一旦指针被分配了变量的地址,为了访问变量的值,使用间接运算符取消引用运算符 *,指针被取消引用。为了更好地理解,请考虑以下示例。

#include <stdio.h>

int main()
{
    int a;  
    a = 10;
    int *p = &a;     // declaring and initializing the pointer

    //prints the value of 'a'
    printf("%d\n", *p);  
    printf("%d\n", *&a);  
    //prints the address of 'a'
    printf("%u\n", &a);    
    printf("%u\n", p);     

    printf("%u\n", &p);    //prints address of 'p'

    return 0;
}

10
10
3795480300
3795480300
3795480304

使用指针时要记住的点

  • 声明/初始化指针变量时,*表示变量是指针。

  • 任何变量的地址都是通过在变量名前面加上&符号&给出的。

  • 指针变量存储变量的地址。

  • 声明int *a并不意味着a将包含一个整数值。这意味着a将包含存储整数值的变量的地址。

  • 使用指针变量*访问存储的某个地址的值。这里*可以理解为的值。

既然我们已经学习了 C 语言中指针的基础知识,那么你可以使用指针来查看一些 C 程序。

阅读更多:

  • 简单指针程序

  • 指针程序数组

  • 双指针

  • 带功能的指针



C 语言中的指向指针的指针(双指针)

原文:https://www.studytonight.com/c/pointer-to-pointer.php

指针用于存储类似数据类型的其他变量的地址。但是如果你想存储指针变量的地址,那么你又需要一个指针来存储它。因此,当一个指针变量存储另一个指针变量的地址时,它被称为指针指向指针变量或双指针

语法:

int **p1;

这里,我们使用了两个间接运算符(*)来存储和指向指针变量的地址,即int *。如果我们想存储这个(双指针)变量p1的地址,那么语法将变成:

int ***p2

表示指针指针的简单程序

#include <stdio.h>

int main() {

    int  a = 10;
    int  *p1;       //this can store the address of variable a
    int  **p2; 
    /*
        this can store the address of pointer variable p1 only. 
        It cannot store the address of variable 'a' 
    */

    p1 = &a;
    p2 = &p1;

    printf("Address of a = %u\n", &a);
    printf("Address of p1 = %u\n", &p1);
    printf("Address of p2 = %u\n\n", &p2);

    // below print statement will give the address of 'a'
    printf("Value at the address stored by p2 = %u\n", *p2);

    printf("Value at the address stored by p1 = %d\n\n", *p1);

    printf("Value of **p2 = %d\n", **p2); //read this *(*p2)

    /*
        This is not allowed, it will give a compile time error-
        p2 = &a;
        printf("%u", p2);
    */
    return 0;
}

a 的地址= 2686724 P1 的地址= 2686728 的地址= 2686732 存储的地址值= 2686724 P1 存储的地址值= 10 * * p2 = 10

上述程序的说明

Pointer to a Pointer

  • p1指针变量只能保存变量a的地址(即间接运算符的个数(*)-1 变量)。同样,p2变量只能保存变量p1的地址。它不能保存变量a的地址。
  • *p2给出了p2指针存储的地址值。p2存储p1指针的地址,p1地址的值是变量a的地址。因此,*p2打印a的地址。
  • **p2可以读作*(*p2)。因此,它给出了存储在地址*p2的值。从上面的陈述中,你知道*p2是指变量 a 的地址。因此,地址*p2的值是 10。因此,**p2打印10


C 语言中的指针和数组

原文:https://www.studytonight.com/c/pointers-with-array.php

在开始学习 C 语言中的指针和数组之前,请先了解以下主题:

  • C 中的数组

  • 指针在 C

当 C 语言中的数组被声明时,编译器分配足够的内存来包含它的所有元素。它的基址也是由编译器分配的。

声明一个数组arr

int arr[5] = { 1, 2, 3, 4, 5 };

假设arr的基址为 1000,每个整数需要两个字节,这五个元素将存储如下:

address of array in C

变量arr会给出基址,是一个常量指针指向arr[0]。因此arr包含arr[0]的地址,即1000

arr有两个目的——

  • 这是数组的名称
  • 它充当指向数组中第一个元素的指针。

arr默认等于&arr[0]

为了更好地理解指针的声明和初始化- 点击这里。参照程序执行。

注:

  • 指针一旦递增,就不能递减。p--行不通。

指向数组的指针

使用指针指向一个数组,然后使用该指针访问数组元素。例如,

#include<stdio.h>

void main()
{
   int a[3] = {1, 2, 3};
   int *p = a;    
   for (int i = 0; i < 3; i++)
   {
      printf("%d", *p);
      p++;
   }
  return 0;
} 

1 2 3

Using Array name as pointer in C

语法:

*(a+i)  //pointer with an array

与以下相同:

a[i]

指向多维数组的指针

让我们看看如何使指针指向多维数组。在a[i][j]中,a会给出这个数组的基址,甚至a + 0 + 0也会给出基址,也就是a[0][0]元素的地址。

语法:

*(*(a + i) + j)

指针和字符串

指针用于创建字符串。char类型的指针变量被视为字符串。

char *str = "Hello";

上面的代码创建了一个字符串,并将其地址存储在指针变量str中。指针str现在指向字符串“你好”的第一个字符。

  • 使用char指针创建的字符串可以在运行时被赋值。
char *str;
str = "hello"; 
  • 可以使用printf()puts()打印字符串的内容。
printf("%s", str);
puts(str);
  • str是字符串的指针,也是字符串的名称。因此我们不需要使用间接运算符*

指针数组

指针在处理具有不同长度行的字符数组时非常有用。

char *name[3] = { 
    "Adam",
    "chris",
    "Deniel"
};
//without pointer
char name[3][20] = { 
    "Adam",
    "chris",
    "Deniel"
};

Pointer with character array in c

在第二种方法中,内存浪费更多,因此在这种情况下最好使用指针。

建议教程:

  • 带功能的指针

  • 指向结构的指针

  • 指针运算

  • 指向数组程序的指针



C 语言中的指向结构数组的指针

原文:https://www.studytonight.com/c/pointers-to-structure-in-c.php

就像我们有整数数组、指针数组等一样,我们也可以有结构变量数组。为了有效地使用结构变量数组,我们使用结构类型为的指针。我们也可以有指向单个结构变量的指针,但它主要用于处理结构变量数组。

#include <stdio.h>

struct Book
{
    char name[10];
    int price;
}

int main()
{
    struct Book a;      //Single structure variable
    struct Book* ptr;   //Pointer of Structure type
    ptr = &a;

    struct Book b[10];  //Array of structure variables
    struct Book* p;     //Pointer of Structure type
    p = &b;  

    return 0;
}

Pointer to Structure array in C


用指针访问结构成员

为了使用结构变量访问结构的成员,我们使用了点.操作符。但是当我们有一个结构类型的指针时,我们使用箭头->来访问结构成员。

#include <stdio.h>

struct my_structure {
    char name[20];
    int number;
    int rank;
};

int main()
{
    struct my_structure variable = {"StudyTonight", 35, 1};

    struct my_structure *ptr;
    ptr = &variable;

    printf("NAME: %s\n", ptr->name);
    printf("NUMBER: %d\n", ptr->number);
    printf("RANK: %d", ptr->rank);

    return 0;
}

姓名:学习今晚人数:35 排名:1



C 语言中的指针算法

原文:https://www.studytonight.com/c/pointer-arithmetic-in-c.php

要想对指针有完整的了解,指针算术非常重要要懂。在本主题中,我们将研究当指针递增时,内存地址如何变化。


16 位机(涡轮增压)

在 16 位机器中,所有类型指针的大小,无论是int*float*char*还是double*总是 2 字节。但是当我们在指针上执行任何算术函数如增量时,变化会根据其原始数据类型的大小而发生。

16 位机器上数据类型的大小:

| 类型 | 大小(字节) |
| 整数或有符号整数 | Two |
| 茶 | one |
| 长的 | four |
| 漂浮物 | four |
| 两倍 | eight |
| 长双 | Ten |


指针算法示例

现在让我们举几个例子,更清楚地理解这一点。

int* i;
i++;

在上述情况下,指针将为 2 字节。而当我们递增时,它会递增 2 个字节,因为int也是 2 个字节。

float* i;
i++;

在这种情况下,指针的大小最初仍然是 2 字节。但是现在,当我们增加它时,它将增加 4 个字节,因为float 数据类型是 4 个字节。

double* i;
i++;

同样,在这种情况下,指针的大小仍然是 2 字节。但是现在,当我们增加它的时候,它会增加 8 个字节,因为它的数据类型是double


32 位机 (Visual Basic C++)

指针算法的概念保持不变,但是在 32 位机器中指针和各种数据类型的大小是不同的。32 位机器中的指针为 4 字节

下面是 32 位机器上数据类型的大小表:

| 类型 | 大小(字节) |
| 整数或有符号整数 | four |
| 茶 | Two |
| 长的 | eight |
| 漂浮物 | eight |
| 两倍 | Sixteen |

注意:我们不能添加两个指针。这是因为指针包含地址,添加两个地址没有意义,因为你不知道它会指向什么。

但是我们可以减去两个指针。这是因为两个指针之间的差异给出了可以存储在两个指针之间的数据类型的元质数量。


指针算法程序(32 位机器)

#include <stdio.h>

int main()
{
    int m = 5, n = 10, o = 0;

    int *p1;
    int *p2;
    int *p3;

    p1 = &m;    //printing the address of m
    p2 = &n;    //printing the address of n

    printf("p1 = %d\n", p1);
    printf("p2 = %d\n", p2);

    o = *p1+*p2;
    printf("*p1+*p2 = %d\n", o);//point 1

    p3 = p1-p2;
    printf("p1 - p2 = %d\n", p3); //point 2

    p1++;
    printf("p1++ = %d\n", p1); //point 3

    p2--;
    printf("p2-- = %d\n", p2); //point 4

    //Below line will give ERROR
    printf("p1+p2 = %d\n", p1+p2); //point 5

    return 0;
}

P1 = 2680016 p2 = 2680012 * P1+* p2 = 15 P1-p2 = 1 p1++ = 2680020 p2-= 2680008

上述程序的说明:

  1. 第 1 点:这里,*表示“给定地址的值”。因此,它将 m 和 n 的值相加,即 15。
  2. 点 2: 它减去两个变量的地址,然后除以指针数据类型的大小(这里是整数,大小为 4 字节),这就给出了可以存储在其中的整数数据类型的元质数量。
  3. 点 3: 它将指针存储的地址增加其数据类型的大小(这里是 4)。
  4. 指针 4: 它将指针存储的地址减其数据类型的大小(这里是 4)。
  5. 点 5: 不允许增加两个指针。


C 语言中的作为函数参数的指针

原文:https://www.studytonight.com/c/pointer-with-function-in-c.php

指针作为函数参数用于保存函数调用期间传递的参数地址。这也被称为通过引用调用。当通过引用调用函数时,对引用变量所做的任何更改都会影响原始变量。


示例时间:使用指针交换两个数字

#include <stdio.h>

void swap(int *a, int *b);

int main()
{
    int m = 10, n = 20;
    printf("m = %d\n", m);
    printf("n = %d\n\n", n);

    swap(&m, &n);    //passing address of m and n to the swap function
    printf("After Swapping:\n\n");
    printf("m = %d\n", m);
    printf("n = %d", n);
    return 0;
}

/*
    pointer 'a' and 'b' holds and 
    points to the address of 'm' and 'n'
*/
void swap(int *a, int *b) 
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

交换后 m = 10n = 20:m = 20n = 10


返回指针变量的函数

一个函数也可以return一个指向调用函数的指针。在这种情况下,你必须小心,因为函数的局部变量不在函数之外。它们只在函数内部有作用域。因此,如果您返回一个连接到局部变量的指针,当函数结束时,该指针将什么也不指向。

#include <stdio.h>

int* larger(int*, int*);

void main()
{
    int a = 15;
    int b = 92;
    int *p;
    p = larger(&a, &b);
    printf("%d is larger",*p);
}

int* larger(int *x, int *y)
{
    if(*x > *y)
        return x;
    else
        return y;
}

92 更大


返回有效指针的安全方法。

  1. 要么使用带有函数的参数。因为传递给函数的参数是在调用函数内部声明的,因此它们也将存在于函数外部。

  2. 或者,在函数内部使用static 局部变量并返回它们。由于静态变量在main()函数退出之前有一个生命周期,因此它们可以通过程序使用。


指向函数的指针

可以声明一个指向某个函数的指针,该指针可以用作另一个函数的参数。指向函数的指针声明如下,

type (*pointer-name)(parameter);

这里有一个例子:

int (*sum)();   //legal declaration of pointer to function
int *sum();     //This is not a declaration of pointer to function

当一个函数指针被分配了该函数的名称时,它可以指向一个特定的函数。

int sum(int, int);
int (*s)(int, int);
s = sum;

这里s是一个函数sum的指针。现在可以使用函数指针s调用sum,同时提供所需的参数值。

s (10, 20);

指向函数的指针示例

#include <stdio.h>

int sum(int x, int y)
{
    return x+y;
}

int main( )
{
    int (*fp)(int, int);
    fp = sum;
    int s = fp(10, 15);
    printf("Sum is %d", s);

    return 0;
}

Twenty-five


复杂函数指针示例

你会发现周围有很多复杂的函数 指针的例子,让我们看一个这样的例子,试着去理解它。

void *(*foo) (int*);

看似复杂,其实很简单。在这种情况下(*foo)是函数的指针,它的参数是int*类型,返回类型是void*



文件/错误

C 语言文件输入/输出

原文:https://www.studytonight.com/c/file-input-output.php

一个文件代表磁盘上存储一组相关数据的字节序列。文件是为永久存储数据而创建的。这是一个现成的结构。

在 C 语言中,我们使用文件类型的结构指针来声明一个文件。

FILE *fp;

c 提供了许多有助于执行基本文件操作的功能。以下是功能,

| 功能 | 描述 |
| fopen() | 创建新文件或打开现有文件 |
| fclose() | 关闭文件 |
| getc() | 从文件中读取字符 |
| putc() | 将字符写入文件 |
| fscanf() | 从文件中读取一组数据 |
| fprintf() | 将一组数据写入文件 |
| getw() | 从文件中读取整数 |
| 普托() | 将整数写入文件 |
| fseek() | 将位置设置为所需的点 |
| ftell() | 给出文件中的当前位置 |
| 倒带() | 将位置设置为起点 |


打开文件或创建文件

fopen()功能用于创建新文件或打开现有文件。

一般语法:

*fp = FILE *fopen(const char *filename, const char *mode);

这里,*fp是文件指针(FILE *fp),它将保存对打开(或创建)文件的引用。

文件名是要打开的文件的名称,模式指定打开文件的目的。模式可以是以下类型:

| 方式 | 描述 |
| r | 以阅读模式打开文本文件 |
| w | 以书写模式打开或创建文本文件。 |
| a | 以追加模式打开文本文件 |
| r+ | 以读写模式打开文本文件 |
| w+ | 以读写模式打开文本文件 |
| a+ | 以读写模式打开文本文件 |
| 元素铷的符号 | 以读取模式打开二进制文件 |
| 世界银行 | 以写入模式打开或创建二进制文件 |
| 腹肌 | 以追加模式打开二进制文件 |
| rb+ | 以读写模式打开二进制文件 |
| wb+ | 以读写模式打开二进制文件 |
| ab+ | 以读写模式打开二进制文件 |


关闭文件

fclose()功能用于关闭已经打开的文件。

一般语法:

int fclose( FILE *fp);

这里fclose()功能关闭文件,成功返回,如果关闭文件有错误则返回 EOF 。这个 EOF 是头文件 stdio.h 中定义的常量。


文件的输入/输出操作

在上表中,我们讨论了执行文件读写的各种文件输入/输出功能。getc()putc()是最简单的函数,可以用来读写文件中的单个字符。

#include<stdio.h>

int main()
{
    FILE *fp;
    char ch;
    fp = fopen("one.txt", "w");
    printf("Enter data...");
    while( (ch = getchar()) != EOF) {
        putc(ch, fp);
    }
    fclose(fp);
    fp = fopen("one.txt", "r");

    while( (ch = **getc**(fp)! = EOF)
    printf("%c",ch);

    // closing the file pointer
    fclose(fp);

    return 0;
}

使用fprintf()fscanf()读取和写入文件

#include<stdio.h>

struct emp
{
    char name[10];
    int age;
};

void main()
{
    struct emp e;
    FILE *p,*q;
    p = fopen("one.txt", "a");
    q = fopen("one.txt", "r");
    printf("Enter Name and Age:");
    scanf("%s %d", e.name, &e.age);
    fprintf(p,"%s %d", e.name, e.age);
    fclose(p);
    do
    {
        fscanf(q,"%s %d", e.name, e.age);
        printf("%s %d", e.name, e.age);
    }
    while(!feof(q));
}

在这个程序中,我们创建了两个文件指针,它们都指向同一个文件,但是模式不同。

fprintf()功能直接写入文件,而fscanf()从文件中读取,然后可以使用标准的printf()功能打印在控制台上。


追加模式和写入模式的区别

写(w)模式和追加(a)模式,而打开文件几乎是一样的。两者都用于写入文件。在这两种模式下,如果新文件还不存在,就会创建新文件。

它们唯一的区别是,当你模式下打开一个文件时,文件被重置,导致文件中已经存在的任何数据被删除。在附加模式下,这不会发生。追加模式用于向文件的现有数据(如果有)追加或添加数据。因此,当您在追加(a)模式下打开一个文件时,光标位于文件中当前数据的末尾。


二进制文件的读写

二进制文件类似于文本文件,但它只包含大的数字数据。在上面的打开模式表中提到了打开模式。

fread()fwrite()函数用来读写的是二进制文件。

fwrite(data-element-to-be-written, size_of_elements, number_of_elements, pointer-to-file);

fread()也是用同样的方式,用同样的参数像fwrite()函数。下面提到的是一个写入二进制文件的简单例子

const char *mytext = "The quick brown fox jumps over the lazy dog";   
FILE *bfp= fopen("test.txt", "wb");   
if (bfp) 
{     
    fwrite(mytext, sizeof(char), strlen(mytext), bfp);     
    fclose(bfp);   
}

fseek()ftell()rewind()功能

  • fseek():用于使用 fseek 功能将读数控件移动到不同的位置。
  • ftell():告知文件指针中光标当前位置的字节位置。
  • rewind():将控件移动到文件开头。

一些文件处理程序示例

  • 列出目录中存在的所有文件
  • 读取文件内容并显示在屏幕上
  • 查找文件大小
  • 创建一个文件并在其中存储信息
  • 反转文件内容并打印
  • 将一个文件的内容复制到另一个文件中


C 语言中的错误处理

原文:https://www.studytonight.com/c/error-handling-in-c.php

C 语言不提供任何对错误处理的直接支持。但是 error.h 头文件中定义的一些方法和变量可以用来使用函数中的返回语句指出错误。在 C 语言中,函数在出现错误时返回-1NULL值,全局变量errno设置有错误代码。所以返回值可以用来在编程时检查错误。


什么是 errno?

每当用 C 语言进行函数调用时,都会有一个名为errno的变量与之关联。它是一个全局变量,可用于根据其值识别函数执行时遇到的错误类型。下面我们列出了错误号及其含义。

| errno value | 错误 |
| one | 不允许操作 |
| Two | 没有这样的文件或目录 |
| three | 没有这样的过程 |
| four | 中断的系统调用 |
| five | 输入输出错误 |
| six | 没有这样的设备或地址 |
| seven | 参数列表太长 |
| eight | Exec 格式错误 |
| nine | 错误的文件编号 |
| Ten | 没有子进程 |
| Eleven | 再试 |
| Twelve | 被遗忘 |
| Thirteen | 权限被拒绝 |

C 语言使用以下函数来表示与 errno 相关的错误信息:

  • perror():返回传递给它的字符串以及当前 errno 值的文本表示。
  • strerror()字符串库中定义。此方法返回指向当前 errno 值的字符串表示形式的指针。

举个例子

#include <stdio.h>       
#include <errno.h>       
#include <string.h> 

int main ()
{
    FILE *fp;

    /* 
        If a file, which does not exists, is opened,
        we will get an error
    */ 
    fp = fopen("IWillReturnError.txt", "r");

    printf("Value of errno: %d\n ", errno);
    printf("The error message is : %s\n", strerror(errno));
    perror("Message from perror");

    return 0;
}

错误号的值:2 错误消息是:没有这样的文件或目录


其他错误处理方式

我们也可以使用exit()函数中的退出状态常量来通知调用函数错误。可用的两个常量值是EXIT_SUCCESSEXIT_FAILURE。这些只不过是定义了 stdlib.h 头文件的宏。

#include <stdio.h>       
#include <errno.h>       
#include <stdlib.h>       
#include <string.h>       

extern int errno;

void main()
{
    char *ptr = malloc( 1000000000UL);  //requesting to allocate 1gb memory space
    if (ptr == NULL)    //if memory not available, it will return null 
    {  
        puts("malloc failed");
        puts(strerror(errno));
        exit(EXIT_FAILURE);     //exit status failure
    }
    else
    {
        free( ptr);
        exit(EXIT_SUCCESS);     //exit status Success      
    }
}

此处退出功能用于指示退出状态。以退出状态退出程序总是一个好的做法。退出 _ 成功退出 _ 失败是用来显示退出状态的两个宏。如果操作成功后程序出来退出 _ 成功用于显示成功退出。它被定义为 0。退出 _ 失败用于程序中出现任何失败的情况。它被定义为-1。


除以零

有些情况下无法处理错误。在 C 语言中,一种这样的情况是被零除。你所能做的就是避免这样做,因为如果你这样做,C 语言就不能理解发生了什么,并给出一个运行时错误。

避免这种情况的最好方法是,在除法运算中使用除数之前检查它的值。可以使用if条件,如果发现为零,只要显示一条消息,从函数返回即可。



C 语言中的动态内存分配

原文:https://www.studytonight.com/c/dynamic-memory-allocation-in-c.php

运行时分配内存的过程称为动态内存分配。被称为内存管理功能的库例程用于在程序执行期间分配和释放内存。这些函数在 stdlib.h 头文件中定义。

| 功能 | 描述 |
| malloc() | 分配请求的字节大小,并返回指向分配空间的第一个字节的 void 指针 |
| calloc() | 为元质数组分配空间,将它们初始化为零,然后返回指向内存的 void 指针 |
| free | 释放以前分配的内存 |
| realloc | 修改以前分配的空间大小 |


内存分配过程

全局变量、static变量和程序指令在永久存储区获得内存,而局部变量存储在名为的存储区。

这两个区域之间的内存空间称为区域。该区域用于程序执行期间的动态内存分配。堆的大小不断变化。

dynamic memory allocation in c


分配内存块

malloc()函数用于在运行时分配内存块。该函数保留给定大小的内存块,并返回类型为void指针。这意味着我们可以使用类型转换将它分配给任何类型的指针。如果它未能按照指定分配足够的空间,它将返回一个NULL指针。

语法:

void* malloc(byte-size)

举例时间:malloc()

int *x;
x = (int*)malloc(50 * sizeof(int));     //memory space allocated to variable x
free(x);    //releases the memory allocated to variable x

calloc()是另一个内存分配函数,用于在运行时分配内存。calloc函数通常用于为派生数据类型分配内存,如数组和 结构。如果未能按规定分配足够的空间,则返回一个NULL 指针。

语法:

void *calloc(number of items, element-size)

举例时间:卡洛克()

struct employee
{
    char *name;
    int salary;
};
typedef struct employee emp;
emp *e1;
e1 = (emp*)calloc(30,sizeof(emp));

realloc()改变已经动态分配给变量的内存大小。

语法:

void* realloc(pointer, new-size)

一个例子的时间:realloc()

int *x;
x = (int*)malloc(50 * sizeof(int));
x = (int*)realloc(x,100);   //allocated a new memory to variable x

malloc()calloc()的区别

卡洛克() malloc()
calloc()用 0 值初始化分配的内存。 malloc()用垃圾值初始化分配的内存。
参数数量为 2 参数数量为 1
语法:(cast_type *)calloc(blocks,size _ of _ block); 语法:(cast _ type *)malloc(Size _ in _ bytes);

表示动态内存分配的程序(使用 calloc())

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i, n;
    int *element;

    printf("Enter total number of elements: ");
    scanf("%d", &n);

    /*
        returns a void pointer(which is type-casted to int*)
        pointing to the first block of the allocated space
    */
    element = (int*) calloc(n,sizeof(int)); 

    /*
        If it fails to allocate enough space as specified, 
        it returns a NULL pointer.
    */
    if(element == NULL) 
    {
        printf("Error.Not enough space available");
        exit(0);
    }

    for(i = 0; i < n; i++)
    {
        /*
            storing elements from the user 
            in the allocated space
        */
       scanf("%d", element+i); 
    }
    for(i = 1; i < n; i++)
    {
       if(*element > *(element+i))
       {
            *element = *(element+i);
        }
    }

    printf("Smallest element is %d", *element);

    return 0;
}

输入元素总数:5 4 2 1 5 3 最小元素为 1



C 语言中的命令行参数

原文:https://www.studytonight.com/c/command-line-argument.php

命令行参数是调用程序时提供给程序的参数。命令行参数是 C 编程中的一个重要概念。它主要用于需要从外部控制程序的时候。命令行参数被传递给main()方法。

语法:

int main(int argc, char *argv[])

这里argc计算命令行上的参数数量,argv[ ]是一个指针数组,它保存类型为char的指针,指向传递给程序的参数。


命令行参数示例

#include <stdio.h>
#include <conio.h>

int main(int argc, char *argv[])
{
    int i;
    if( argc >= 2 )
    {
        printf("The arguments supplied are:\n");
        for(i = 1; i < argc; i++)
        {
            printf("%s\t", argv[i]);
        }
    }
    else
    {
        printf("argument list is empty.\n");
    }
    return 0;
}

请记住argv[0]保存程序的名称,argv[1]指向第一个命令行参数,argv[n]给出最后一个参数。如果没有提供参数,argc将为 1。


C 程序

从基本程序开始

C 程序:你好世界

原文:https://www.studytonight.com/c/programs/basic/hello-world

下面是一个用 C 语言打印 Hello World 的简单程序。

Hello World 程序是任何编程语言中的第一个程序,它的创建是为了检查基本设置和安装是否成功完成。

#include <stdio.h>

int main()
{
    printf("Hello World");
    return 0;
}

你好,世界

运行代码→

printf()是头文件 stdio.h 下的系统定义函数,用于将数据打印到屏幕上

让我们再看一个例子,我们将在控制台上打印更多的文本。

#include <stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int num;
    printf("\nHello world!\nWelcome to Studytonight: Best place to learn\n");
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Hello World Program in C language

\n用于将控件移动到下一行

\t用于给出水平制表符,即连续的五个空格



C 程序:接受各种数据类型输入

原文:https://www.studytonight.com/c/programs/basic/different-data-type-input

下面是一个程序,解释如何从用户那里获取 C 语言中不同数据类型的输入。不同的数据类型是int(整数值)、float(十进制值)和char(字符值)。

下面是 C 语言教程,讲解各种数据类型→C 语言中的数据类型

printf()用于在屏幕上显示文本

&用于将输入值赋给变量,并将其存储在该特定位置。

scanf()被设计为使用即将到来的教程中讨论的格式说明符从用户处获取输入

%d%i,两者都是用来从用户那里接受数字作为输入的。

%f是将浮点作为用户输入的格式说明符

%s是将字符作为用户输入的格式说明符

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int num1, num2;  
    float fraction;     
    char character;

    printf("Enter two numbers number\n");

    // Taking integer as input from user
    scanf("%d%i", &num1, &num2);
    printf("\n\nThe two numbers You have entered are %d and %i\n\n", num1, num2);

    // Taking float or fraction as input from the user
    printf("\n\nEnter a Decimal number\n");
    scanf("%f", &fraction); 
    printf("\n\nThe float or fraction that you have entered is %f", fraction);

    // Taking Character as input from the user
    printf("\n\nEnter a Character\n");
    scanf("%c",&character);
    printf("\n\nThe character that you have entered is %c", character);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");

    return 0;
}

输出:

Program for Data Type Input in C



C 程序:字符的 ASCII 值

原文:https://www.studytonight.com/c/programs/basic/ascii-value-of-character

下面是一个查找任何输入字符的 ASCII 值的程序。

%c是以字符为输入的格式说明符

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char c;
    printf("Enter a character : ");
    scanf("%c" , &c);
    printf("\n\nASCII value of %c = %d",c,c);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program to find ASCII value of character in C



C 程序:如何使用get()函数

原文:https://www.studytonight.com/c/programs/basic/use-of-gets

关于scanf()gets()的一些要点是:

  • scanf()gets()都用于接受用户的输入。
  • scanf()只有遇到空格才能进行输入。空格后的单词被它忽略了。
  • gets()用于一次进行一次输入,但与 scanf()不同,可以用于输入带有空格的完整句子。

下面是gets()的使用程序。

gets()一次只取一行,即在按下\n(回车键)之前的所有单词。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char str[50];   // char array of size 50
    printf("Enter your complete name:\n\n\n");

    gets(str);
    printf("\n\nWelcome to Studytonight  %s\n\n\n", str);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Use of Gets() Program in C language



C 程序:基本if-else条件

原文:https://www.studytonight.com/c/programs/basic/if-else

下面是if - else上的一个程序。

下面是 C 语言教程,解释 C 语言中的 If Else→If Else

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int number;
    printf("Please enter a number:\n");
    scanf("%d",&number);
    /*
        For single statements we can skip the curly brackets
    */
    if(number < 100)
        printf("Number is less than 100!\n");
    else if(number == 100)
        printf("Number is 100!\n");
    else
        printf("Number is greater than 100!\n");

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");

    return 0;
}

输出:

program output for If Else usage program in C



C 程序:带有breakswitch-case

原文:https://www.studytonight.com/c/programs/basic/switch-case

下面是一个带断点的switch-case程序。

switch()只能包含charint

break用于退出开关语句。

切换的情况可以不用默认的情况。

另一个信息是char变量总是在''内初始化(单引号)。

下面是 C 语言教程,讲解 C 中的switch-caseswitch-case

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    // Local Variable Definition
    char grade;
    printf("Enter your grade:\n");
    scanf("%c", &grade);

    switch(grade)
    {
        case 'A':
            printf("Excellent\n");
            break;
        case 'B':
            printf("Keep it up!\n\n");
            break;
        case 'C':
            printf("Well done\nbreak keyword takes execution to exit the switch case\n\n");
            break;
        case 'D':
            printf("You passed\n");
            break;
        case 'F':
            printf("Better luck next time\n");
            break;
        default:
            printf("Invalid grade\n");
    }
    printf("Your grade is %c\n",grade);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program to demonstrate Switch Case with break


不带break的开关箱

下面是一个关于switch-case的程序,没有中断。

如果没有break语句,则除default之外的匹配案例后面的案例将被执行。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    /* Local Variable Definition */
    char grade;
    printf("Enter your grade:\n");
    scanf("%c", &grade);

    switch(grade)
    {
        case 'A':
            printf("Excellent\n");
        case 'B':
            printf("\n\n\nKeep it up!\n\nNo break statement\n\nHence all the case following this(but not the ones above this) except the default case will get executed !\n\n");
        case 'C':
            printf("\n\n\t\tCase C : Well done !\n\n");
        case 'D':
            printf("\t\tCase D : You passed!\n\n");
        case 'F':
            printf("\t\tCase E : Better luck next time\n\n\n");
        default:
            printf("\t\tDefault Case : Invalid grade\n\n\n");
    }
    printf("Your grade is %c\n",grade);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program to demonstrate Switch Case without Break



C 程序:使用switch-case检查输入字符是否为元音

原文:https://www.studytonight.com/c/programs/basic/check-vowel-using-switch-case

下面是一个用switch-case检查元音的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char ch;
    printf("Input a Character :  ");
    scanf("%c", &ch);

    switch(ch)
    {
        case 'a':
        case 'A':
        case 'e':
        case 'E':
        case 'i':
        case 'I':
        case 'o':
        case 'O':
        case 'u':
        case 'U':
            printf("\n\n%c is a vowel.\n\n", ch);
            break;
        default:
            printf("%c is not a vowel.\n\n", ch);
    }
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Check Vowel using Switch Case

解释:

  • 如果break语句不用于某个案例,则执行并评估有效案例之后的所有案例。这样只写一次break语句就可以一次检查多个条件,让代码更容易理解。
  • default只有在上述情况都不成立时才执行。类似于 if-else 代码的else语句。


C 程序:反转输入字符大小写

原文:https://www.studytonight.com/c/programs/basic/reversing-case-of-character

下面是一个反转输入字符大小写的程序。

getchar()类似于scanf()

islower()是系统在 ctype.h 头文件下定义的检查字符是否小写的功能。

toupper()将输入参数转换为等效大写字符。

putchar()类似于printf()

#include<stdio.h>
#include<ctype.h> // to use system defined function islower & toupper

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char alphabet;
    printf("Enter an alphabet : ");
    putchar('\n');  // to move to next Line

    alphabet=getchar();

    printf("\n\nReverse case of %c is :  ",alphabet);

    if(islower(alphabet))
        putchar(toupper(alphabet));

    else 
        // must be an uppercase character
        printf("%c",tolower(alphabet)) ;

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Reversing case of character



C 程序:使用临时变量交换两个数字

原文:https://www.studytonight.com/c/programs/basic/swapping-two-numbers-program

下面是一个使用临时变量交换两个数字的程序。

#include<stdio.h>
#include<conio.h>

void main()
{
    int x = 10, y = 15, temp;
    temp = x;
    x = y;
    y = temp;
    printf("x = %d and y = %d", x, y);
    getch();
}

x = 15,y = 10


不使用临时变量交换牵引数

下面是一个不使用任何临时变量交换两个数字的程序。

#include<stdio.h>
#include<conio.h>

void main()
{
    int x = 10, y = 15;
    x = x + y - (y = x);
    printf("x = %d and y = %d",x,y);
    getch();
}

x = 15,y = 10


使用按位运算符交换两个数字

下面是一个使用按位运算符交换两个数字的程序。

#include<stdio.h>
#include<conio.h>

void main()
{
    int x = 6, y = 4;
    x = x^y;
    y = x^y;
    x = x^y;
    printf("x = %d and y = %d", x, y);
    getch();
}

x = 4,y = 6


用乘法和除法交换两个数字

下面是一个用乘除法交换两个数字的程序。

#include<stdio.h>
#include<conio.h>

void main()
{
    int x = 6, y = 4;
    x = x*y;
    y = x/y;
    x = x/y;
    printf("x = %d and y = %d", x, y);
    getch();
}

x = 4,y = 6



C 程序:使用全局声明打印最大和最小

原文:https://www.studytonight.com/c/programs/basic/largest-and-smallest-using-global-declaration

关于全局变量声明的一些要点是:

  • 它可以在程序中的任何地方完成。
  • 与可以在特定函数范围内使用的局部变量不同。
  • &用于将输入值赋给变量,并将其存储在该特定位置。

%0nd用于表示n数字格式的数字,以 0 开头

下面是一个使用全局声明寻找最大值和最小值的程序。

#include<stdio.h>

int a,b;
int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    printf("\n\nEnter the two values to find the greatest and smallest number: \n");
    scanf("%d%d", &a, &b);

    if(a == b)
        printf("Both are equal\n");

    else if(a < b)
    {
        printf("\n\nThe largest number is %03d\n", b);
        printf("\nThe smallest number is %03d\n", a);
        printf("\nThe largest number is %03d\n", b);
    }
    else    //Only possibility remaining
    {
        printf("The largest number is %03d\n", a);
        printf("The smallest number is %03d\n", b);
    }
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Largest and Smallest using Global Declaration



循环

C 程序:for循环的基础

原文:https://www.studytonight.com/c/programs/loop/for-loop

每个循环由序列中的三个部分组成

  1. 初始化:用于初始化循环变量。
  2. 条件:每次迭代后检查,作为循环的入口点。
  3. 更新:增加循环变量,最终终止不满足循环条件的循环。

请记住,循环条件会在条件语句再次循环之前检查它。

语法:

for(initialization, condition, incrementation)
{ 
    code statements;
}

下面是一个关于for循环的简单程序。

这是 C 语言教程,解释了中循环的for循环→

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    /* 
        Always declare the variables before using them 
    */
    int i = 0;  // declaration and initialization at the same time

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

        /*
            consequently, when i equals 10, the loop breaks.
            i is updated before the condition is checked-
            hence the value of i after exiting the loop is 10 
        */
     }

    printf("\n\The value of i after exiting the loop is %d\n\n", i);

    printf("\nRemember that the loop condition checks the conditional statement before it loops again.\n\n");

    printf("Consequently, when i equals 10, the loop breaks.\n\n");

    printf("i is updated before the condition is checked- hence the value of i after exiting the loop is 10 .\n\n");

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Basic for Loop Program



C 程序:简单的while循环

原文:https://www.studytonight.com/c/programs/loop/while-loop

每个循环依次由三个部分组成

  1. 初始化:用于初始化循环变量。
  2. 条件:每次迭代后检查,作为循环的入口点。
  3. 更新:增加循环变量,最终终止不满足循环条件的循环。

这是 C 语言教程,解释了在 C 中循环时→ 和循环时

下面是一个关于while循环的简单程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    /* 
        always declare the variables before using them 
    */
    int i = 0;  // declaration and initialization at the same time

    printf("\nPrinting numbers using while loop from 0 to 9\n\n");

    /* 
        while i is less than 10 
    */
    while(i<10)
    {
        printf("%d\n",i);

        /* 
            Update i so the condition can be met eventually 
            to terminate the loop 
        */
        i++;    // same as i=i+1;
      }
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Basic while Loop Program



C 程序:do-while循环基础

原文:https://www.studytonight.com/c/programs/loop/do-while-loop

每个循环依次由三部分组成:

  1. 初始化:用于初始化循环变量。
  2. 条件:每次迭代后检查,作为循环的入口点。
  3. 更新:增加循环变量,最终终止不满足循环条件的循环。

这是 C 语言教程,解释了在 C 语言中循环时做→ 在循环时做

当实际代码必须至少执行一次时,使用 Do while 循环。例如:在菜单驱动功能的情况下。

**下面是一个关于 do while 循环的简单程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    /* 
        always declare the variables before using them 
    */
    int i = 10;     // declaration and initialization at the same time

    do // do contains the actual code and the updation
    {
        printf("i = %d\n",i);
        i = i-1;    // updation
    }
    // while loop doesn't contain any code but just the condition
    while(i > 0);

    printf("\n\The value of i after exiting the loop is %d\n\n", i);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Basic Do While Loop Program example



C 程序:显示嵌套for循环用法

原文:https://www.studytonight.com/c/programs/loop/nested-loops

嵌套循环通常用于打印 C 语言中的模式。它们也用于使用二维数组和许多其他模式(如数字金字塔等)打印出矩阵。

下面是 C 语言教程,解释循环的嵌套→ 在 C 语言中循环的嵌套

在另一个循环中使用一个循环称为嵌套循环

下面是一个关于嵌套循环的简单程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    printf("\n\nNested loops are usually used to print a pattern in c. \n\n");
    printf("\n\nThey are also used to print out the matrix using a 2 dimensional array. \n\n");

    int i,j,k;
    printf("\n\nOutput of the nested loop is :\n\n");
    for(i = 0; i < 5; i++)
    {
        printf("\t\t\t\t");
        for(j = 0; j < 5; j++)
        printf("* ");

        printf("\n");
    }
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program example to show use of Nested for Loops in C



C 程序:打印数字阶乘

原文:https://www.studytonight.com/c/programs/loop/factorial-program

下面是一个使用 for循环求一个数的阶乘的程序。

#include<stdio.h>
#include<conio.h>
void main()
{
   int fact, i, n;
   fact = 1;
   printf("Enter the number\t");
   scanf("%d" , &n);
   for(i = 1; i <= n; i++)
   {
       fact = fact*i;
   }
   printf("Factorial of %d is %d", n , fact);
   getch();
}

输入数字 5,5 的阶乘是 120



C 程序:打印斐波那契数列

原文:https://www.studytonight.com/c/programs/loop/fibonacci-series-program

下面是一个使用 while循环打印斐波那契数列的程序。

#include<stdio.h>
#include<conio.h>

void fibonacci(int num);
void main()
{
    int num = 0;
    clrscr();
    printf("Enter number of terms\t");
    scanf("%d", &num);
    fibonacci(num);
    getch();
}

void fibonacci(int num)
{
   int a, b, c, i = 3;
   a = 0;
   b = 1;
   if(num == 1)
   printf("%d",a);

   if(num >= 2)
   printf("%d\t%d",a,b);

   while(i <= num)
   {
      c = a+b;
      printf("\t%d", c);
      a = b;
      b = c;
      i++;
   }
}

输入术语数 6 0 1 2 3 5



C 程序:检查数字是否是回文

原文:https://www.studytonight.com/c/programs/loop/palindrome-program

下面是一个检查数字是否是回文的程序。

一个回文是一个数字或者一个字符串,从前面和后面看都是相似的。例如:121 或 Oppo 等。

#include<stdio.h>
#include<conio.h>

void main()
{
    int a, b, c, s = 0;
    clrscr();
    printf("Enter a number:\t");
    scanf("%d", &a);
    c = a;

   // the number is reversed inside the while loop.
   while(a > 0)
   {
      b = a%10;
      s = (s*10)+b;
      a = a/10;
   }

   // here the reversed number is compared with the given number.
   if(s == c)
   {
      printf("The number %d is a palindrome", c);
   }
   else
   {
      printf("The number %d is not a palindrome", c);
   }
  getch();
}

输入数字:121 数字 121 是回文



C 程序:求一个数的位数和

原文:https://www.studytonight.com/c/programs/loop/sum-of-digits-program

下面是一个数字总和的程序。

#include<stdio.h>

int main()
{
	printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

	int n, sum = 0, c, remainder;

    	printf("Enter the number you want to add digits of:  ");
    	scanf("%d", &n);

	while(n != 0)
    	{
        	remainder = n%10;
        	sum += remainder;
        	n = n/10;
    	}

    	printf("\n\nSum of the digits of the entered number is  =  %d\n\n", sum);
    	printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    	return 0;
}

输出:

Program to find Sum of Digits of Number



C 程序:反转字符串

原文:https://www.studytonight.com/c/programs/loop/reverse-a-string-program

在本教程中,我们将学习如何反转给定的字符串。如果字符串是"hello" ,那么输出应该是"olleh"。我们可以用这个概念来检查回文。因为回文字符串即使在我们反转后也会有相同的值。

如果不熟悉 C 程序,建议通读这些题目。

  • C 语言概述

  • C 中的字符串和字符数组

string reversal program in C

主要有三种方法来保留给定的字符串:

  • 通过使用新的字符数组。

  • 通过交换字符串的字符。

  • 通过使用标准库函数。

使用新的字符数组反转字符串:

在这个例子中,首先我们接受用户的输入,在接受输入后,我们必须计算字符串的长度。为了计算长度,我们从字符数组的开始运行一个循环,直到找到一个空字符('\0'),并且在每次迭代中,我们增加计数变量。我们给 j 分配一个比它小的值,因为数组从零开始。在这之后,我们简单地将字符从结尾一个接一个地从原始字符数组复制到新的字符数组。

#include <stdio.h>
int main()
{
  char str[1000], rev[1000];
  int i, j, count = 0;
  scanf("%s", str);
  printf("\nString Before Reverse: %s", str);
  //finding the length of the string
  while (str[count] != '\0')
  {
    count++;
  }
  j = count - 1;

  //reversing the string by swapping
  for (i = 0; i < count; i++)
  {
    rev[i] = str[j];
    j--;
  }

  printf("\nString After Reverse: %s", rev);
}

你好

反转前串:你好
反转后串:olleH


通过交换字符串的字符来反转字符串

本示例将通过交换字符对字符串进行排序。

#include <stdio.h>
#include <string.h>
void reverseStr(char str[])
{
  int n = strlen(str);

  for (int i = 0; i < n / 2; i++)
  {
    char ch = str[i];
    str[i] = str[n - i - 1];
    str[n - i - 1] = ch;
  }
}

int main()
{
  char str[1000];
  scanf("%s", str);
  printf("\nString Before Reverse: %s", str);
  reverseStr(str);
  printf("\nString After Reverse: %s", str);
  return 0;
} 

你好

反转前串:你好
反转后串:olleH

建议教程:

  • 字符串和字符数组

  • C 中的数组

  • 功能在 C

  • C 中的指针



数字处理

C 程序:求N个数平均值

原文:https://www.studytonight.com/c/programs/numbers/average-of-n-numbers

下面是一个计算 n 个数字平均值的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int n, i;
    float sum = 0, x;

    printf("Enter number of elements:  ");
    scanf("%d", &n);
    printf("\n\n\nEnter %d elements\n\n", n);
    for(i = 0; i < n; i++)
    {
        scanf("%f", &x);
        sum += x;
    }
    printf("\n\n\nAverage of the entered numbers is =  %f", (sum/n));
    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program solution to find Average of N Numbers



C 程序:寻找 1 到 500 之间的阿姆斯特朗数字

原文:https://www.studytonight.com/c/programs/numbers/armstrong-number-program

一个阿姆斯壮数自恋数是一个 n 位数,这样其上升到 n 次方的位数之和等于该数本身。

举个例子,我们来看一个阿姆斯壮号:153,是 3 位数,这里1<sup>3</sup> + 5<sup>3</sup> + 3<sup>3</sup>1 + 125 + 27,等于 153

下面是一个程序,用于查找 1 到 500 之间的阿姆斯特朗数字。

#include<stdio.h>
#include<math.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n,sum,i,t,a;
    printf("\n\n\nThe Armstrong numbers in between 1 to 500 are : \n\n\n");

    for(i = 1; i <= 500; i++)
    {
        t = i;  // as we need to retain the original number
        sum = 0;
        while(t != 0)
        {
            a = t%10;
            sum += a*a*a;
            t = t/10;
        }

        if(sum == i)
        printf("\n\t\t\t%d", i);
    }

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program to print armstrong number between 1 to 500


检查一个数字是否是阿姆斯特朗数字的程序

下面是一个检查一个数字是否是阿姆斯特朗的程序。

#include<stdio.h>
#include<math.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int n, sum = 0, c, t, a;

    printf("Enter a number:  ");
    scanf("%d", &n);

    t = n;  // as need to retain the original number
    while(n != 0)
    {
        a = n%10;
        sum += a*a*a;
        n = n/10;
    }

    printf("\n\n\n\t\t\tsum = %d", sum);

    if(sum == t)
        printf("\n\n\t\t%d is an armstrong number\n", t);
    else
        printf("\n\n\t\t%d is not an armstrong number\n", t);

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program to Check if a number is Armstrong Number



C 程序:使用按位运算符检查奇数和偶数

原文:https://www.studytonight.com/c/programs/numbers/checking-for-odd-or-even

下面是一个使用按位运算符来查找数字是偶数还是奇数的程序。

如果整数 x 的二进制表示的最低有效位为 1,则x&1返回。如果二进制序列中的最低有效位或最右边的位为 0,则返回

在一个整数的二进制表示中,如果 LSB 是 1,那么它是奇数,如果 LSB 是 0,那么它是偶数

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int x;
    for(x = 0; x <= 10; x++)
    {
        if(x&1) // if number is odd
            printf("\t\t\t%d is odd\n",x);
        else if(!(x&1)) // ! is used inside if to reverse the boolean value
            printf("\t\t\t%d is even\n",x);
    }

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Finding Odd and Even Numbers using Bitwise Operator


我们使用了一个简单的for循环来输入数字,并展示了如何使用 Bitwise 运算符。您可以使用scanf()从用户处获取输入,并使用相同的逻辑来查找输入的数字是奇数还是偶数。

不使用% (Mod)运算符检查输入数是奇数还是偶数

下面是一个不用% (Mod)运算符就能发现一个数是偶数还是奇数的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n;
    printf("Enter a number:  ");
    scanf("%d",&n);

    if((n/2)*2 == n)
        printf("\n\n\t\t %d is Even\n", n);
    else
        printf("\n\n\t\t %d is Odd\n", n);

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Finding Odd and Even Numbers without using %(mod) Operator



C 程序:寻找数字因数

原文:https://www.studytonight.com/c/programs/numbers/factors-of-a-number

下面是一个寻找数字因数的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int  num, i;
    printf("Enter the number to find the factors of :  ");
    scanf("%d",&num);
    printf("\n\n\nFactors of %d are \n\n", num);

    for(i = 1; i <= num/2; i++)
    {
        if(num%i == 0)
            printf("\t\t\t%d\n", i);
    }

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Finding Factors of Number



C 程序:求N个输入数之和

原文:https://www.studytonight.com/c/programs/numbers/sum-of-n-numbers

下面是一个关于 n 个数和的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n,sum=0,c,value;

    printf("\n\nEnter the number of integers you want to add:  ");
    scanf("%d", &n);

    printf("Enter %d integers\n\n",n);
    for(c = 1; c <= n; c++)
    {
        scanf("%d", &value);
        /* 
            need to initialise sum before using otherwise 
            garbage value will get printed
        */
        sum += value;
    }

    printf("\n\n\nsum of entered numbers  = %d", sum);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program example to find Sum of N Numbers in C



C 程序:寻找前N个质数

原文:https://www.studytonight.com/c/programs/numbers/first-n-prime-numbers

下面是一个使用嵌套for循环首先找到n质数的程序,其中n的值由用户输入。

在您继续使用程序之前,请检查以下主题以了解程序:

  • C 中的循环
  • 对于 C 中的循环程序
  • 嵌套用于 C 中的循环程序
#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n,i = 3, count, c;

    printf("\nEnter the number of prime numbers required :  ");
    scanf("%d", &n);

    if(n >= 1)
    {
        printf("\n\nFirst %d prime numbers are :  ", n);
        printf("2 ");
    }

    // iteration for n prime numbers
    // i is the number to be checked in each iteration starting from 3
    for(count = 2; count <= n; i++)  
    {
        // iteration to check c is prime or not
        for(c = 2; c < i; c++)
        {
            if(i%c == 0)
                break;
        }

        if(c == i)  // c is prime
        {
            printf("%d ", i);
            count++;    // increment the count of prime numbers
        }

    }
    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

First N Prime Numbers



C 程序:在n个输入数字中找出最大数字

原文:https://www.studytonight.com/c/programs/numbers/finding-largest-among-n-numbers

下面是一个在n用户输入数字中寻找最大数字的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n,i;
    float c,big;

    printf("\n\nEnter the number of elements you wish to find the greatest element of: ");
    scanf("%d", &n);
    printf("\n\nEnter %d numbers :\n", n);

    printf("\n\n\t\t\tElement 1: ");

    //Important step- always initialize big to the first element
    scanf("%f", &big);

    for(i = 2; i <= n; i++)
    {
        printf("\n\t\t\tElement %d  : ", i);
        scanf("%f", &c);
        /* 
            if input number is larger than the 
            current largest number
        */
        if(big < c)  
            big = c;    // update big to the larger value
    }

    printf("\n\n\nThe largest of the %d numbers is  %f ", n, big);
    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Finding Largest among N Numbers



C 程序:不用pow()方法求指数

原文:https://www.studytonight.com/c/programs/numbers/finding-exponential-without-pow(-method)

下面是一个不用pow()方法求指数的程序。

long long intlong int的两倍大。

%lldlong long int的格式说明符。

#include<stdio.h>
int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int n, exp, exp1;
    long long int value = 1;

    printf("Enter the number and its exponential:\n\n");
    scanf("%d%d",&n, &exp);

    exp1 = exp;   // storing original value for future use

    // same as while((--exp)!=-1)
    while(exp-- > 0)
    {
        value *= n; // multiply n to itself exp times
    }

    printf("\n\n %d^%d = %lld\n\n", n, exp1, value);
    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Finding Exponential without Pow() Method in C



C 程序:检查输入数字是整数还是浮点数

原文:https://www.studytonight.com/c/programs/numbers/input-number-is-int-or-float

下面是一个检查用户输入的数字是整数还是浮点数据类型的程序。

strlen()不计算空字符“\0”。

#include<stdio.h>

#include<conio.h>
#include<string.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    char number[10];
    int flag = 0;
    int length, i = 0;

    printf("\n\nEnter a number: ");
    scanf("%s", number);

    length = strlen(number);

    // till string does not end
    while(number[i++] != '\0')    // same as while(length-->0)
    {
        if(number[i] == '.')    // decimal point is present
        {
            flag = 1;
            break;
        }
    }

    // if(0) is same as if(false)
    if(flag)
        printf("\n\n\n\tEntered Number is a Floating point Number\n\n");
    else
        printf("\n\n\n\tEntered Number is a integer Number\n\n");

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to find if Input Number is Int or Float



C 程序:打印任意数字的乘法表

原文:https://www.studytonight.com/c/programs/numbers/multiplication-table-of-a-number

下面是一个打印任意用户输入数字的乘法表的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n,i;

    printf("Enter an integer you need to print the table of: ");
    scanf("%d", &n);
    printf("\n\n\n");

    for(i = 1; i <= 10; i++)
    {
        printf("\n\t\t\t%d * %d   =   %d \n", n, i, n*i);
    }

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to print Multiplication Table of any Number in C



数组的概念

C 程序:打印数组的反转

原文:https://www.studytonight.com/c/programs/array/reverse-an-array

下面是一个反转数组的简单程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int c, d, n, a[100], b[100];
    printf("\n\nEnter number of elements in array :");
    scanf("%d", &n);
    printf("\n\nEnter %d elements\n", n);

    for(c = 0; c < n; c++)
        scanf("%d", &a[c]);

    /*
        temporarily storing elements into array b 
        starting from end of array a
    */
    for(c = n-1, d = 0; c >= 0; c--, d++)
        b[d] = a[c];

    /*
        copying reversed array into original.
        Here we are modifying original array to reverse it.
    */

    for(c = 0; c < n; c++)
        a[c] = b[c];

    printf("\n\n Resultant array is: ");
    for(c = 0; c < n; c++)
        printf("%d", a[c]);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to reverse an Array in C



C 程序:在数组中插入元素

原文:https://www.studytonight.com/c/programs/array/inserting-an-element-in-array

下面是一个在数组中插入元素的简单程序。

下面是 C 语言教程,讲解数组→C 语言中的数组

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int array[100], position, c, n, value;

    printf("\n\nEnter number of elements in array:");
    scanf("%d", &n);

    printf("\n\nEnter %d elements\n", n);
    for(c = 0; c < n; c++)
        scanf("%d", &array[c]);

    printf("\n\nEnter the location where you want to insert new element:  ");
    scanf("%d", &position);

    printf("\n\nEnter the value to insert: ");
    scanf("%d", &value);

    // shifting the elements from (position to n) to right
    for(c = n-1; c >= position-1; c--)
        array[c+1] = array[c];

    array[position - 1] = value;    // inserting the given value

    printf("\n\nResultant array is: ");
    /* 
        the array size gets increased by 1 
        after insertion of the element
    */
    for(c = 0; c <= n; c++) 
        printf("%d  ", array[c]);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

在上面的程序中,我们将一个数组作为用户输入,然后向用户询问他们想要添加到原始数组中的新数字,以及他们想要添加新数字的位置。

我们将现有的数字从索引位置移到数组末尾的右边一个位置,从而为新元素留出空间。然后我们在用户指定的位置索引处添加新的数字。

输出:

Insert an Element in Array



C 程序:从数组中删除元素

原文:https://www.studytonight.com/c/programs/array/deleting-an-element-from-array

下面是一个从数组中删除元素的简单程序,其中要删除的元素的位置由用户给出。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int array[100], position, c, n;
    printf("\n\nEnter number of elements in array:");
    scanf("%d", &n);

    printf("\n\nEnter %d elements\n", n);
    for(c = 0; c < n; c++)
        scanf("%d", &array[c]);

    printf("\n\nEnter the location where you want to delete element from:  ");
    scanf("%d", &position);

    if(position >= n+1)
        printf("\n\nDeletion not possible\n\n");
    else 
        // updating the locations with next elements
        for(c = position-1; c < n-1; c++)
        array[c] = array[c+1];

    printf("\n\nResultant array is: ");
    /* 
        the array size gets reduced by 1 
        after deletion of the element
    */
    for(c = 0; c < n-1; c++) 
        printf("%d  ", array[c]);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to Delete an Element from Array based on position


基于值从数组中删除元素的程序

下面是一个从数组中删除元素的简单程序,其中要删除的元素由用户给出:

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int array[10], element, c, n, pos;
    /* 
        initialization as garbage value is 
        stored by default in c variables
    */
    int found = 0; 
    printf("\n\nEnter number of elements in array:");
    scanf("%d", &n);

    printf("\n\nEnter %d elements\n", n);

    for(c = 0; c < n; c++)
        scanf("%d", &array[c]);

    printf("\n\nThe input array is: ");
    for(c = 0; c < n; c++)
    printf("%d", array[c]);

    printf("\n\nEnter the element to be deleted: ");
    scanf("%d", &element);

    // check the element to be deleted is in array or not
    for(c = 0; c < n; c++)
    {
        if(array[c] == element)
        {
            found = 1;
            pos = c;
            break;  // terminate the loop
        }
    }
    if(found == 1) // the element to be deleted exists in the array
    {
        for(c = pos; c < n-1; c++)
            array[c] = array[c+1];
    }
    else
        printf("\n\nElement %d is not found in the array\n\n", element);

    printf("\n\nResultant array is: ");
    /* 
        the array size gets reduced by 1 
        after deletion of the element
    */
    for(c = 0; c < n-1; c++) 
        printf("%d  ",array[c]);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to Delete an Element from Array based on value



C 程序:寻找数组中最大和最小元素

原文:https://www.studytonight.com/c/programs/array/largest-and-smallest-element-in-array

下面是一个寻找数组中最大和最小元素的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int a[50], size, i, big, small;

    printf("\nEnter the size of the array: ");
    scanf("%d", &size);

    printf("\n\nEnter the %d elements of the array: \n\n", size);
    for(i = 0; i < size; i++)
    scanf("%d", &a[i]);

    big = a[0]; // initializing
    /* 
        from 2nd element to the last element 
        find the bigger element than big and 
        update the value of big
    */
    for(i = 1; i < size; i++)
    {
        if(big < a[i])   // if larger value is encountered
        {
            big = a[i]; // update the value of big
        }
    }
    printf("\n\nThe largest element is: %d", big);

    small = a[0];   // initializing
    /*
        from 2nd element to the last element 
        find the smaller element than small and 
        update the value of small
    */
    for(i = 1; i < size; i++)
    {
        if(small>a[i])   // if smaller value is encountered
        {
            small = a[i];   // update the value of small
        }
    }
    printf("\n\nThe smallest element is: %d", small);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to find the Largest and Smallest Element in an Array



C 程序:使用数组求N个输入数之和

原文:https://www.studytonight.com/c/programs/array/sum-of-n-numbers-using-arrays

下面是一个使用数组查找和打印 n 个数总和的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n, sum = 0, c, array[100];

    printf("Enter the number of integers you want to add: ");
    scanf("%d", &n);

    printf("\n\nEnter %d integers \n\n", n);

    for(c = 0; c < n; c++)
    {
        scanf("%d", &array[c]);
        sum += array[c];    // same as sum = sum + array[c]
    }

    printf("\n\nSum = %d\n\n", sum);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to find Sum of N numbers using Arrays



C 程序:排序数组元素

原文:https://www.studytonight.com/c/programs/array/sort-array-element-program

下面是一个对数组中的数组元素进行排序的程序。

#include<stdio.h>
#include<conio.h>

void sorting(int *x, int y);

void main()
{
    int a[20], i, c, n;
    clrscr();
    printf("Enter number of elements you want to sort: ");
    scanf("%d", &n);

    for(i = 0; i < n; i++)
    scanf("%d", &a[i]);

    sorting(a, n);

    for(i = 0; i <n; i++)
    printf("%d\t", a[i]);

    getch();
}

void sorting(int *x, int y)
{
    int i, j, temp;
    for(i = 1; i <= y-1; i++)
    {
        for(j = 0; j < y-i; j++)
        {
            if(*(x+j) > *(x+j+1))
            {
                temp = *(x+j);
                *(x+j) = *(x+j+1);
                *(x+j+1) = temp;
            }
        }
    }
}

输入要排序的元质数量:6 5 3 4 2 1 6 1 2 3 5 6



C 程序:删除数组中重复元素

原文:https://www.studytonight.com/c/programs/array/remove-duplicate-element-program

在本教程中,我们将学习如何从数组中移除重复的元素。在继续这个程序之前,如果你不熟悉什么是数组,请阅读这篇文章:C 语言数组。

remove duplicate from array

从排序的数组中删除重复项:

这里我们实现了从排序数组中移除重复元素的程序。我们将创建一个临时数组,并将元素从一个数组复制到另一个数组,以防没有下一个匹配的元素。

注意: 这个程序只对排序数组起作用,所以在提供输入的同时,要确保给定的数组在排序数组中,否则会给出意外的输出。

#include <stdio.h>
int remove_duplicate(int arr[], int n)
{

  if (n == 0 || n == 1)
    return n;

  int temp[n];

  int j = 0;
  int i;
  for (i = 0; i < n - 1; i++)
    if (arr[i] != arr[i + 1])
      temp[j++] = arr[i];
  temp[j++] = arr[n - 1];

  for (i = 0; i < j; i++)
    arr[i] = temp[i];

  return j;
}

int main()
{
  int n;
  scanf("%d", &n);
  int arr[n];
  int i;
  for (i = 0; i < n; i++)
  {
    scanf("%d", &arr[i]);
  }
  printf("\nArray Before Removing Duplicates: ");
  for (i = 0; i < n; i++)
    printf("%d ", arr[i]);

  n = remove_duplicate(arr, n);

  printf("\nArray After Removing Duplicates: ");
  for (i = 0; i < n; i++)
    printf("%d ", arr[i]);

  return 0;
}

10
1 2 2 3 4 5 6 7 8
T3】删除重复项前的数组:1 2 2 3 4 5 6 7 8
删除重复项后的数组:1 2 3 4 5 6 7 8

从未排序的数组中删除重复项:

在这个程序中,我们将占用额外的空间来存储一个没有重复元素名声的新数组。我们将运行一个嵌套循环,首先是将元素从数组复制到 temp 数组,如果该元素已经存在于 temp 变量中,那么我们将中断内部循环,并继续对剩余的元素执行相同的过程。

#include <stdio.h>
int main()
{
  int n, count = 0;
  scanf("%d", &n);
  int arr[n], temp[n];
  for (int i = 0; i < n; i++)
  {
    scanf("%d", &arr[i]);
  }

  printf("\nArray Before Removing Duplicates: ");
  for (int i = 0; i < n; i++)
    printf("%d ", arr[i]);

  for (int i = 0; i < n; i++)
  {
    int j;
    for (j = 0; j < count; j++)
    {
      if (arr[i] == temp[j])
        break;
    }
    if (j == count)
    {
      temp[count] = arr[i];
      count++;
    }
  }

  printf("\nArray After  Removing Duplicates: ");
  for (int i = 0; i < count; i++)
    printf("%d ", temp[i]);

  return 0;
}

10
1 2 2 3 4 5 6 7 8
消除重复项前的数组:1 2 2 3 4 5 6 7 7 8
消除重复项后的数组:1 2 3 4 5 6 7 8

建议教程:

  • C 中的数组

  • C 中的循环

  • 功能在 C

  • 文件输入/输出用 C 语言



C 程序:检查二维数组是否为稀疏矩阵

原文:https://www.studytonight.com/c/programs/array/checking-for-sparse-matrix

稀疏矩阵是指 0 的个数大于非零元素个数的矩阵(二维数组)。

下面是一个检查矩阵是否稀疏的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n, m, c, d, matrix[10][10];
    int counter = 0;
    printf("\nEnter the number of rows and columns of the matrix \n\n");
    scanf("%d%d",&m,&n);

    printf("\nEnter the %d elements of the matrix \n\n", m*n);
    for(c = 0; c < m; c++)   // to iterate the rows
    {
        for(d = 0; d < n; d++)   // to iterate the columns
        {
            scanf("%d", &matrix[c][d]);
            if(matrix[c][d] == 0)
            counter++;  // same as counter=counter +1
        }
    }

    // printing the matrix
    printf("\n\nThe entered matrix is: \n\n");
    for(c = 0; c < m; c++)   // to iterate the rows
    {
        for(d = 0; d < n; d++)   // to iterate the columns
        {
            printf("%d\t", matrix[c][d]);
        }
    printf("\n"); // to take the control to the next row
    }

    // checking if the matrix is sparse or not
    if(counter > (m*n)/2)
        printf("\n\nThe entered matrix is a sparse matrix\n\n");
    else
        printf("\n\nThe entered matrix is not a sparse matrix\n\n");

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Checking if a two dimensional array is Sparse Matrix



C 程序:检查给定方阵是否对称

原文:https://www.studytonight.com/c/programs/array/check-square-matrix-is-symmetric-or-not

需要记住的几个要点:

  • 如果一个方阵等于它的转置,那么它就是对称的。
  • 矩阵的转置是通过交换行和列的索引来实现的。
  • 转置只为方阵定义。

下面是一个检查 sqaure 矩阵是否对称的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int c, d, a[10][10], b[10][10], n, temp;
    printf("\nEnter the dimension of the matrix: \n\n");
    scanf("%d", &n);

    printf("\nEnter the %d elements of the matrix: \n\n",n*n);
    for(c = 0; c < n; c++) // to iterate the rows
        for(d = 0; d < n; d++) // to iterate the columns
            scanf("%d", &a[c][d]);

    // finding transpose of a matrix and storing it in b[][]
    for(c = 0; c < n; c++) // to iterate the rows
        for(d = 0; d < n; d++) //to iterate the columns
            b[d][c] = a[c][d];

    // printing the original matrix
    printf("\n\nThe original matrix is: \n\n");
    for(c = 0; c < n; c++)   // to iterate the rows
    {
        for(d = 0; d < n; d++)   // to iterate the columns
        {
            printf("%d\t", a[c][d]);
        }
    printf("\n");
    }

    // printing the transpose of the entered matrix
    printf("\n\nThe Transpose matrix is: \n\n");
    for(c = 0; c < n; c++) // to iterate the rows
    {
        for(d = 0; d < n; d++)   // to iterate the columns
        {
            printf("%d\t", b[c][d]);
        }
        printf("\n");
    }

    // checking if the original matrix is same as its transpose
    for(c = 0; c < n; c++)   // to iterate the rows
    {
        for(d = 0; d < n; d++)   // to iterate the columns
        {
            /* 
                even if they differ by a single element, 
                the matrix is not symmetric
            */
            if(a[c][d] != b[c][d]) 
            {
                printf("\n\nMatrix is not Symmetric\n\n");
                exit(0);    // a system defined method to terminate the program
            }
        }
    }

    /* 
        if the program is not terminated yet, 
        it means the matrix is symmetric
    */
    printf("\n\nMatrix is Symmetric\n\n");
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program for Checking if a two dimensional array is Symmetric square Matrix



C 程序:2x2矩阵的行列式

原文:https://www.studytonight.com/c/programs/array/determinant-of-2x2-matrix

下面是一个寻找 2x2 矩阵的行列式的程序。

请注意,当我们说 2x2 矩阵时,我们指的是 2x2 的数组。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int a[2][2], i, j;
    long determinant;

    printf("\n\nEnter the 4 elements of the array\n");
    for(i = 0; i < 2; i++)
    for(j = 0; j < 2; j++)
    scanf("%d", &a[i][j]);

    printf("\n\nThe entered matrix is: \n\n");
    for(i = 0; i < 2; i++)
    {
        for(j = 0; j < 2; j++)
        {
            printf("%d\t", a[i][j]);   // to print the complete row
        }
        printf("\n"); // to move to the next row
    }

    // finding the determinant of a 2x2 matrix
    determinant = a[0][0]*a[1][1] - a[1][0]*a[0][1];
    printf("\n\nDterminant of 2x2 matrix is : %d - %d =  %d", a[0][0]*a[1][1], a[1][0]*a[0][1], determinant);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program to find Determinant of 2X2 Matrix



C 程序:求方阵的范数和迹

原文:https://www.studytonight.com/c/programs/array/normal-and-trace-of-square-matrix

需要记住的几个要点:

  • 范数仅针对正方阵定义。
  • 方阵:其中,行数=列数的矩阵。
  • 范数:矩阵各元素平方和的平方根。
  • :矩阵对角元素之和。
  • 对角线元素:行和列具有相同索引的元素。

让我们举一个简单的例子来更好地理解这些术语:

Normal and Trace of matrix

下面是一个求方阵的范数和迹的程序。

#include<stdio.h>
/* 
    to use the sqrt method to find 
    the square root of a number we include
    math.h header file
*/
#include<math.h>  

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int i, j, n, aj[10][10], sum = 0, sum1 = 0, a = 0, normal;

    printf("\nEnter the number of rows (columns) of the matrix: \n\n");
    scanf("%d", &n);

    printf("\nEnter the %d elements of the first matrix: \n\n", n*n);

    for(i = 0; i < n; i++)   // to iterate the rows
    {
        for(j = 0; j < n; j++)   // to iterate the columns
        {
            scanf("%d", &aj[i][j]);
            a = aj[i][j]*aj[i][j];  // finding square of each element
            sum1 += a;  // same as sum1 = sum1 + a
        }
    }
    normal = sqrt((double)sum1);    // typecasting to double value

    printf("\n\nThe normal of the given matrix is: %d", normal);
    for(i = 0; i < n; i++)
    {
        sum = sum + aj[i][i];   // sum of the diagonal elements
    }
    printf("\n\nThe Trace of the given matrix is: %d", sum);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to find Normal and Trace of a Square Matrix



C 程序:执行矩阵加减

原文:https://www.studytonight.com/c/programs/array/addition-and-subtraction-of-matrices

下面是一个对两个矩阵进行加减运算的程序。

\n用于将控件带到下一行。

\t用于控制前方 5 个空格(tab)。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int n, m, c, d, first[10][10], second[10][10], sum[10][10], diff[10][10];
    printf("\nEnter the number of rows and columns of the first matrix \n\n");
    scanf("%d%d", &m, &n);

    printf("\nEnter the %d elements of the first matrix \n\n", m*n);
    for(c = 0; c < m; c++)   // to iterate the rows
        for(d = 0; d < n; d++)   // to iterate the columns
            scanf("%d", &first[c][d]);

    printf("\nEnter the %d elements of the second matrix \n\n", m*n);
    for(c = 0; c < m; c++)   // to iterate the rows
        for(d = 0; d < n; d++)   // to iterate the columns
            scanf("%d", &second[c][d]);

    /*
        printing the first matrix
    */
    printf("\n\nThe first matrix is: \n\n");
    for(c = 0; c < m; c++)   // to iterate the rows
    {
        for(d = 0; d < n; d++)   // to iterate the columns
        {
            printf("%d\t", first[c][d]);
        }
    printf("\n");
    }

    /* 
        printing the second matrix
    */
    printf("\n\nThe second matrix is: \n\n");
    for(c = 0; c < m; c++)   // to iterate the rows
    {
        for(d = 0; d < n; d++)   // to iterate the columns
        {
            printf("%d\t", second[c][d]);
        }
    printf("\n");
    }

    /* 
        finding the SUM of the two matrices 
        and storing in another matrix sum of the same size
    */
    for(c = 0; c < m; c++)
        for(d = 0; d < n; d++)
            sum[c][d] = first[c][d] + second[c][d];

    // printing the elements of the sum matrix
    printf("\n\nThe sum of the two entered matrices is: \n\n");
    for(c = 0; c < m; c++)
    {
        for(d = 0; d < n; d++)
        {
            printf("%d\t", sum[c][d]);
        }
        printf("\n");
    }

    /*
        finding the DIFFERENCE of the two matrices 
        and storing in another matrix difference of the same size
    */
    for(c = 0; c < m; c++)
        for(d = 0; d < n; d++)
            diff[c][d] = first[c][d] - second[c][d];

    // printing the elements of the diff matrix
    printf("\n\nThe difference(subtraction) of the two entered matrices is: \n\n");
    for(c = 0; c < m; c++)
    {
        for(d = 0; d < n; d++)
        {
            printf("%d\t", diff[c][d]);
        }
        printf("\n");
    }

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to perform Addition and Subtraction of two matrices



C 程序:矩阵乘法

原文:https://www.studytonight.com/c/programs/array/matrix-multiplication-program

下面是一个关于矩阵乘法的程序。

只有当第一个矩阵的列数等于第二个矩阵的行数时,具有给定顺序的两个矩阵才能相乘。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int n, m, c, d, p, q, k, first[10][10], second[10][10], pro[10][10],sum = 0;

    printf("\nEnter the number of rows and columns of the first matrix: \n\n");
    scanf("%d%d", &m, &n);

    printf("\nEnter the %d elements of the first matrix: \n\n", m*n);
    for(c = 0; c < m; c++)   // to iterate the rows
        for(d = 0; d < n; d++)   // to iterate the columns
            scanf("%d", &first[c][d]);

    printf("\nEnter the number of rows and columns of the first matrix: \n\n");
    scanf("%d%d", &p, &q);

    if(n != p)
        printf("Matrices with the given order cannot be multiplied with each other.\n\n");

    else    // matrices can be multiplied
    {
        printf("\nEnter the %d elements of the second matrix: \n\n",m*n);

        for(c = 0; c < p; c++)   // to iterate the rows
            for(d = 0; d < q; d++)   // to iterate the columns
                scanf("%d", &second[c][d]);

        // printing the first matrix
        printf("\n\nThe first matrix is: \n\n");
        for(c = 0; c < m; c++)   // to iterate the rows
        {
            for(d = 0; d < n; d++)   // to iterate the columns
            {
                printf("%d\t", first[c][d]);
            }
            printf("\n");
        }

        // printing the second matrix
        printf("\n\nThe second matrix is: \n\n");
        for(c = 0; c < p; c++)   // to iterate the rows
        {
            for(d = 0; d < q; d++)   // to iterate the columns
            {
                printf("%d\t", second[c][d]);
            }
            printf("\n");
        }

        for(c = 0; c < m; c++)   // to iterate the rows
        {
            for(d = 0; d < q; d++)   // to iterate the columns
            {
                for(k = 0; k < p; k++)
                {
                    sum = sum + first[c][k]*second[k][d];
                }
            pro[c][d] = sum;    // resultant element of pro after multiplication
            sum = 0;    // to find the next element from scratch
            }
        }

        // printing the elements of the product matrix
        printf("\n\nThe multiplication of the two entered matrices is: \n\n");
        for(c = 0; c < m; c++)   // to iterate the rows
        {
            for(d = 0; d < q; d++)   // to iterate the columns
            {
                printf("%d\t", pro[c][d]);
            }
            printf("\n"); // to take the control to the next row
        }
    }
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program for Matrix Multiplication



指针

C 程序:指针基础

原文:https://www.studytonight.com/c/programs/pointer/simple-pointer-program

需要记住的几个要点:

  • *用于访问指针变量中存储的值。
  • &用于存储给定变量的地址。

这里是 C 语言教程关于 C 中的指针→C 中的指针

下面是一个简单的指针程序。

int *p;是指针变量声明,其中p是指向int变量的指针,即它存储整数的位置。

%x是打印十六进制值的格式说明符。它通常用于打印位置。

#include <stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int var = 24;   // actual variable declaration
    int *p;

    p = &var;   // storing address of int variable var in pointer p

    printf("\n\nAddress of var variable is: %x \n\n", &var);

    // address stored in pointer variable
    printf("\n\nAddress stored in pointer variable p is: %x", p);

    // access the value using the pointer variable
    printf("\n\nValue of var variable or the value stored at address p is   %d ", *p);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Simple C Program for Pointer



C 程序:将malloc()用于动态内存分配

原文:https://www.studytonight.com/c/programs/pointer/memory-management-program

下面是一个使用malloc()动态分配内存和使用free()清空内存空间的程序。

sizeof()返回任何数据类型占用的字节数,在本例中是一个整数。

#include <stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n, i, *ptr, sum = 0;

    printf("\n\nEnter number of elements: ");
    scanf("%d", &n);

    // dynamic memory allocation using malloc()
    ptr = (int *) malloc(n*sizeof(int));

    if(ptr == NULL) // if empty array
    {
        printf("\n\nError! Memory not allocated\n");
        return 0;   // end of program
    }

    printf("\n\nEnter elements of array: \n\n");
    for(i = 0; i < n; i++)
    {
        // storing elements at contiguous memory locations
        scanf("%d", ptr+i);    
        sum = sum + *(ptr + i);
    }

    // printing the array elements using pointer to the location
    printf("\n\nThe elements of the array are: ");
    for(i = 0; i < n; i++)
    {
        printf("%d  ",ptr[i]);    // ptr[i] is same as *(ptr + i)
    }

    /* 
        freeing memory of ptr allocated by malloc 
        using the free() method
    */
    free(ptr);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Basic Memory Management/allocation Program using malloc and free in c language



C 程序:访问整型指针数组

原文:https://www.studytonight.com/c/programs/pointer/array-of-pointers

下面是一个访问int指针数组的程序:

#include <stdio.h>
/* 
    Global declaration. 
    Value of a const variable cannot be changed 
    throughout the execution of program
*/
const int MAX = 5;  

int main()
{

    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int var[]={10, 20, 30, 40, 50}; // initializing an array(here var) of int pointers
    int i = 0;

    /*
        ptr is an array of int pointers i.e. 
        it stores the address of each array element
    */
    int *ptr[MAX];

    for(i = 0; i < MAX; i++)
    {
        /*
            Assign the address of each of the array 
            element to the ptr array
        */
        ptr[i] = &var[i];
    }

    for(i = 0; i < MAX; i++)
    {
        /*
            ptr[i] stores the address of the element var[i]. 
            Hence, *ptr[i] returns the value of the element 
            stored at location ptr[i]
        */
        printf("Value of var[%d] = %i\n\n", i, *ptr[i]);
    }

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Array of Int Pointer

解释:

printf("Value of var[%d] = %i\n\n", i, *ptr[i]);
  • 这里ptr[i]存储元素var[i]的地址。因此,*ptr[i]返回存储在位置var[i]的元素的值。

访问char指针数组的程序

char指针数组仅使用每个字符串的第一个字符(基址)的地址来访问完整的字符串。

下面是一个访问char指针数组的程序。

#include <stdio.h>
const int MAX = 4;  // Global declaration.

int main()
{

	printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char *names[] = {"Google", "Amazon", "Facebook", "Apple"}; // initializing an array(here names) of char pointers
    int i = 0;

    for(i = 0; i < MAX; i++)
    {
        printf("Value of names[%d] = %s\n\n", i, names[i]);
    }

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

program to sotre and access the Array of Char Pointer

解释:

printf("Value of names[%d] = %s\n\n",i,names[i]);
  • 该语句用于仅使用指向names数组每个元素的第一个字符的指针来打印完整的名称。

C 程序:通过递增指针来访问数组元素(遍历数组)

原文:https://www.studytonight.com/c/programs/pointer/pointer-increment-and-decrement

数组的名称是指数组的基地址

这里我们有一个教程来了解指针算法是如何工作的?

下面是一个使用指针增量访问数组元素的程序。

#include <stdio.h>

const int MAX = 3;  // Global declaration
int main()
{
	printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
	int var[] = {100, 200, 300};
    int i, *ptr;

    /* 
        storing address of the first element 
        of the array in pointer variable
    */
    ptr = var;

    for(i = 0; i < MAX; i++)
    {
        printf("\n\n\nAddress of var[%d] = %x ", i, ptr);
        printf("\nValue of var[%d] = %d ", i, *ptr);

       // move to the next location
        ptr++;
    }
	printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

traversing array with Pointer Increment


通过递减指针遍历数组元素

下面是一个使用指针递减来访问数组元素的程序。

#include <stdio.h>

const int MAX = 3;  // Global declaration
int main()
{
	printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
	int var[] = {100, 200, 300};
    int i, *ptr;

    /* 
        storing address of the last element 
        of the array in pointer variable
    */
    ptr = &var[MAX-1];

	for(i = MAX; i > 0; i--)
    {
    	printf("\n\n\nAddress of var[%d] = %x ", i, ptr);
        printf("\nValue of var[%d] = %d ", i, *ptr);

		// move to the previous location
        ptr--;
	}
	printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

traversing array elements using Pointer Decrement in C language



C 程序:指针比较

原文:https://www.studytonight.com/c/programs/pointer/pointer-comparison-program

在 C 语言中,如果两个指针指向同一个数组,就可以对指针进行比较。

所有关系运算符都可以用于指针比较,但指针不能相乘或相除。

下面是一个相同类型指针的指针比较程序:

#include <stdio.h>

int main()
{
    int *ptrA,*ptrB;

    ptrA = (int *)1;
    ptrB = (int *)2;

    if(ptr2 > ptr1)
        printf("PtrB is greater than ptrA");

return(0);
}

下面是针对不同类型指针的指针比较程序:

#include <stdio.h>

int main()
{
    int *ptrA;
    float *ptrB;

    ptrA = (int *)1000;
    ptrB = (float *)2000;

    if(ptrB > ptrA)
       printf("PtrB is greater than ptrA");

    return(0);
}


C 程序:指向指针的指针

原文:https://www.studytonight.com/c/programs/pointer/pointer-to-a-pointer

指针变量存储值的地址。类似地,指向指针的指针存储指针变量的地址。利用**执行指向指针的指针。

下面是一个指向指针的程序。

int var;是存储值的整数变量。

int *ptr;是存储整数变量地址的指针变量。

int **pptr;是指向指针变量的指针,该指针变量存储指针变量的地址。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int var;
    int *ptr;
    int **pptr;

    var = 50;

    // take the address of the variable var
    ptr = &var;

    // taking the address of ptr using address of operator-&
    pptr = &ptr;

    // take the value using the pptr
    printf("\n\nValue of var = %d\n\n", var);

    printf("\n\nValue available at *ptr = %d\n\n", *ptr);

    printf("\n\nValue available at **pptr = %d\n\n", **pptr);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Pointer to pointer C Program



C 程序:使用指针连接字符串

原文:https://www.studytonight.com/c/programs/pointer/concatenate-strings-using-pointer

下面是一个使用指针连接字符串的程序:

#include <stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    char aa[100], bb[100];

    printf("\nEnter the first string: ");
    gets(aa);   // inputting first string

    printf("\nEnter the second string to be concatenated: ");
    gets(bb);   // inputting second string

    char *a = aa;
    char *b = bb;

    // pointing to the end of the 1st string
    while(*a)   // till it doesn't point to NULL-till string is not empty
    {
        a++;    // point to the next letter of the string
    }
    while(*b)   // till second string is not empty
    {
        *a = *b;
        b++;
        a++;
    }
    *a = '\0';  // string must end with '\0'
    printf("\n\n\nThe string after concatenation is: %s ", aa);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to Concatenate Strings using Pointer in C language

解释:

  • char *a = aa;中,a是指向字符数组的指针,并存储aa的基址。
  • char *b = bb;中,b是指向字符数组的指针,并存储bb的基址。
  • *a = *b;在第一个的末尾存储第二个的基址。


C 程序:使用指针反转字符串

原文:https://www.studytonight.com/c/programs/pointer/reverse-a-string-using-pointer

下面是一个使用指针反转字符串的程序:

#include <stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char str[100];
    char rev[100];
    char *sptr = str; // sptr stores the base address of the str
    char *rptr = rev; // rptr stores the base address of the reverse

    int i = -1;

    printf("\n\nEnter a string: ");
    scanf("%s", str);

    // storing the ending address of str in sptr
    while(*sptr)
    {
        sptr++;
        i++; // i is the index of the end location
    }

    // storing the string str in rev in reverse order
    while(i >= 0)
    {
        /*
            First decrementing then using as it stores 
            the location after the end location due to above while loop
        */
        sptr--; 
        *rptr = *sptr;  // storing the value in sptr in rptr
        rptr++; // pointing to next location
        i--;    // decrementing the index
    }
    /*
        String should always end with '\0' so explicitly 
        putting it at the end of the string
    */
    *rptr = '\0'; 
    rptr = rev; // restoring the base address of the reverse string

    // storing the reverse string in the original string
    while(*rptr)
    {
        *sptr = *rptr;
        sptr++;
        rptr++;
    }

    // printing the reverse string
    printf("\n\nReverse of the string is: %s ", str);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Reversing a String using Pointer



C 程序:使用指针交换两个数字

原文:https://www.studytonight.com/c/programs/pointer/swapping-two-numbers-using-pointers

下面是一个用指针交换两个数字的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int a, b;
    int *ptra, *ptrb;
    int temp;

    printf("Enter value for a: ");
    scanf("%d", &a);

    printf("\n\nEnter value for b: ");
    scanf("%d", &b);

    printf("\n\nThe values before swapping are: a = %d     b = %d", a, b);

    ptra = &a;    // to store the location of a
    ptrb = &b;    // to store the location of b

    temp = *ptra;   // temp stores the value at location ptra
    *ptra = *ptrb;  // assigning value at location  ptrb to ptra
    *ptrb = temp;   // assign value of themp to  the variable at location ptrb

    printf("\n\nThe values after swapping are: a = %d    b = %d", a, b);

    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;

}

输出:

Program for Swapping Two Numbers using Pointers



C 程序:指向函数的指针

原文:https://www.studytonight.com/c/programs/pointer/pointer-to-a-function

下面是一个指向函数的程序。

下面是 C 语言教程,解释带有函数的指针→ 指向函数的指针

#include<stdio.h>

int func(int a, int b)  // function definition
{
    printf("\n\n a = %d \n", a);
    printf("\n\n b = %d \n", b);
}

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    // function pointer
    int(*fptr)(int , int);

    // assign address to function pointer
    fptr = func;

    // function calling
    func(2,3);
    fptr(2,3);  // calling a function referring to pointer to a function

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program for Pointer to a function



C 程序:空指针

原文:https://www.studytonight.com/c/programs/pointer/null-pointer-program

空指针是指针的特殊保留值。任何类型的指针都有这个保留值。形式上,每个特定的指针类型 (int *、char *、等等)都有自己专用的空指针值。从概念上讲,当指针有空值时,它并不指向任何地方。

Void 指针是一种特定的指针类型。void *它是指向存储器中某个数据位置的指针,没有任何特定的类型。

空指针是一个值,而空指针是一个类型。

下面是一个空指针的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int *ptr = NULL;    // ptr is a NULL pointer

    printf("\n\n The value of ptr is: %x ", ptr);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program example for Null Pointer



递归的概念

C 程序:递归相加两个数

原文:https://www.studytonight.com/c/programs/recursion/adding-two-numbers-using-recursion

下面是一个用递归将两个数相加的程序。

#include<stdio.h>

int y;

/*
    Function to add two numbers and
    return the result
*/
int add(int m, int n)
{
    if(n == 0)
        return m;

    /*
        Recursion: adding 1, n times and 
        then at the end adding m to it
    */
    y = add(m, n-1) + 1;
    return y;   // return the result
}

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int a, b, r;
    printf("Enter the two numbers:\n");
    scanf("%d%d", &a, &b);
    r = add(a, b);     // function call
    printf("\n\nSum of two numbers is: %d\n\n", r);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program to Add two numbers using recursion



C 程序:使用递归求一个数的阶乘

原文:https://www.studytonight.com/c/programs/recursion/factorial-using-recursion

下面是一个用递归求给定数的阶乘的程序。

#include<stdio.h>
// declaring the function
int fact(int);

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int num, f;
    printf("\n\nEnter a number: ");
    scanf("%d", &num);
    f= fact(num);
    printf("\n\nFactorial of  %d is  %d\n\n", num, f);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

int fact(int aj)
{
    if(aj==1 || aj==0)
        return 1;
    else
        return (aj*fact(aj-1));
}

输出:

Program to find Factorial using recursion



C 程序:使用递归打印斐波那契数列

原文:https://www.studytonight.com/c/programs/recursion/fibonacci-series-using-recursion

斐波那契数列被定义为一个数列,其中每个数字是前面两个数字的和,1,1 是数列的前两个元素。

static关键字仅用于初始化变量一次。

下面是一个用递归打印斐波那契数列的程序。

#include<stdio.h>
// declaring the function
void printFibo(int );

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int k, n;
    long int i = 0, j = 1;
    printf("Enter the length of the Fibonacci series: ");
    scanf("%d", &n);
    printf("\n\nfirst %d terms of Fibonacci series are:\n\n\n",n);
    printf("%d ", 1);
    printFibo(n);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

void printFibo(int aj)
{
    static long int first = 0, second = 1, sum;
    if(aj > 1)
    {
        sum = first + second;
        first = second;
        second = sum;
        printf("%ld ", sum);
        printFibo(aj-1);    // recursive call
    }
    else
    {
        // after the elements, for line break
        printf("\n\n\n");
    }
}

输出:

Fibonacci Series using recursion



C 程序:计算前N个数和

原文:https://www.studytonight.com/c/programs/recursion/sum-of-first-n-numbers

下面是一个用递归求前n数之和的程序,其中n的值由用户提供。

#include<stdio.h>
// declaring the recursive function
int getSum(int);

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n, sum;
    printf("\n\nEnter the range of n: ");
    scanf("%d", &n);
    sum = getSum(n);
    printf("\n\nThe sum of first %d numbers is %d\n", n, sum);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

// function definition
int getSum(int aj)
{
    /*
        static variables hold their values
        till the end of the program
    */
    static int sum = 0;
    if(aj > 0)
    {
        sum = sum + aj;
        getSum(aj-1);
    }
    return sum ;
}

输出:

C program for Sum of first n numbers



C 程序:使用递归求数字和

原文:https://www.studytonight.com/c/programs/recursion/sum-of-digits-using-recursion

下面是一个用递归求给定数字的总和的程序。

#include<stdio.h>
#include<conio.h>

//declaring the recursive function
int sumOfDigit(int num);

void main()
{
    int num, sum;
    clrscr();
    printf("Enter a number:\t");
    scanf("%d", &num);
    sum = sumOfDigit(num);
    printf("The sum of digits of %d is: %d", num, sum);
    getch();
}

int sumOfDigit(int num)
{
    int s, a;
    s = s + (num%10);
    a = num/10;
    if(a > 0)
    {
        sumOfDigit(a);
    }
    return s;
}

输入一个数字:108 108 的位数总和是:9



C 程序:使用递归检查回文

原文:https://www.studytonight.com/c/programs/recursion/palindrome-using-recursion

回文是一个序列,如果颠倒过来看起来与原始序列相同,例如:abba、level、999 等。

下面是一个简单的 C 程序,使用递归来判断用户输入的数字是否是回文:

#include<stdio.h>

// declaring the recursive function
int isPal(int );

/*
    global declaration to use the same value 
    in both the functions
*/
int n;

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int palindrome;
    printf("\n\nEnter a number to check for Palindrome: ");
    scanf("%d", &n);
    palindrome = isPal(n);
    if(palindrome == 1)
        printf("\n\n\n%d is palindrome\n\n", n);
    else
        printf("\n\n\n%d is not palindrome\n\n", n);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

int isPal(int aj)
{
    static int sum = 0;
    if(aj != 0)
    {
        sum = sum *10 + aj%10;
        isPal(aj/10);   // recursive call same as while(n!=0) using loop
    }
    else if(sum == n)
        return 1;
    else
        return 0;
}

输出:

Progrm to find Palindrome using recursion



C 程序:使用递归计算N的幂

原文:https://www.studytonight.com/c/programs/recursion/power-of-n-using-recursion

下面是一个计算给定数字的结果的程序,使用递归上升到n的幂。

#include<stdio.h>

// function prototype declaration
int power(int n1, int n2);

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int base, exp;
    printf("Enter base number: ");
    scanf("%d", &base);
    printf("\n\nEnter Power factor: ");
    scanf("%d", &exp);
    printf("\n\n\n\t\t\t%d^%d = %d", base, exp, power(base, exp));
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

int power(int b, int e)
{
    if(e == 0)
        return 1;

    return (b*power(b, e-1));
}

输出:

Program to find Power of N using recursion



C 程序:使用递归寻找数组中最大元素

原文:https://www.studytonight.com/c/programs/recursion/largest-array-element-using-recursion

下面是一个使用递归寻找给定数组中最大数组元素的程序。

#define用于初始化一个更像常量的值。

#include<stdio.h>

#define MAX 100

int getMaxElement(int []);  // takes array of int as parameter
int size;

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int arr[MAX], max, i;
    printf("\n\nEnter the size of the array: ");
    scanf("%d", &size);
    printf("\n\nEnter %d elements\n\n", size);

    for(i = 0; i < size; i++)
    {
        scanf("%d", &arr[i]);
    }

    max = getMaxElement(arr);   // passing the complete array as parameter
    printf("\n\nLargest element of the array is %d\n\n", max);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

int getMaxElement(int a[])
{
    static int i = 0, max =- 9999;  // static int max=a[0] is invalid
    if(i < size)   // till the last element
    {
        if(max < a[i])
        max = a[i];

        i++;    // to check the next element in the next iteration
        getMaxElement(a);   // recursive call
    }
    return max;
}

输出:

Program to find Largest array element using recursion



C 程序:使用递归求一个数是质数还是合数

原文:https://www.studytonight.com/c/programs/recursion/prime-or-composite-using-recursion

  • 质数:只能被 1 和自身整除的数。
  • 复合数:不是质数的数。

注: 1 既不是质数,也不是复合数。

下面是一个程序,使用递归查找用户输入的数字是质数还是复合数。

#include<stdio.h>

// declaring the recursive function
int isPrime(int, int);

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int num, prime;
    printf("Enter a positive number to check if Prime: ");
    scanf("%d", &num);
    prime = isPrime(num, num/2);
    if(prime == 1)
    {
        printf("\n\n%d is a prime number\n\n", num);
    }
    else
    {
        printf("\n\n%d is a Composite number\n\n", num);
    }
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

// function definition
int isPrime(int n, int i)
{
    if(i == 1)
        return 1;   // return statement terminates the recursive funtion
    else
    {
        if(n%i == 0)
            return 0;
        else
            isPrime(n, i-1);    // recursive call not using return statement
    }
}

输出:

Program to find whether a number is Prime or Composite using recursion



C 程序:使用递归求两个数的 LCM

原文:https://www.studytonight.com/c/programs/recursion/lcm-of-two-numbers-using-recursion

LCM: 两个数的最小公倍数是两个数的公倍数。

下面是一个用递归求两个数 LCM 的程序。

#include<stdio.h>

int find_lcm(int, int);   // function prototype declaration

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int a, b, lcm;
    printf("\n\nEnter 2 integers to find LCM of:\n");
    scanf("%d%d", &a, &b);
    lcm = find_lcm(a,b);    // function call
    printf("\n\n LCM of %d and %d is: %d\n\n", a, b, lcm);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

int find_lcm(int a, int b)  // function definition
{
    /*
        static variable is initialized only once 
        for each function call
    */
    static int temp = 1;    
    if(temp%a == 0 && temp%b == 0)
    {
        return temp;
    }
    else
    {
        temp++;
        find_lcm(a,b);
        return temp;
    }
}

输出:

C Program to find LCM of numbers using recursion



C 程序:使用递归求两个数的 GCD

原文:https://www.studytonight.com/c/programs/recursion/gcd-of-two-numbers-using-recursion

两个数的最大公约数(GCD) 是两个数相除的数。

下面是一个程序,以 GCD 的两个用户输入数字使用递归。

#include<stdio.h>

// declaring the recursive function
int find_gcd(int , int );

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int a, b, gcd;
    printf("\n\nEnter two numbers to find GCD of \n");
    scanf("%d%d", &a, &b);
    gcd = find_gcd(a, b);
    printf("\n\nGCD of %d and %d is: %d\n\n", a, b, gcd);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

// defining the function
int find_gcd(int x, int y)
{
    if(x > y)
        find_gcd(x-y, y);

    else if(y > x)
        find_gcd(x, y-x);
    else
    return x;
}

输出:

C Program output for GCD of two numbers using recursion



C 程序:使用递归反转字符串

原文:https://www.studytonight.com/c/programs/recursion/reverse-a-string-using-recursion

下面是一个用 C 语言递归反转用户输入字符串的程序。

#include<stdio.h>
#include<conio.h>

// declaring recursive function
char* reverse(char* str);

void main()
{
    int i, j, k;
    char str[100];
    char *rev;
    printf("Enter the string:\t");
    scanf("%s", str);
    printf("The original string is: %s\n", str);
    rev = reverse(str);
    printf("The reversed string is: %s\n", rev);
    getch();
}

// defining the function
char* reverse(char *str)
{
    static int i = 0;
    static char rev[100];
    if(*str)
    {
        reverse(str+1);
        rev[i++] = *str;
    }
    return rev;
}

输入字符串:今晚学习原始字符串是:今晚学习反向字符串是:开始



文件和流

C 程序:打印目录中所有文件名称

原文:https://www.studytonight.com/c/programs/files-and-streams/program-to-list-files-in-directory

dirent.h 头文件包含与目录流相关的变量和函数。

下面是一个打印目录中所有文件名称的程序。

#include<stdio.h>
#include<dirent.h>

int main(void)
{
    DIR *d;
    struct dirent *dir;
    d = opendir(".");
    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            printf("%s\n", dir->d_name);
        }
        closedir(d);
    }
    return(0);
}

File1.txt 文件 2.txt 文件 3.txt 文件 4.txt 文件 5.txt 文件 6.txt 文件 7.txt

我们还可以将目录名作为用户的输入,也可以创建一个简单的 C 程序来搜索目录中的特定文件。



C 程序:查找任何文件大小

原文:https://www.studytonight.com/c/programs/files-and-streams/program-to-find-size-of-file

我们将使用fseek()ftell()函数来查找文件的大小。还有其他方法可以找到文件大小,比如循环整个文件内容并找出大小,但是文件处理功能使它变得容易得多。

下面是一个查找文件大小的程序。

下面是 C 语言教程,讲解 C 语言中的文件处理→C 语言中的文件处理

#include<stdio.h>
#include<conio.h>

void main()
{
    FILE *fp;
    char ch;
    int size = 0;

    fp = fopen("MyFile.txt", "r");
    if (fp == NULL)
    {
        printf("\nFile unable to open...");
    }
    else
    {
        printf("\nFile opened...");
    }
    fseek(fp, 0, 2);    /* File pointer at the end of file */
    size = ftell(fp);   /* Take a position of file pointer in size variable */
    printf("The size of given file is: %d\n", size);
    fclose(fp);
}


C 程序:创建文件并在其中写入数据

原文:https://www.studytonight.com/c/programs/files-and-streams/program-to-write-in-file

下面是一个创建新文件并在其中存储信息的程序。

#include<stdio.h>
#include<conio.h>

void main()
{
    FILE *fptr;
    char name[20];
    int age;
    float salary;

    /* open for writing */
    fptr = fopen("emp.txt", "w");

    if (fptr == NULL)
    {
        printf("File does not exist.\n");
        return;
    }
    printf("Enter the name:\n");
    scanf("%s", name);
    fprintf(fptr, "Name  = %s\n", name);

    printf("Enter the age:\n");
    scanf("%d", &age);
    fprintf(fptr, "Age  = %d\n", age);

    printf("Enter the salary:\n");
    scanf("%f", &salary);
    fprintf(fptr, "Salary  = %.2f\n", salary);

    fclose(fptr);
}

您可以在文件中添加任何信息,就像我们为一些员工添加了姓名、年龄和工资一样,您可以根据自己的要求更改程序。

您甚至可以初始化一个for循环,将多个员工的详细信息添加到文件中。你所要做的就是,向用户询问需要存储数据的员工数量,多次运行for循环,并继续将数据添加到文件中。



C 程序:反转文件内容

原文:https://www.studytonight.com/c/programs/files-and-streams/program-to-reverse-content-of-file

下面是一个反转文件内容的程序。

下面是 C 语言教程,讲解 C 语言中的文件处理→C 语言中的文件处理

#include<stdio.h>
#include<errno.h>

/* 
    to count the total number of characters 
    inside the source file
*/
long count_characters(FILE *);

void main()
{
    int i;
    long cnt;
    char ch, ch1;
    FILE *fp1, *fp2;

    if (fp1 = fopen("File_1.txt", "r"))
    {
        printf("The FILE has been opened...\n");
        fp2 = fopen("File_2.txt", "w");
        cnt = count_characters(fp1);

        /*
            Make the pointer fp1 to point at the
            last character of the file
        */
        fseek(fp1, -1L, 2);
        printf("Number of characters to be copied %d\n", ftell(fp1));

        while (cnt)
        {
            ch = fgetc(fp1);
            fputc(ch, fp2);
            fseek(fp1, -2L, 1); // shifts the pointer to the previous character
            cnt--;
        }
        printf("\n**File copied successfully in reverse order**\n");
    }
    else
    {
        perror("Error occured\n");
    }
    fclose(fp1);
    fclose(fp2);
}

/*
    Count the total number of characters in the file
    that *f points to
*/
long count_characters(FILE *f)
{
    fseek(f, -1L, 2);
    /*
        returns the position of the 
        last element of the file
    */
    long last_pos = ftell(f);
    last_pos++;
    return last_pos;
}


C 程序:将一个文件的内容复制到另一个文件

原文:https://www.studytonight.com/c/programs/files-and-streams/program-copy-file-to-another-file

我们已经知道如何打开文件、读取文件内容和写入文件。所以在这个程序中,我们将从一个文件中读取,同时写入另一个文件,直到我们到达第一个文件的末尾。

#include<stdio.h>
#include<stdio.h>

void main()
{
    /*
        File_1.txt is the file with content and,
        File_2.txt is the file in which content of File_1
        will be copied.
    */
    FILE *fp1, *fp2;
    char ch;
    int pos;

    if ((fp1 = fopen("File_1.txt", "r")) == NULL)
    {
        printf("\nFile cannot be opened.");
        return;
    }
    else
    {
        printf("\nFile opened for copy...\n ");
    }
    fp2 = fopen("File_2.txt", "w");
    fseek(fp1, 0L, SEEK_END);   // File pointer at end of file
    pos = ftell(fp1);
    fseek(fp1, 0L, SEEK_SET);   // File pointer set at start
    while (pos--)
    {
        ch = fgetc(fp1);    // Copying file character by character
        fputc(ch, fp2);
    }
    fcloseall();
}


杂项 I

C 程序:识别闰年

原文:https://www.studytonight.com/c/programs/important-concepts/identify-a-leap-year

下面是识别用户输入的年份是否是闰年的程序。

%nd用于对齐文本,表示n空格内的值,剩余空格为前导。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int year;

    printf("Enter the year to check if it is a leap year: ");
    scanf("%d", &year);

    // divisible by 4, 100 and 400
    if(year%400 == 0)
        printf("\n\n%d is a leap year\n", year);

    // divisible by 100 and 4 and not divisible by 400
    else if(year%100 == 0)
        printf("\n\n%d is not a leap year\n", year);

    // divisible only by 4 and not by 100
    else if(year%4 == 0)
    {   
        /*
            %0nd is used to represent the number 
            in n digits with leading 0's
        */
        printf("\n\n%07d is a leap year\n", year); 
    }
    // not divisible by 4
    else
        printf("\n\n%d is not a leap year\n", year);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Identify Leap Year Program



C 程序:求三个数中最大值

原文:https://www.studytonight.com/c/programs/important-concepts/largest-of-three-numbers

下面是一个在三个用户输入数字中找出最大数字的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    float a, b, c;

    printf("Enter 3 numbers:\n\n");
    scanf("%f%f%f", &a, &b, &c);

    if(a >= b && a >= c)
    {
        /*
            %.3f prints the floating number 
            upto 3 decimal places
        */
        printf("\n\nLargest number = %.3f ", a);
    }
    else if(b >= a && b >= c)
    {
        printf("\n\nLargest number is = %.3f", b);
    }
    else
    {
        printf("\n\nLargest number is = %.3f", c);
    }

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program output for Largest of three numbers



C 程序:在三个用户输入数字中找出第二大数字

原文:https://www.studytonight.com/c/programs/important-concepts/second-largest-among-three-numbers

.2lf将数字限制在小数点后两位

下面是一个使用嵌套 if-else 循环从三个用户输入数字中找出第二大数字的程序:

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    double a, b, c;

    printf("Enter 3 numbers:\n");
    scanf("%lf%lf%lf", &a, &b, &c);  //lf is a format specifier to take double as input

    // a is the largest
    if(a >= b && a >= c)
    {
        if(b >= c)
        {
            /*
                .2lf restricts the number till 
                2 decimal places
            */
            printf("\n\n%.2lf is the 2nd largest number\n", b);
        }
        else
        {
            printf("\n\n%.2lf is the 2nd largest number\n", c);
        }
    }
    else if(b >= a && b >= c)
    {
        if(a >= c)
        {
            printf("\n\n%.2lf is the 2nd largest number\n",a);
        }
        else
        {
            printf("\n\n%.2lf is the 2nd largest number\n",c);
        }
    }

    // c is the largest number of the three
    else if(a >= b)
    {
        printf("\n\n%.2lf is the 2nd largest number\n", a);
    else
    {
        printf("\n\n%.2lf is the 2nd largest number\n", b);
    }

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Second Largest among three numbers



C 程序:使用指针相加两个用户输入数字

原文:https://www.studytonight.com/c/programs/important-concepts/adding-two-numbers-using-pointers

需要记住的几个要点:

  • *运算符在给定的地址位置返回的值。
  • &运算符将给定值返回的地址。

下面是一个用指针加两个数字的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int first, second, *p , *q, sum;
    printf("Enter two integers to add using pointers:\n");
    scanf("%d%d", &first, &second);
    p = &first;
    q = &second;
    sum = *p + *q;
    printf("\n\nThe sum of the entered numbers is: %d", sum);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program output for Adding two numbers using pointers



C 程序:求圆的面积和周长

原文:https://www.studytonight.com/c/programs/important-concepts/area-and-circumference-of-a-circle

下面是一个求圆的面积和周长的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int rad;
    float PI = 3.14, area, ci;
    printf("\nEnter the radius of the circle: ");
    scanf("%d", &rad);
    area = PI*rad*rad;
    printf("\n\n\n Area of the circle is: %f ", area);
    ci = 2*PI*rad;
    printf("\n\n\n Circumference of the circle is: %f", ci);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program output for Area and Circumference of a Circle



C 程序:使用底和高求三角形面积

原文:https://www.studytonight.com/c/programs/important-concepts/area-of-triangle

下面是一个利用底和高来计算三角形面积的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int h, b;
    float area;
    printf("\n\nEnter the height of the Triangle: ");
    scanf("%d", &h);
    printf("\n\nEnter the base of the Triangle: ");
    scanf("%d", &b);

    /*
        Formula for the area of the triangle = (height x base)/2

        Also, typecasting denominator from int to float 
        to get the output in float
    */
    area = (h*b)/(float)2;
    printf("\n\n\nThe area of the triangle is: %f", area);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program output for Area of Triangle using Base and Height


用赫伦公式求三角形面积的程序

下面是一个用 heron 公式求三角形面积的程序。

#include<stdio.h>
#include<math.h>  // to use sqrt() function

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    double a, b, c, area, s;
    printf("\nEnter the sides of the triangle:\n\n");
    scanf("%lf%lf%lf", &a, &b, &c);   // lf is format specifier for double input

    s = (a+b+c)/2;
    /*
        sqrt is a predefined system function that 
        returns the square root of the input value
    */
    area = sqrt(s*(s-a)*(s-b)*(s-c));
    printf("\n\n\n\nThe area of the Triangle calculated using Heron's formula is: %lf", area);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program output for Area of Triangle using Heron's formula



C 程序:展示基本算术运算和类型转换作用

原文:https://www.studytonight.com/c/programs/important-concepts/basic-arithmetic-operations

这里我们有两个简单的程序来展示各种基本的算术运算,以及在我们的程序中显式使用和不使用类型转换的情况下,C 语言是如何处理类型转换的。

没有类型转换的算术运算

下面是一个不用类型转换就能完成基本算术运算的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int a, b, add, subtract, multiply;
    float divide;

    printf("Enter two integers: \n");
    scanf("%d%d", &a, &b);

    add = a+b;
    subtract = a-b;
    multiply = a*b;
    divide = a/b;

    printf("\nAddition of the numbers = %d\n", add);
    printf("Subtraction of 2nd number from 1st = %d\n", subtract);
    printf("Multiplication of the numbers = %d\n", multiply);
    printf("Dividing 1st number from 2nd = %f\n", divide);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program output for basic Arithmetic Operations without Typecasting


具有类型转换的算术运算

C 语言确实隐式处理类型转换,但是用户也可以在他们的程序中处理它。

下面是一个使用类型转换执行基本算术运算的简单程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int a, b, add, subtract, multiply, remainder;
    float divide;

    printf("Enter two integers: \n");
    scanf("%d%d", &a, &b);

    add = a+b;
    subtract = a-b;
    multiply = a*b;
    divide = a/(float)b;
    remainder = a%b;

    printf("\n\nAddition of the numbers = %d\n", add);
    printf("\nSubtraction of 2nd number from 1st = %d\n", subtract);
    printf("\nMultiplication of the numbers = %d\n", multiply);
    printf("\nDividing 1st number from 2nd = %f\n", divide);
    printf("\nRemainder on Dividing 1st number by 2nd is %d\n", remainder);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program output for Arithmetic Operations with Typecasting



C 程序:展示各种数字系统之间转换

原文:https://www.studytonight.com/c/programs/important-concepts/conversion-between-number-system

在这里,我们有多个程序来展示各种数字系统之间的转换,如二进制到十进制、八进制到十进制、十进制到二进制,我们甚至会使用递归来帮助您理解递归如何在这些程序中使用。让我们开始吧。


将二进制等价转换为十进制等价的程序

下面是一个将二进制数转换成十进制数的程序。

#include<stdio.h>
#include<math.h>

// Function prototype declaration
int binary_decimal(int n); 

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n;
    char c;
    printf("Enter the binary number: ");
    scanf("%d", &n);
    printf("\n\n\nThe decimal equivalent of %d is  %d\n\n", n, binary_decimal(n)); // function calling
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

// Definition of the function to convert binary to decimal.
int binary_decimal(int n)
{
    int decimal = 0, i = 0, rem;
    while(n != 0)
    {
        rem = n%10;   // gives the digit at the units place
        n = n/10; // gives the number excluding its units digit
        /*
            pow is a system defined function that takes 
            two integers as input parameters
        */
        decimal += rem*pow(2, i++);
    }
    /*
        return the decimal equivalent of the input 
        binary number to the function call
    */
    return decimal; 
}

输出:

C Program output for Binary to Decimal equivalent Program


将八进制转换为十进制的程序

下面是一个将八进制数转换成十进制数的程序。

%ld是输入长值的格式说明符。

#include<stdio.h>
#include<stdio.h>
#include<math.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    long int octal, val, decimal = 0;
    int i = 0;
    printf("Enter any octal number: ");
    scanf("%ld", &val);
    octal = val;
    while(octal != 0)
    {
        /*
            i++ is post increment, where value is 
            first assigned and then incremented
        */
      decimal += (octal % 10)*pow(8, i++);
      octal/=10;    // same as octal=octal/10
    }
    printf("\n\n\nEquivalent decimal value of %ld is %ld\n\n\n", val, decimal);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program output for conversion of Octal to Decimal Program


将十进制等价转换为二进制等价的程序

下面是一个不用递归就能把十进制数转换成二进制数的程序。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n,c,k;
    printf("Enter an integer in decimal number system: ");
    scanf("%d", &n);

    // In 31 bit format
    printf("\n\n\nThe binary equivalent of decimal value %d is:", n);

    for(c = 31; c >= 0; c--)
    {
        k = n>>c;
        /*
            num&1 = returns true if the last digit of num is 1 
            else false
        */
        if(k&1)
            printf("1");
        else
            printf("0");
    }
    printf("\n");
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program output for converting a number from Decimal to Binary


用递归将十进制等价转换为二进制等价的程序

下面是一个用递归将十进制数转换成二进制数的程序:

#include<stdio.h>

//Function prototype declarations
void decimal_binary(int ); 
void F(int );
void reverse(int );

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int n;
    printf("\n\nEnter an integer in decimal number system: ");
    scanf("%d", &n);

    //In 31 bit format
    printf("\n\nThe binary equivalent of decimal value %d using decimal_binary method is: ", n);

    decimal_binary(n);  // function call

    printf("\n\nThe binary equivalent of decimal value %d using F() method is: ", n);
    F(n);   // function call
    printf("\n\nThe Reverse of the binary representation of value %d is: ", n);
    reverse(n); // function call
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

// function definition
void decimal_binary(int i)
{
    if(i <= 1)
    printf("%d", i);   // to print in up to down format
    else
    {
        decimal_binary(i/2);
        printf("%d", i%2);
    }
}

void F(int j)
{
    if(j/2)
    {
        F(j/2);
    }
    printf("%d", j%2);
}

void reverse(int k)
{
    if(k <= 1)
        printf("%d", k);
    else
    {
        printf("%d", k%2);
        F(k/2);
    }
    printf("\n\n");
}

输出:

C Program output to convert Decimal to Binary using recursion



C 程序:将摄氏温度转换成华氏温度

原文:https://www.studytonight.com/c/programs/important-concepts/celsius-to-fahrenheit

下面是一个从摄氏到华氏的温度转换程序。我们所要做的就是使用程序中的简单公式,即如果温度值以摄氏度为单位,将其乘以1.89/5,并将32加到结果中,这将给出等效的法赫内热值。

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    float celsius, fahrenheit;
    printf("\n\nEnter temperature in Celsius: ");
    scanf("%f", &celsius);

    fahrenheit = (1.8*celsius) + 32;

    printf("\n\n\nTemperature in Fahrenheit is: %f ", fahrenheit);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Program output for conversion of Celsius to Fahrenheit


将摄氏温度转换成华氏温度的程序

要将华氏温度转换为摄氏温度,公式是,从数值中减去32,然后乘以0.55565/9

所以你所要做的就是替换 avove 程序中的转换公式。去吧,你自己试试。


C 程序:计算单利

原文:https://www.studytonight.com/c/programs/important-concepts/simple-interest-program

下面是一个计算给定本金、利率和持续时间的简单利息的程序。

%7.3f表示浮点值用 7 位数字表示,包括小数点后的 3 位数字。

#include<stdio.h>

void main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    float principal_amt, rate, simple_interest;
    int time;
    printf("Enter the value of principal amount, rate and time\n\n\n");
    scanf("%f%f%d", &principal_amt, &rate, &time);

    // considering rate is in percentage
    simple_interest = (principal_amt*rate*time)/100.0;

    // usually used to align text in form of columns in table
    printf("\n\n\t\t\tAmount = Rs.%7.3f\n ", principal_amt);

    printf("\n\n\t\t\tRate = Rs.%7.3f\n ", rate);
    printf("\n\n\t\t\tTime= %d years \n", time);
    printf("\n\n\t\t\tSimple Interest = Rs.%7.3f\n ", simple_interest);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program output for Simple Interest



C 程序:求N个数的 GCD

原文:https://www.studytonight.com/c/programs/important-concepts/greatest-common-divisor-program

下面是一个查找N用户输入数字的 GCD 的程序。

 #include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int x, y =- 1;
    printf("Enter numbers. To exit enter 0\n");
    while(1)    // infinite loop to take input
    {
        scanf("%d", &x);
        if(x < 1)
            break;
        else if(y ==- 1)    // only 1 number entered, its GCD is itself
            y = x;
        else if(x < y)
            y = gcd(x, y);
        else
            y = gcd(y, x);
    }
    printf("\n\n\nGCD of all the entered number is: %d", y);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

// GCD of 2 numbers is calculated at a time
int gcd(int a, int b) 
{
    int i;
    /*
        a is the smallest of the two numbers 
        of which GCD is to be calculated
    */
    for(i = a; i >= 1; i--) 
    {
        // Greatest number that divides both the numbers
        if(a%i == 0 && b%i == 0) 
            break;  // exits the loop
    }
    return i;
}

输出:

C program to find the GCD of N Numbers


用函数求两个数的 GCD 的 C 程序

下面是一个用函数求两个数的 GCD 的程序。

 #include<stdio.h>

int gcd(int c, int d)   // function definition
{
    if(d == 0)
        return c;
    else
        return gcd(d, c%d);
}

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int a, b;
    printf("Enter 2 numbers: \n\n");
    scanf("%d%d", &a, &b);
    printf("\n\nGreatest Common Divisor is: %d", gcd(a, b)); // function calling
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program output to find GCD of Two Numbers Using Function



杂项 II

C 程序:求二次方程根

原文:https://www.studytonight.com/c/programs/important-concepts/finding-roots-of-quadratic-equation

下面是一个求二次方程根的程序。

%.nf用于将一个小数值的值限制到n位小数。

#include<stdio.h>
#include<math.h>  // This is needed to use sqrt() function

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    float a, b, c, determinant, r1, r2, real, imag;
    printf("\n\nEnter coefficients a, b and c: \n\n\n");
    scanf("%f%f%f", &a, &b, &c);

    /*
        mathematical formula to know the 
        nature of the roots
    */
    determinant == b*b - 4*a*c; 

    if(determinant > 0)    // both roots are real
    {
        r1 = (-b + sqrt(determinant))/2*a;  // Brackets are important
        r2 = (-b - sqrt(determinant))/2*a;
        printf("\n\n\nRoots are: %.2f and %.2f ", r1, r2);
    }
    else if(determinant == 0)   // both roots are real and equal
    {
        r1 = r2 = -b/(2*a); // brackets are important
        printf("\n\n\nRoots are: %.2f and %.2f ", r1, r2);
    }
    /*
        Determinant < 0 - both roots are imaginary of the 
        form real + i*imaginary
    */
    else
    {
        real = -b/(2*a);
        imag = sqrt(-determinant)/(2*a);
        printf("\n\n\nRoots are %.2f + i%.2f and %.2f - i%.2f ", real, imag, real, imag);
    }
    printf("\n\n\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program out for Finding Roots of Quadratic Equation



C 程序:检查完全平方

原文:https://www.studytonight.com/c/programs/important-concepts/checking-for-perfect-square

下面是一个检查用户输入的数字是否是一个完全平方的程序。

#include<stdio.h>
int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    // variable declaration
    int i, number;

    // take user input
    printf("Enter a number: ");
    scanf("%d", &number);

    // loop to check number is perfect square or not
    for(i = 0; i <= number; i++)
    {
        if(number == i*i)
        {
            printf("\n\n\n\t\t\t%d is a perfect square\n\n\n", number);

            printf("\n\n\t\t\tCoding is Fun !\n\n\n");
            return 0;   // same as using break in this case to end the program
        }
    }
    printf("\n\n\n\t\t\t%d is not a perfect square\n", number);
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Simple C program to Check a number for Perfect Square



C 程序:计算排列组合

原文:https://www.studytonight.com/c/programs/important-concepts/calculate-nPr-and-nCr

Definition of nPr and nCr

下面是计算nPrnCr的程序。

全球申报范围在整个计划内。

局部声明的范围仅限于函数。

#include<stdio.h>

// function prototype declarations
long factorial(int);
long find_npr(int, int);
long find_ncr(int, int);

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    int n, r;
    long npr, ncr;

    printf("Enter the value of n and r respectively: \n\n");
    scanf("%d%d", &n, &r);

    // function calls
    npr = find_npr(n, r);
    ncr = find_ncr(n, r);

    printf("\n\n\n\t\t%dC%d = %ld\n", n, r, ncr);
    printf("\n\n\t\t%dP%d = %ld\n", n, r, npr);

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

/*
    function definition for nCr
*/
long find_ncr(int a, int b)
{
    return (factorial(a)/(factorial(b)*factorial(a-b)));
}

/*
    function definition for nPr
*/
long find_npr(int a, int b)
{
    return (factorial(a)/factorial(a-b));
}

/*
    recursive function definition for finding 
    factorial of a number
*/
long factorial(int c)
{
    if(c == 1 || c == 0)
        return 1;
    else
        return c*factorial(c-1);
}

输出:

C program output to Calculate nPr and nCr



C 程序:关闭 Windows/Linux 机器

原文:https://www.studytonight.com/c/programs/misc/windows-shutdown-program

这个程序关闭你的电脑系统。stdlib.h的系统功能是运行一个可执行文件 shutdown.exe,它存在于 Windows 7 和 XP 的C:\WINDOWS\system32文件夹中。

下面是一个关闭 Windows 7 的程序。

#include<stdio.h>
#include<stdlib.h>    // to use system() method

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char ch;

    printf("Do you want to shutdown your pc now (y/n)?");
    scanf("%c", &ch);

    if(ch == 'y'|| ch == 'Y')
    {   /*
            /s is used to order the compiler 
            to shutdown the PC
        */
        system("C:\\WINDOWS\\System32\\shutdown /s");
    }

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

执行shutdown.exe时可以使用各种选项,例如可以使用/t选项指定关机发生的秒数。

  • 语法: "shutdown /s /t x";这里 x 是关机的秒数。
  • 示例:默认 30 秒后关机。要立即关机,可以写"shutdown /s /t 0"

如果你希望重启你的电脑,那么你可以使用"shutdown /r"


关闭视窗操作系统的程序

下面是一个关闭 Windows XP 的程序。

#include<stdio.h>
#include<stdlib.h>    // to use system() function

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char ch;

    printf("Do you want to shutdown the PC- (y/n) ?\n");
    scanf("%c", &ch);

    if(ch == 'y' || ch == 'Y')
    {
        system("C:\\WINDOWS\\System32\\shutdown -s");
    }

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}
  • 要立即关机,请使用"C:\\WINDOWS\\System32\\shutdown -s -t 0"。要重启,请使用"-r"代替"-s"
  • 为了更好的理解,请浏览关闭 Windows 7 的程序,其中详细解释了使用 tr代替s

注: A '-' 在 Windows XP 中执行的功能与 Windows 7 情况下 '/' 执行的功能相同。


关闭操作系统的程序

下面是一个关闭 Linux 操作系统的程序。

#include<stdio.h>
#include<stdlib.h>    // to use system() function

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    char ch;

    printf("Do you want to shutdown your pc now(y/n)?");
    scanf("%c", &ch);

    if(ch == 'y' || ch == 'Y')
    system("shutdown -P now");

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}
  • 您需要以用户身份登录才能执行上述程序,否则您将收到关机消息:“需要 root”
    *** '-P'选项指定您想要关闭机器的电源。* 您可以将分钟指定为:shutdown -P "number of minutes"* 如需更多帮助或选项,请在终端输入:man shutdown**


C 程序:没有main()函数

原文:https://www.studytonight.com/c/programs/misc/program-without-main-function

下面是一个没有main()的程序。

在下面的程序中,main()功能在那里,但是使用预处理器隐藏。

第二行可以看到,使用了#define decode()函数,保存m,a,i,n的字符组合,后面跟##m##a##i##n

这里##运算符用于按照使用##提到的顺序合并字符,即main

在第三行#define go decode(m,a,i,n)中,由于我们以相同的顺序指定了字符,decode功能将为go赋值main

#include<stdio.h>
//Need to include the following statements in same manner
#define decode(m,a,i,n) m##a##i##n
#define go decode(m,a,i,n)

int go()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    printf("You have just executed your first program without making use of main() function!\n");
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

Program without main() function

我们可以在这里使用不同的单词和组合,比如

#define decode(s,t,u,m,p,e,d) m##s##u##t
#define go decode(a,n,i,m,a,t,e)

这里按照第一行,第四、第一、第三和第二个字符必须组成一个单词。当同样的组合从动画这个词中取出时,它使成为主


使用宏定义 main

#include<stdio.h>
#define go main
int go(void)
{
    printf("Welcome to Studytonight");
    return 0;
}

这是最简单的技术,我们所做的就是为我们的main()函数提供一个不同的名字,这个名字是在程序执行之前设置的main


使用标记粘贴操作符

#include<stdio.h>
#define go m##a##i##n
int go(void)
{
    printf("Welcome to Studytonight");
    return 0;
}


C 程序:使用switch-case创建菜单驱动软件

原文:https://www.studytonight.com/c/programs/misc/menu-driven-program

下面是一个使用switch-case的菜单驱动程序。

unsigned是有符号的两倍大小,因为它只考虑正值。

%lu是无符号整数的格式说明符。

可被 1 以外的整数整除的数,其本身称为合数

#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");
    int choice, num, i;
    unsigned long int fact;

    while(1)
    {
        printf("1\. Factorial \n");
        printf("2\. Prime\n");
        printf("3\. Odd\\Even\n");
        printf("4\. Exit\n\n\n");
        printf("Enter your choice :  ");
        scanf("%d",&choice);

        switch(choice)
        {
            case 1:
                printf("Enter number:\n");
                scanf("%d", &num);
                fact = 1;
                for(i = 1; i <= num; i++)
                {
                    fact = fact*i;
                }
                printf("\n\nFactorial value of %d is = %lu\n\n\n",num,fact);
                break;

            case 2:
                printf("Enter number:\n");
                scanf("%d", &num);
                if(num == 1)
                printf("\n1 is neither prime nor composite\n\n");
                for(i = 2; i < num; i++)
                {
                    if(num%i == 0)
                    {
                        printf("\n%d is not a prime number\n\n", num);
                        break;
                    }

                }
                /*
                    Not divisible by any number other 
                    than 1 and itself
                */
                if(i == num) 
                {
                    printf("\n\n%d is a Prime number\n\n", num);
                    break;
                }

            case 3:
                printf("Enter number:\n");
                scanf("%d", &num);

                if(num%2 == 0) // 0 is considered to be an even number
                    printf("\n\n%d is an Even number\n\n",num);
                else
                    printf("\n\n%d is an Odd number\n\n",num);
                break;

            case 4:
                printf("\n\n\t\t\tCoding is Fun !\n\n\n");
                exit(0);    // terminates the complete program execution
        }
    }
    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C Menu Driven Program using switch case



C 程序:改变文本背景颜色

原文:https://www.studytonight.com/c/programs/misc/changing-text-background-color

关于该程序的几个要点是:

  • SetConsoleTextAttribute:通过写文件写控制台功能,或通过读文件读控制台功能,设置写入控制台屏幕缓冲区的字符的属性。

  • 此函数影响在函数调用后编写的文本。

  • 语法:

    BOOL WINAPI SetConsoleTextAttribute(_In_ HANDLE hConsoleOutput , _In_ WORD wAttributes);
    

更多详细信息,请访问这里的官方文档:https://docs . Microsoft . com/en-us/windows/console/setconsoletextattribute

下面是改变文本背景颜色的程序。

#include<windows.h>
#include<stdio.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    //BACKGROUND_RED| BACKGROUND_GREEN| BACKGROUND_BLUE| BACKGROUND_INTENSITY
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_BLUE|BACKGROUND_RED|BACKGROUND_INTENSITY);
    printf("\n\nStudytonight just showed you how to put colors to your code!!");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_GREEN);
    printf("\n\nIsn't this Awesome?");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY|BACKGROUND_RED);
    printf("\n\nYou just did something that only 1 out of 10 coders are familiar of :)\n");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_GREEN|BACKGROUND_INTENSITY);
    printf("\n\nYou are doing great!!");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_BLUE|BACKGROUND_INTENSITY);
    printf("\n\nThe best is yet to come!");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_GREEN|BACKGROUND_INTENSITY);
    printf("\n\nWhat are you waiting for?? Just play with it!!");

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

C program out for Changing text background color



C 程序:显示当前日期和时间

原文:https://www.studytonight.com/c/programs/misc/display-current-date-and-time

C 库函数char *ctime(const time_t *timer)根据参数定时器返回一个代表本地时间的字符串。返回的字符串具有以下格式: Www Mmm dd hh:mm:ss yyyy 。这里 Www 是工作日, Mmm 是字母中的月份, dd 是月份中的日子, hh:mm:ss 是时间, yyyy 是年份。

下面是显示当前日期和时间的程序。

#include<time.h>用于timectime功能以及time_t数据类型。

#include<stdio.h>
#include<time.h>

int main()
{
    printf("\n\n\t\tStudytonight - Best place to learn\n\n\n");

    time_t t;   // not a primitive datatype
    time(&t);

    printf("\nThis program has been writeen at (date and time): %s", ctime(&t));

    printf("\n\n\t\t\tCoding is Fun !\n\n\n");
    return 0;
}

输出:

c program out to Display current date and time



C++

基本 C++ 概念

C++ 入门

原文:https://www.studytonight.com/cpp/introduction-to-cpp.php

众所周知,C++ 是 C 语言的扩展,由贝尔实验室的 Bjarne stroustrup 开发。C++ 是一种中级语言,因为它包含对高级和低级语言特性的确认。C++ 是一种静态类型、自由形式、多参数、编译的通用语言。

C++ 是一种 面向对象编程语言 ,但不是纯粹的面向对象。像FriendVirtual这样的特性违反了一些非常重要的 OOPS 特性,使得这种语言不值得被称为完全面向对象的语言。这是一种中级语言。


C++ 相对于 C 语言的优势

主要区别在于 OOPS 概念,C++ 是一种面向对象的语言,而 C 是一种过程语言。除此之外,C++ 还有许多其他特性,使这种语言在 C 语言中占据上风。

遵循 C++ 的特性使它成为比 C 更强的语言,

  1. C++ 中有更强的类型检查。
  2. C++ 中所有的 OOPS 特性,比如抽象、封装、继承等等,都让它对程序员来说更有价值,更有用。
  3. C++ 支持并允许用户自定义运算符(即运算符重载),其中也支持函数重载。
  4. 异常处理在 C++ 里是有的。
  5. 虚函数的概念以及对象的构造器和析构器。
  6. C++ 中的内联函数,而不是 C 语言中的宏。内联函数使完整的函数体像宏一样安全。
  7. 变量可以用 C++ 在程序中的任何地方声明,但必须在使用前声明。

**What we will cover in Basics of C++**
  • OOPS 概念基础
  • 基本语法和结构
  • 数据类型和修改器
  • c++ 中的变量
  • c++ 中的运算符
  • c++ 中的 sizeof 和 typedef
  • 决策
  • 回路类型
  • 存储类别
  • 功能


C++ 中的面向对象编程

原文:https://www.studytonight.com/cpp/cpp-and-oops-concepts.php

面向对象编程是一种与类、对象和围绕这两个概念的各种其他概念相关联的编程风格,如继承、多态、抽象、封装等。

Basic OOPS concepts in c++

在下面的视频中,我们借助一个非常容易理解的例子解释了面向对象编程的基本概念。如果你想跳过视频,所有内容都在下面讨论。

让我们试着通过一个简单的例子来了解一下这些。人类是有生命的形式,大致分为两种,男性和女性。正确是真的。每个人(男性或女性)都有两条腿、两只手、两只眼睛、一个鼻子、一颗心等。男性和女性都有一些常见的身体部位,但男性有一些女性没有的特定身体部位,女性有一些身体部位,但男性没有。

所有的人都走路、吃饭、看、说话、听等等。现在,男性和女性都执行一些共同的功能,但是两者都有一些细节,这对另一个是无效的。比如:女的可以生,男的不可以生,所以这只针对女的。

人体解剖学很有趣,不是吗?但是让我们看看这一切是如何与 C++ 和 OOPS 相关联的。在这里,我们将尝试通过这个例子来解释所有的 OOPS 概念,稍后我们将有所有这些的技术定义。


班级

这里我们可以把人类作为一个类。类是定义其属性和功能的任何功能实体的蓝图。像人一样,有身体的一部分,做各种动作。


遗产

考虑HumanBeing一个类,有手、腿、眼等属性,有走、说、吃、看等功能。MaleFemale也是类,但是大部分属性和函数都包含在HumanBeing中,因此它们可以使用继承的概念从类HumanBeing继承一切。


目标

我的名字是阿布舍克,我是类Male实例/对象。当我们说,人类,男性或女性,我们只是指一种,你,你的朋友,我,我们是这些类的形式。我们有一个物理存在,而一个类只是一个逻辑定义。我们是目标。


抽象

抽象意味着,只向外界展示需要的东西,而隐藏细节。继续我们的例子,人类的会说话,会走路,会听,会吃,但是细节对外界是隐藏的。在我们的案例中,我们可以将皮肤作为抽象因素,隐藏内部机制。


包装

这个概念用我们的例子来解释有点棘手。我们的腿被绑在一起帮助我们走路。我们的手,帮我们拿东西。属性与函数的这种绑定称为封装。


多态

多态是一个概念,它允许我们重新定义某件事的工作方式,要么通过改变它是如何完成的,要么通过改变它所使用的部分。这两种方式都有不同的术语。

如果我们用手走路,而不是用腿走路,这里我们将改变用来做某事的部分。因此这被称为过载。

如果有一个明确的行走方式,但我希望以不同的方式行走,但使用我的腿,像其他人一样。然后我就可以随心所欲的走路了,这就叫做压倒


糟糕的概念定义

现在,让我们讨论一下面向对象编程的一些主要特性,您将在 C++ 中使用这些特性(技术上)。

  1. 目标
  2. 班级
  3. 抽象
  4. 包装
  5. 继承
  6. 过载
  7. 异常处理

目标

对象是面向对象程序设计的基本单元。它们是类的实例,具有数据成员并使用各种成员函数来执行任务。


班级

它类似于 C 语言中的结构。类也可以定义为用户定义的数据类型,但它也包含函数。所以,类基本上是对象的蓝图。它声明并定义了对象将拥有哪些数据变量,以及可以对类的对象执行哪些操作。


抽象

抽象是指只显示应用程序的基本特征,隐藏细节。在 C++ 中,类可以向外部世界提供访问和使用数据变量的方法,避免直接访问变量,或者类甚至可以声明每个人都可以访问的所有内容,或者可能只是继承它的类。这可以使用访问说明符来完成。


包装

也可以说是数据绑定。封装就是在类中将数据变量和函数绑定在一起。


遗产

继承是一种反复重用曾经编写的代码的方式。继承的类称为类&继承的类称为派生类。它们也被称为父类和子类。

因此,当派生类继承基类时,派生类可以使用基类中定义的所有函数,从而使代码可重用。


多态

这是一个特性,它允许我们创建具有相同名称但不同参数的函数,这些函数将执行不同的操作。也就是说,功能名称相同,但功能方式不同。或者,它还允许我们重新定义一个函数,为它提供一个全新的定义。在接下来的课程中,您将很快详细了解如何做到这一点。


异常处理

异常处理是 OOP 的一个特性,用于处理运行时产生的未解决的异常或错误。



C++ 的基本概念

原文:https://www.studytonight.com/cpp/basics-of-cpp.php

在本节中,我们将介绍 C++ 的基础知识,它将包括语法、变量、运算符、循环类型、指针、引用以及关于 C++ 程序其他要求的信息。你会遇到很多你已经在 C 学过的术语。


C++ 程序的语法和结构

在这里,我们将讨论一个简单而基本的 C++ 程序来打印“你好,这是 C++”及其部分结构的细节和用途。

第一个 C++ 程序

#include <iostream.h>
using namespace std;
int main()
{
    cout << "Hello this is C++";
}

头文件就像 C 程序一样包含在开头。这里iostream是一个头文件,为我们提供输入&输出流。头文件包含预声明的函数库,用户可以轻松使用。

使用命名空间标准,告诉编译器使用标准命名空间。命名空间收集用于类、对象和变量的标识符。namespace 在程序中可以通过两种方式使用,要么在开头使用using语句,就像我们在上面提到的程序中所做的那样,要么使用 NameSpace 的名称作为前缀,放在带有范围解析(::)运算符的标识符之前。

例: std::cout << "A";

main() ,是保存程序执行部分的函数,返回类型为int

cout < < ,用于在屏幕上打印任何东西,与 C 语言中的printf相同。 cincoutscanfprintf相同,唯一不同的是在cout & cin中不需要提到格式说明符,如int等的%d


C++ 程序中的注释

对于单行评论,在提评论之前先用 // ,比如

cout<<"single line";   // This is single line comment 

For multiple line comment, enclose the comment between /* and */

/*this is 
  a multiple line 
  comment */

用 C++ 创建类

类名称必须以大写字母开头,包含数据变量和成员函数。这只是对类的介绍,我们将在整个 C++ 教程中详细讨论类。

class Abc
{
    int i;           //data variable
    void display()         //Member Function
    { 
        cout << "Inside Member Function";
    }
}; // Class ends here

int main()
{
    Abc obj;  // Creatig Abc class's object
    obj.display();  //Calling member function using class object
}

这就是类的定义方式,一旦定义了类,就创建了它的对象,并使用了成员函数。

变量可以在整个程序的任何地方声明,但是在使用之前必须声明。因此,我们不需要在程序开始时声明变量。

别担心,这只是给你一个关于 C++ 语言的基本概念,我们将在接下来的教程中详细介绍一切。



C++ 中的数据类型和修饰符

原文:https://www.studytonight.com/cpp/datatypes-and-modifiers-in-cpp.php

让我们从数据类型开始。它们用于定义变量的类型和使用的内容。数据类型定义了您在编写的程序中使用存储的方式。数据类型可以有两种:

  1. 内置数据类型
  2. 用户定义或抽象数据类型

内置数据类型

这些是预定义的数据类型,直接连接到编译器中。例如:intchar等。


用户定义的或抽象的数据类型

这些是用户作为类或结构创建的类型。在 C++ 中,这些类与在 C 语言中一样,将用户定义的数据类型实现为结构。


C++ 中的基本内置数据类型

| char | 用于字符存储(1 字节) |
| int | 对于整数(2 字节) |
| float | 单精度浮点(4 字节) |
| double | 双精度浮点数(8 字节) |

:

char a = 'A';          // character type
int a = 1;             // integer type
float a = 3.14159;     // floating point type 
double a = 6e-4;       // double type (e is for exponential) 

C++ 中的其他内置数据类型

| bool | 布尔型(真或假) |
| void | 没有任何价值 |
| wchar_t | 宽字符 |


C++ 中作为数据类型的枚举

枚举类型声明一个新的类型名以及一个包含标识符的值序列,标识符的值从 0 开始,每次递增 1。

例如:

enum day(mon, tues, wed, thurs, fri) d;

这里定义了一个由变量d表示的天数计数。周一将持值 0周二将有 1 以此类推。我们也可以显式赋值,比如,enum day(mon, tue=7, wed);。这里周一会是 0周二会被分配 7 ,所以周三会得到值 8


C++ 中的修饰符

在 C++ 中,特殊的单词(称为修饰符)可以用来修改预定义的内置数据类型的含义,并将它们扩展到更大的集合。C++ 中有四种数据类型修饰符,它们是:

  1. long
  2. short
  3. signed
  4. unsigned

上面提到的修饰符可以与内置数据类型一起使用,以使它们更加精确,甚至扩大它们的范围。

下面提到了一些你必须知道的关于修饰语的要点,

  • 修改数据类型将保持的最大值和最小值。
  • 普通 int 的最小尺寸必须为
  • 尺寸层次: short int < int < long int
  • 浮点数的大小层次为: float < double < long double
  • 长浮点不是合法类型,没有短浮点数字。
  • 有符号类型包括正数和负数,是默认类型。
  • 无符号,数字总是没有任何符号,也就是总是正数。


C++ 中的变量

原文:https://www.studytonight.com/cpp/variables-scope-details.php

变量在 C++ 中使用,在 c++ 中,我们需要存储任何值,这些值将在程序中改变。变量可以用多种方式声明,每种方式都有不同的内存需求和功能。变量是编译器根据变量的数据类型分配的内存位置的名称。

variables in C++


变量的基本类型

每个变量 while 声明必须给定一个数据类型,分配给该变量的内存依赖于该数据类型。以下是变量的基本类型,

| bool | 用于存储布尔值的变量(真或假) |
| char | 用于存储字符类型的变量。 |
| int | 对于整数值变量 |
| floatdouble也是具有大浮点值的变量类型 |


声明和初始化

变量必须在使用前声明。通常最好在程序开始时声明它们,但是在 C++ 中,它们也可以在程序中间声明,但是必须在使用它们之前完成。

例如:

int i;      // declared but not initialised
char c; 
int i, j, k;  // Multiple declaration 

初始化意味着给已经声明的变量赋值,

int i;   // declaration
i = 10;  // initialization 

初始化和声明也可以在一个步骤中完成,

int i=10;         //initialization and declaration in same step
int i=10, j=11; 

如果一个变量被声明并且没有被默认初始化,那么它将保存一个垃圾值。此外,如果一个变量被声明了一次,如果我们试图再次声明它,我们会得到一个编译时错误。

int i,j;
i=10;
j=20;
int j=i+j;   //compile time error, cannot redeclare a variable in same scope 

变量的范围

所有的变量都有它们的作用区域,在这个边界之外,它们不保持它们的值,这个边界被称为变量的范围。在大多数情况下,它在花括号之间,在花括号中,变量被声明为变量存在,而不是在它之外。我们将在后面研究存储类,但是到目前为止,我们可以将变量大致分为两种主要类型,

  • 全局变量
  • 局部变量

全局变量

全局变量是那些一旦声明就可以被任何类或函数在程序的整个生命周期中使用的变量。它们必须在main()函数之外声明。如果只声明,它们可以在程序生命周期的不同时间被赋予不同的值。但是,即使它们在 main()函数之外同时被声明和初始化,它们也可以在程序的任何点被赋值。

例如:仅声明,未初始化

include <iostream>
using namespace std;
int x;                // Global variable declared
int main()
{
    x=10;                 // Initialized once
    cout <

局部变量

局部变量是只存在于花括号之间的变量,它在花括号中声明。除此之外,它们不可用并导致编译时错误。

:

include <iostream>
using namespace std;
int main()
{
    int i=10;
    if(i<20)        // if condition scope starts
    {
        int n=100;   // Local variable declared and initialized
    }              // if condition scope ends
    cout << n;      // Compile time error, n not available here
}

一些特殊类型的变量

还有一些特殊的关键字,赋予程序中的变量独特的特征。下面两个是最常用的,我们以后再详细讨论。

  1. 最终 -一旦初始化,其值不能改变。
  2. 【静态】 -这些变量在函数调用之间保持它们的值。

:

#include <iostream.h>
using namespace std;
int main()
{
    final int i=10;
    static int y=20;
}


C++ 中的运算符

原文:https://www.studytonight.com/cpp/operators-and-their-types.php

运算符是特殊类型的函数,它接受一个或多个参数并产生一个新值。例如:加法(+)、减法(-)、乘法(*)等都是运算符。运算符用于对变量和常量执行各种操作。

operators in C++


运算符的类型

  1. 赋值运算符
  2. 数学运算符
  3. 关系运算符
  4. 逻辑运算符
  5. 按位运算符
  6. 移位运算符
  7. 一元运算符
  8. 三元算子
  9. 逗点算符

赋值运算符(=)

Operates ' = '用于赋值,它取右侧(称为右值)并将其复制到左侧(称为左值)。赋值运算符是唯一可以重载但不能继承的运算符。


数学运算符

有用于执行基本数学运算的运算符。加法(+)、减法(-)、分流(/)乘法(*)和模(%)是基本的数学运算符。模数运算符不能用于浮点数。

C++ 和 C 也使用速记符号来执行相同类型的运算和赋值。

int x=10;
x += 4 // will add 4 to 10, and hence assign 14 to X. 
x -= 5 // will subtract 5 from 10 and assign 5 to x. 

关系运算符

这些运算符建立操作数之间的关系。关系运算符有:小于()、小于或等于(<=), greater than equal to (> =)、等价(==)和不等价(!=).

您必须注意到赋值运算符是(=),并且有一个关系运算符,表示等价的(==)。这两者互不相同,赋值运算符将值赋给任何变量,而等效运算符用于比较值,就像在 if-else 条件中一样,示例

int x = 10;  //assignment operator
x=5;         // again assignment operator 
if(x == 5)   // here we have used equivalent relational operator, for comparison
{
    cout <

逻辑运算符

逻辑运算符是 AND (&&)和 OR (||)。它们用于将两个不同的表达式组合在一起。

如果两个语句使用“与”运算符连接,将考虑这两个语句的有效性,但是如果它们使用“或”运算符连接,则其中任何一个都必须有效。这些运算符主要用于循环(尤其是while循环)和决策。


按位运算符

它们用于将单个位转换成一个数字。它们只处理整数数据类型,如charintlong,而不处理浮点值。

  • 按位“与”运算符&
  • 按位或运算符|
  • 和逐位异或运算符^
  • 并且,按位非运算符~

它们也可以用作速记符号,& =|=^=~=等。


移位运算符

移位运算符用于移位任何变量的位。它有三种类型,

  1. 左移运算符 <<
  2. 右移运算符 >>
  3. 无符号右移位运算符 >>>

一元运算符

这些运算符只对一个操作数起作用。一元运算符很多,但使用最多的是递增++和递减--运算符。

其他一元运算符:地址为&,取消引用*新增删除,按位不~,逻辑不!,一元减-和一元加+


三元算子

三元 if-else ? :是一个有三个操作数的运算符。

int a = 10;
a > 5 ? cout << "true" : cout << "false"

逗点算符

这用于分隔变量名和表达式。在表达式的情况下,生成并使用最后一个表达式的值。

:

int a,b,c; // variables declaration using comma operator
a=b++, c++; // a = c++ will be done. 


C++ 中的sizeOftypedef运算符

原文:https://www.studytonight.com/cpp/sizeof-and-typedef.php

在本教程中,我们将介绍 C++ 中sizeOftypedef运算符的用法。

sizeOf也是一个运算符不是一个函数,它用于获取分配给数据类型&对象的内存量信息。它也可以用来获取用户定义的数据类型的大小。

sizeOf运算符可以带括号,也可以不带括号。如果你把它应用到一个变量上,你可以不用括号来使用它。

cout << sizeOf(double);   //Will print size of double
int x = 2;
int i = sizeOf x; 

typedefc++ 中的运算符

typedef是在 C 中使用的关键字,用于为现有类型指定替代名称。当数据类型的名称变得稍微复杂时,它主要用于用户定义的数据类型。以下是使用 typedef 的一般语法,

typedef existing_name alias_name

让我们举个例子,看看 typedef 实际上是如何工作的。

typedef unsigned long ulong;

上面的语句为无符号长类型定义了一个术语。现在这个 ulong 标识符可以用来定义无符号长类型变量。

ulong i, j;

typedef和指针

typedef也可以用来给指针取别名。这里有一个例子,在指针声明过程中使用 typedef 是有益的。

在指针中*绑定到右边而不是左边。

int* x, y ;

通过这个声明语句,我们实际上是将 x 声明为 int 类型的指针,而 y 将声明为普通整数。

typedef int* **IntPtr** ;
IntPtr x, y, z;

但是如果我们像上面的例子一样使用 typedef ,我们可以在一个语句中声明任意数量的指针。



C++ 中的决策——ifelseelse if

原文:https://www.studytonight.com/cpp/decision-making-in-cpp

决策是根据特定条件决定语句的执行顺序,或者重复一组语句,直到满足特定条件。C++ 通过支持以下语句来处理决策,

  • if 语句
  • 切换语句
  • 条件运算符语句
  • 转到语句

if语句进行决策

if语句可以根据测试条件的复杂程度以不同的形式实现。不同的形式是,

  1. 简单的 if 语句
  2. 如果....else 语句
  3. 嵌套如果....else 语句
  4. 否则如果声明

简单if语句

简单的 if 语句的一般形式是,

if(expression)
{
    statement-inside;
}
    statement-outside; 

如果表达式为真,则执行‘语句-内部’,否则跳过‘语句-内部’,只执行‘语句-外部’。

示例:

#include< iostream.h>
int main( )
{
    int x,y;
    x=15;
    y=13;
    if (x > y )
    {
        cout << "x is greater than y";
    }
}

x 大于 y


if...else声明

简单的一般形式如果...否则的说法是,

if(expression)
{
    statement-block1;
}
else
{
    statement-block2;
} 

如果“表达式”为或返回,则执行“语句块 1”,否则跳过“语句块 1”,执行“语句块 2”。

示例:

void main( )
{
    int x,y;
    x=15;
    y=18;
    if (x > y )
    {
        cout << "x is greater than y";
    }
    else
    {
        cout << "y is greater than x";
    }
}

y 大于 x


嵌套if....else语句

嵌套的一般形式如果...否则的说法是,

if(expression)
{
    if(expression1)
    {
        statement-block1;
    }
    else 
    {
        statement-block2;
    }
}
else
{
    statement-block3;
}

如果“表达式”为或返回,则执行“语句块 3”,否则执行将进入if条件并检查“表达式 1”。那么如果“表达式 1”为或返回,则执行“语句块 1”,否则执行“语句块 2”。

示例:

void main( )
{
    int a,b,c;
    cout << "enter 3 number";
    cin >> a >> b >> c;
    if(a > b)
    {
        if( a > c)
        {
            cout << "a is greatest";
        }
        else 
        {
            cout << "c is greatest";
        }
    }
    else
    {
        if( b> c)
        {
            cout << "b is greatest";
        }
        else
        {
            cout << "c is greatest";
        }
    }
}

以上代码将根据abc变量的值打印不同的语句。


else-if梯子

else 的一般形式——如果梯子是,

if(expression 1)
{
    statement-block1;
}
else if(expression 2) 
{
    statement-block2;
}
else if(expression 3 ) 
{
    statement-block3;
}
else 
    default-statement;

这个表达式是从(梯子的)顶部向下测试的。一旦找到真正的条件,就执行与之关联的语句。

示例:

void main( )
{
    int a;
    cout << "enter a number";
    cin >> a;
    if( a%5==0 && a%8==0)
    {
        cout << "divisible by both 5 and 8";
    }  
    else if( a%8==0 )
    {
        cout << "divisible by 8";
    }
    else if(a%5==0)
    {
        cout << "divisible by 5";
    }
    else 
    {
        cout << "divisible by none";
    }
}

如果为变量a输入值 40 ,那么输出将是:

可被 5 和 8 整除


需要记住的要点

  1. In if statement, a single statement can be included without enclosing it into curly braces { }.

    int a = 5;
    if(a > 4)
        cout << "success"; 
    

    成功

    上面的情况不需要花括号,但是如果我们在if条件中有一个以上的语句,那么我们必须将它们包含在花括号中,否则只会考虑if条件之后的第一个语句。

    int a = 2;
    if(a > 4)
        cout << "success";
        // below statement is outside the if condition
        cout << "Not inside the if condition" 
    

    不在 if 条件内

  2. if条件的表达式中必须使用==进行比较,如果使用=,表达式将始终返回 true ,因为它执行赋值而不是比较。

  3. Other than 0(zero), all other positive numeric values are considered as true.

    if(27)
        cout << "hello"; 
    

    你好



C++ 循环——whilefordo while循环

原文:https://www.studytonight.com/cpp/loops-in-cpp

在任何编程语言中,循环用于重复执行一组语句,直到满足特定条件。


它是如何工作的

loopflow diagram in C++

执行一系列语句,直到指定条件为真。要执行的语句序列保存在花括号{ }中,称为循环体。每次执行循环体后,检查条件,如果发现为真,则再次执行循环体。当条件检查为时,不执行循环体。


在 C++ 语言中有 3 种类型循环

  1. 循环
  2. 回路
  3. 边做边循环

while循环

循环可以被称为入口控制循环。它分三步完成。

  • 变量初始化。(例如int x=0;)
  • 条件(例如while( x<=10))
  • 可变增量或减量(x++x--x=x+2

语法:

variable initialization;
while (condition)
{
    statements;
    variable increment or decrement; 
} 

for循环

for循环用于重复执行一组语句,直到满足特定条件。我们可以称之为开环。一般格式是,

for(initialization; condition; increment/decrement)
{
    statement-block;
}

for循环中,我们正好有两个分号,一个在初始化之后,第二个在条件之后。在这个循环中,我们可以有多个初始化或增量/减量,用逗号运算符分隔。对于回路只能有一个条件


嵌套for循环

我们还可以为循环嵌套,即一个循环位于另一个循环内,用于循环。基本语法是,****

for(initialization; condition; increment/decrement)
{
    for(initialization; condition; increment/decrement)
    {
        statement;
    }
}

do...while循环

在某些情况下,有必要在测试条件之前执行循环体。这种情况可以借助 do-while 循环来处理。 do 语句首先评估循环体,最后使用语句检查条件。 do-while 循环的一般格式是,

do
{
    // a couple of statements
}
while(condition);

跳出循环

有时,在执行循环时,一旦某个条件成立,即跳出循环,就必须跳过循环的一部分或离开循环。C 语言允许在一个循环中从一条语句跳到另一条语句,也允许跳出循环。

1) break语句

当在循环中遇到break语句时,循环立即退出,程序继续执行紧接着循环的语句。

2) continue语句

它使控件直接进入测试条件,然后继续循环过程。遇到继续时,光标离开当前循环,并从下一个循环开始。



C++ 中的存储类

原文:https://www.studytonight.com/cpp/storage-classes-in-cpp

存储类用于指定变量的生存期和范围。如何为变量分配存储以及编译器如何处理变量取决于这些存储类。

这些基本上分为 5 种不同的类型:

  1. 全局变量
  2. 局部变量
  3. 寄存器变量
  4. 静态变量
  5. 外部变量

全局变量

这些在开始时、在所有功能体之前定义,并且在整个程序中可用。

using namespace std;
int globe;      // Global variable
void func();
int main()
{
    .....
} 

局部变量

它们是在特定范围内定义和可用的。它们也被称为自动变量,因为它们在进入范围时产生,在范围结束时自动消失。

使用关键字 auto ,但是默认情况下所有局部变量都是 auto,所以我们不必在变量去重之前显式添加关键字 auto。该变量的默认值为垃圾


寄存器变量

这也是一种局部变量。这个关键字用来告诉编译器尽可能快地访问这个变量。变量存储在寄存器中,以提高访问速度。

但是您永远不能使用或计算寄存器变量的地址,并且寄存器变量只能在内声明,这意味着您不能有全局静态寄存器变量


静态变量

静态变量是在程序执行开始时只被初始化和分配存储一次的变量,无论它们在程序中被使用和调用多少次。静态变量保持其值直到程序结束。

void fun()
{
    static int i = 10;
    i++;
    cout << i;
}
int main()
{
    fun();      // Output = 11
    fun();      // Output = 12
    fun();      // Output = 13
}

由于i是静态的,因此它将通过函数调用保持其值,并且在开始时只初始化一次。

静态说明符也在类中使用,但是我们将在后面学习。


外部变量

此关键字用于访问某个文件中的变量,该文件被声明为在其他文件中定义的&,也就是说,在一个文件中全局变量的存在是使用 extern 关键字在另一个文件中声明的。

extern keyword in C++



C++ 中的函数

原文:https://www.studytonight.com/cpp/functions-in-cpp

函数用于为程序提供模块化。使用函数创建应用程序使理解、编辑、检查错误等变得更加容易。


在 C++ 中使用函数的基本语法

下面是如何在 C++ 中定义一个函数,

return-type function-name(parameter1, parameter2, ...)
{
    // function-body
}
  • 返回类型:表示函数将返回什么。它可以是 int,char,一些指针甚至是一个类对象。可以有不返回任何东西的函数,它们用 void 来表示。

  • 函数名:是函数的名称,使用它被调用的函数名。

  • 参数:是保存调用函数时传递的参数值的变量。函数可能包含参数列表,也可能不包含参数列表。

    // function for adding two values
    void sum(int x, int y)
    {
        int z;
        z = x + y;
        cout << z;
    }
    
    int main()
    {
        int a = 10;
        int b = 20;
        // calling the function with name 'sum'
        sum (a, b);
    }
    

    这里,ab是两个变量,作为参数发送到函数sum,而xy参数,将保存ab的值,以执行函数内部所需的操作。

  • 函数体:是编写代码语句的部分。


声明、定义和调用函数

函数声明,是为了告诉编译器函数的存在。提到了函数的返回类型、名称和参数列表。函数体写在其定义中。让我们借助一个例子来理解这一点。

#include < iostream>
using namespace std;

//declaring the function
int sum (int x, int y);

int main()
{
    int a = 10;
    int b = 20;
    int c = sum (a, b);    //calling the function
    cout << c;
}

//defining the function
int sum (int x, int y)
{
    return (x + y);
}

这里,最初的功能是声明,没有身体。然后在main()函数里面是叫做,因为函数返回两个值的总和,变量c是用来存储结果的。然后,最后定义功能为,指定功能体。我们也可以,声明&一起定义函数,但是之后要在调用之前完成。


调用函数

函数是通过名字来调用的。如果函数没有参数,可以直接使用它的名称调用它。但是对于带参数的函数,我们有两种方法可以调用它们,

  1. 按值调用
  2. 引用调用

按值调用

在这种调用技术中,我们将存储或复制的参数值传递给函数的形式参数。因此,原始值不变,只有函数内部的参数发生变化。

void calc(int x);

int main()
{
    int x = 10;
    calc(x);
    printf("%d", x);
}

void calc(int x)
{
    x = x + 10 ;
} 

Ten

在这种情况下,实际变量x没有改变,因为我们通过值传递参数,因此传递了 x 的副本,该副本被改变,并且该复制的值随着函数结束(超出范围)而被破坏。所以 main()中的变量 x 仍然有值 10。

但是我们可以通过使函数 calc() 返回值,并将该值存储在 x 中,来改变这个程序来修改原来的 x

int calc(int x);

int main()
{
    int x = 10;
    x = calc(x);
    printf("%d", x);
}

int calc(int x)
{
    x = x + 10 ;
    return x;
} 

Twenty


引用调用

在这种情况下,我们将变量的地址作为参数传递。在这种情况下,形式参数可以作为引用或指针,在这两种情况下,它们都将改变原始变量的值。

void calc(int *p);

int main()
{
    int x = 10;
    calc(&x);     // passing address of x as argument
    printf("%d", x);
}

void calc(int *p)
{
    *p = *p + 10;
} 

Twenty

注意:如果你没有指针的先验知识,一定要先研究指针。



OOP 的概念

C++ 类和对象简介

原文:https://www.studytonight.com/cpp/class-and-objects.php

类是导致面向对象编程的 C++ 最重要的特性。类是用户定义的数据类型,它拥有自己的数据成员和成员函数,可以通过创建该类的实例来访问和使用。

类定义中的变量被称为数据成员,函数被称为成员函数。

比如:类鸟,所有的鸟都会飞,都有翅膀和喙。所以在这里飞行是一种行为,翅膀和喙是它们特征的一部分。这个类别中有许多不同的鸟,它们有不同的名字,但是它们都有这种行为和特征。

同样,类只是一个蓝图,它分别声明和定义了特性和行为,即数据成员和成员函数。并且这个类的所有对象将共享这些特征和行为。


关于课程的更多信息

  1. 类名必须以大写字母开头(尽管这不是必需的)。如果类名由多个单词组成,那么每个单词的第一个字母必须是大写的。

    class Study, class StudyTonight etc
    
  2. 类包含数据成员和成员函数,这些数据成员和变量的访问依赖于访问说明符(在下一节中讨论)。

  3. 类的成员函数可以在类定义内定义,也可以在类定义外定义。

  4. C++ 中的类类似于 C 中的结构,唯一的区别是,类默认为私有访问控制,其中 as 结构默认为公共。

  5. OOPS 的所有特性都围绕着 C++ 中的类。继承、封装、抽象等。

  6. 类的对象保存数据成员的单独副本。我们可以根据需要创建任意多的类对象。

  7. 类确实拥有更多的特性,比如我们可以创建抽象类,不可变类,所有这些我们将在后面研究。


类的对象

班级只是一个蓝图或模板。当我们定义一个类时,没有分配存储。对象是类的实例,它保存类中声明的数据变量,成员函数处理这些类对象。

每个对象都有不同的数据变量。使用名为的特殊类函数初始化对象。稍后我们将学习构造器。

而每当对象超出其范围时,调用另一个名为析构器的特殊类成员函数,释放对象预留的内存。C++ 没有像在 JAVA 中那样的自动垃圾收集器,在 C++ 析构器中执行这个任务。

class Abc
{
    int x;
    void display()
    {
        // some statement
    } 
};  

int main()
{
    Abc obj;   // Object of class Abc created
}


C++ 中的访问控制

原文:https://www.studytonight.com/cpp/access-control.php

现在,在学习如何定义类及其对象之前,让我们先快速了解什么是访问修饰符。

C++ 类中的访问修饰符定义了访问控制规则。C++ 引入了 3 个新的关键字,即,

  1. 公众的
  2. 私人的
  3. 保护

这些访问修饰符用于设置类成员可用性的边界,无论是数据成员还是成员函数

程序中的访问修饰符,后面跟一个冒号。您可以在同一个类中使用一个、两个或全部三个修饰符来为不同的类成员设置不同的边界。它们改变了跟随它们的所有声明的边界。


C++ 中的公共访问修饰符

Public,指 public 下声明的所有班级成员将对所有人开放。声明为公共的数据成员和成员函数也可以被其他类访问。因此,他们有可能改变它们。所以关键成员不能公开。

class PublicAccess
{
    // public access modifier
    public:   
    int x;            // Data Member Declaration 
    void display();   // Member Function decaration
}

C++ 中的私有访问修饰符

Private 关键字,意味着在该类之外,没有人可以访问声明为 private 的类成员。如果有人试图访问一个类的私有成员,他们会得到一个编译时错误。默认情况下,类变量和成员函数是私有的。

class PrivateAccess
{
    // private access modifier
    private:   
    int x;            // Data Member Declaration 
    void display();   // Member Function decaration
} 

C++ 中受保护的访问修饰符

Protected 是最后一个访问说明符,它类似于 private,它使类成员在类外不可访问。但是该类的任何子类都可以访问它们。(如果 A 类是被 B 类继承的,那么 B 类就是 A 类的子类,后面我们会学习继承。)

class ProtectedAccess
{
    // protected access modifier
    protected: 
    int x;            // Data Member Declaration 
    void display();   // Member Function decaration
} 


定义类和创建对象

原文:https://www.studytonight.com/cpp/defining-class-and-object.php

当我们定义任何类时,我们并没有定义任何数据,我们只是定义了一个结构或蓝图,关于该类类型的对象将包含什么,以及可以对该对象执行什么操作。

下面是类定义的语法,

class ClassName
{
    Access specifier: 
    Data members;
    Member Functions()
    {
        // member function defintion
    }
}; 

这里有一个例子,我们创建了一个名为 Student 的简单类,它有适当的成员,

class Student
{
    public:
    int rollno;
    string name;
};

所以从语法和例子中可以清楚地看到,类定义以关键字“class”开始,后跟类名。然后花括号内是类体,即数据成员和成员函数,其访问由访问说明符限定。类定义以分号或对象声明列表结束。

例如:

class Student
{
    public:
    int rollno;
    string name;
}A,B;

这里AB是类Student的对象,用类定义声明。我们也可以单独声明对象,就像我们声明原始数据类型的变量一样。在这种情况下,数据类型是类名,变量是对象。

int main()
{
    // creating object of class Student
    Student A;
    Student B;
}

AB都有自己的数据成员副本,即rollnoname,我们可以在这些对象中为它们存储不同的值。



在 C++ 中访问类的数据成员

原文:https://www.studytonight.com/cpp/accessing-data-members.php

访问数据成员仅取决于该数据成员的访问控制。如果它是公共的,那么使用直接成员访问(.)操作符和该类的对象可以很容易地访问数据成员。

如果数据成员被定义为私有或受保护的,那么我们就不能直接访问数据变量。然后我们必须创建特殊的公共成员函数来访问、使用或初始化私有和受保护的数据成员。这些成员函数也被称为访问器变异器方法或获取器设置器函数。


访问公共数据成员

下面是一个示例,向您展示如何使用点()初始化和使用公共数据成员。)运算符和类的相应对象。

class Student
{
    public:
    int rollno;
    string name;
};

int main()
{
    Student A;
    Student B;

    // setting values for A object
    A.rollno=1;
    A.name="Adam";

    // setting values for B object
    B.rollno=2;
    B.name="Bella";

    cout <

甲的名字和数字是:亚当-1,乙的名字和数字是:贝拉-2


访问私有数据成员

要访问、使用和初始化私有数据成员,您需要创建 getter 和 setter 函数,以获取和设置数据成员的值。

setter 函数将设置作为参数传递给私有数据成员的值,getter 函数将返回要使用的私有数据成员的值。getter 和 setter 函数都必须定义为公共的。

:

class Student
{
    private:    // private data member
    int rollno;

    public:
    // public function to get value of rollno - getter
    int getRollno()
    {
        return rollno;
    }
    // public function to set value for rollno - setter
    void setRollno(int i)
    {
        rollno=i;
    }
};

int main()
{
    Student A;
    A.rollono=1;  //Compile time error
    cout<< A.rollno; //Compile time error

    A.setRollno(1);  //Rollno initialized to 1
    cout<< A.getRollno(); //Output will be 1
}

这就是我们如何使用 getter 和 setter 方法访问和使用任何类的私有数据成员。我们将在后面详细讨论这个问题。


访问受保护的数据成员

受保护的数据成员,可以直接使用点(。)运算符在当前类的子类中,对于非子类,我们将必须遵循与访问私有数据成员相同的步骤。



C++ 中类的成员函数

原文:https://www.studytonight.com/cpp/member-functions-cpp.php

成员函数是这样的函数,它们的声明在类定义中,并作用于类的数据成员。成员函数的定义可以在类定义的内部或外部。

如果成员函数是在类定义里面定义的,那么可以直接定义,但是如果是在类外面定义的,那么我们就要使用作用域解析::运算符以及带有函数名的类名 alng。

例如:

class Cube
{
    public:
    int side;
    /*
        Declaring function getVolume 
        with no argument and return type int.
    */
    int getVolume();     
}; 

如果我们在类内部定义函数,那么我们不需要先声明它,我们可以直接定义函数。

class Cube
{
    public:
    int side;
    int getVolume()
    {
        return side*side*side;      //returns volume of cube
    }
};

但是如果我们计划在类定义之外定义成员函数,那么我们必须在类定义内部声明函数,然后在外部定义它。

class Cube
{
    public:
    int side;
    int getVolume();
}

// member function defined outside class definition
int Cube :: getVolume()
{
    return side*side*side;
}

两个函数定义的主要函数是相同的。在 main()中,我们将创建类的对象,并使用点.运算符调用成员函数。


在 C++ 中调用类成员函数

类似于访问类中的数据成员,我们也可以使用点运算符(.)通过类对象访问公共成员函数。

下面我们有一个简单的代码示例,我们正在创建类的一个对象Cube并调用成员函数getVolume():

int main()
{
    Cube C1;
    C1.side = 4;    // setting side value
    cout<< "Volume of cube C1 = "<< C1.getVolume();
} 

立方体 C1 的体积= 16

同样,我们可以定义 getter 和 setter 函数来访问类定义内部或外部的私有数据成员。



C++ 中类成员函数的类型

原文:https://www.studytonight.com/cpp/types-of-member-function.php

我们已经知道什么是成员函数,它们做什么,如何定义成员函数以及如何使用类对象调用它们。现在让我们了解一些可以在 C++ 类中定义的特殊成员函数。以下是不同类型的成员函数:

  1. 简单功能
  2. 静态函数
  3. 常量函数
  4. 内嵌函数
  5. 友元功能

C++ 中的简单成员函数

这些是基本的成员函数,没有任何特殊的关键字如静态等作为前缀。下面给出形式的所有一般成员函数被称为简单的基本成员函数。

return_type functionName(parameter_list)
{
    function body;
} 

C++ 中的静态成员函数

静态是保持其位置的东西。Static 是一个可以和数据成员以及成员函数一起使用的关键字。我们稍后将详细讨论这一点。到目前为止,我们将只讨论它在成员函数中的用法。

通过使用带有函数名的static关键字使函数成为静态函数。这些函数对整个类起作用,而不是对类的特定对象起作用。

可以使用对象和直接成员访问.操作符调用。但是,更典型的是使用类名和作用域解析::运算符单独调用静态成员函数。

例如:

class X
{
    public:
    static void f()
    {
        // statement
    }
};

int main()
{
    X::f();   // calling member function directly with class name
} 

这些函数不能访问普通的数据成员和成员函数,只能在里面调用static数据成员和static成员函数。

它没有任何“这个”关键字,这就是它无法访问普通成员的原因。我们后面会研究关于“这个”的关键字。


C++ 中的常量成员函数

后面我们会详细研究 Const 关键字( Const 关键字,但作为介绍,Const 关键字让变量保持不变,也就是说一旦定义,就有值不能变。

与成员函数一起使用时,此类成员函数永远不能修改对象或其相关数据成员。

// basic syntax of const Member Function

void fun() const 
{
    // statement
}

C++ 中的内联函数

默认情况下,类定义中定义的所有成员函数都声明为 Inline。我们将在下一个主题中详细研究内联函数。


C++ 中的友元函数

友元函数实际上不是类成员函数。友元函数是让私有访问非类函数。可以将全局函数声明为友元,也可以将其他类的成员函数声明为友元。

例如:

class WithFriend
{
    int i;
    public:
    friend void fun(); // global function as friend
};

void fun()
{
    WithFriend wf;
    wf.i=10;  // access to private data member
    cout << wf.i;
}

int main()
{
    fun(); //Can be called directly
} 

因此,友元函数可以通过创建类的对象来访问私有数据成员。同样我们也可以把其他某个类的函数做成友元,或者我们也可以把整个类做成友元类

class Other
{
    void fun();
};

class WithFriend
{
    private:
    int i;
    public:
    void getdata();  // Member function of class WithFriend

    // making function of class Other as friend here
    friend void Other::fun();   

    // making the complete class as friend
    friend class Other;  
}; 

当我们将一个类作为友元时,它的所有成员函数都会自动变成友元函数。

友元函数是一个原因,为什么 C++ 没有被称为纯粹的面向对象语言。因为违反了封装的概念。



C++ 中的内联函数

原文:https://www.studytonight.com/cpp/inline-functions.php

默认情况下,类定义中定义的所有成员函数都声明为 Inline。让我们对这些功能有一些背景知识。

你必须记住来自 C 语言的预处理器。C++ 中的内联函数和 C 语言中的宏做同样的事情。预处理器/宏没有在 C++ 中使用,因为它们有一些缺点。


C++ 中预处理程序/宏的缺点

在宏中,我们在程序开始时用它的值定义某个变量,在程序中我们使用那个变量的任何地方,它都被编译时的值所代替。

1)间距问题

让我们试着用一个例子来理解这个问题,

#define G (y) (y+1)

这里我们定义了一个名为G(y)的宏,在编译时用它的值来代替,也就是(y+1)。但是,当我们称之为G(y)时,实际上会发生什么,

G(1)  // Macro will replace it

预处理器会像这样展开它,

(y) (y+1) (1)

你一定在想为什么会这样,这是因为宏定义中的间距。因此,带有多个表达式的大函数永远不能与宏一起使用,所以在 C++ 中引入了 Inline 函数。

2)复杂论证问题

在某些情况下,这样的宏表达式对某些参数很有效,但是当我们使用复杂的参数时,问题就开始出现了。

#define MAX(x,y) x>y?1:0

如果我们用这个表达,

if(MAX(a&0x0f, 0x0f))  // Complex Argument 

宏将扩展到,

if( a&0x0f > 0x0f ? 1:0)

这里运算符的优先级会导致问题,因为&的优先级比>低,所以宏观评估会让你大吃一惊。这个问题可以通过使用括号来解决,但是对于更大的表达式,问题还是会出现。

3)无法访问类的私有成员

使用宏,在 C++ 中,您永远无法访问私有变量,因此您必须将这些成员公开,这将暴露实现。

class Y
{
    int x;
    public : 
    #define VAL(Y::x)   // Its an Error
} 

C++ 中的内联函数

内联函数是实际的函数,在编译过程中会被复制到各处,就像预处理器宏一样,这样就减少了函数调用的开销。默认情况下,类定义中定义的所有函数都是内联的,但是您也可以使用关键字将任何非类函数内联到它们上面。

对于内联函数,声明和定义必须一起完成。例如,

inline void fun(int a) 
{ 
    return a++; 
} 

关于内联函数的几个要点

  1. 我们必须保持内联函数小,小的内联函数有更好的效率。
  2. 内联函数确实提高了效率,但是我们不应该让所有的函数都内联。因为如果我们内联大函数,可能会导致代码膨胀,也可能会影响速度。
  3. 因此,建议使用范围解析::运算符在类定义之外定义大型函数,因为如果我们在类定义之内定义这样的函数,那么它们会自动内联。
  4. 内联函数由编译器保存在符号表中,对这些函数的所有调用都在编译时进行。

C++ 中的 Getter 和 Setter 函数

我们已经在访问类内部的私有数据变量的主题中研究过这一点。我们使用内联的访问函数来实现这一点。

class Auto
{
    // by default private
    int price;

    public:
    // getter function for variable price
    int getPrice()
    {
        return price;
    }
    // setter function for variable price
    void setPrice(int x)
    {
        i=x;
    }
};

这里getPrice()setPrice()是内联函数,用于访问类Auto的私有数据成员。函数getPrice(),在这种情况下称为 Getter 或 Accessor 函数,函数setPrice()Setter 或 Mutator 函数。

也可以有重叠的存取函数和变异函数。我们将在下一个主题中研究重载函数。


内联函数的局限性

  1. 大型内联函数会导致缓存未命中,并对性能产生负面影响。
  2. 编译时在代码中到处复制函数体的编译开销,对于小程序来说可以忽略不计,但是对于大代码库来说却有所不同。
  3. 另外,如果我们需要函数在程序中的地址,编译器就不能对这些函数进行内联。因为为了给函数提供地址,编译器必须给它分配存储空间。但是内联函数没有存储空间,它们保存在符号表中。

理解 C++ 中的前向引用

所有内联函数都由编译器在类声明的末尾进行评估。

class ForwardReference
{
    int i;
    public:
    // call to undeclared function
    int f() 
    {
        return g()+10;
    }
    int g() 
    {
        return i;
    }
};

int main()
{
    ForwardReference fr;
    fr.f();
} 

您一定认为这将导致编译时错误,但在这种情况下,它会起作用,因为在类声明的右大括号之前,不会计算类中的内联函数。



C++ 中的函数重载

原文:https://www.studytonight.com/cpp/function-overloading.php

如果任何类有多个同名但不同参数的函数,那么它们就被称为重载。函数重载允许您对不同的函数使用相同的名称,以在同一个类中执行相同或不同的函数。

函数重载通常用于增强程序的可读性。如果您必须执行一个操作,但参数的数量或类型不同,那么您可以简单地重载该函数。


控制一个函数的不同方法

  1. 通过更改参数数量。
  2. 通过不同类型的争论。

函数重载:不同数量的参数

在这种类型的函数重载中,我们定义了两个名称相同但相同类型的参数数量不同的函数。例如,在下面提到的程序中,我们做了两个 sum()函数来返回两个和三个整数的和。

// first definition
int sum (int x, int y)
{
    cout << x+y;
}

// second overloaded defintion
int sum(int x, int y, int z)
{
    cout << x+y+z;
} 

这里sum()函数被称为重载函数,因为它有两个定义,一个接受两个参数,另一个接受三个参数。将调用哪个sum()函数,取决于参数的数量。

int main()
{
    // sum() with 2 parameter will be called
    sum (10, 20);  

    //sum() with 3 parameter will be called
    sum(10, 20, 30);  
} 

30 60


函数重载:参数的不同数据类型

在这种类型的重载中,我们定义了两个或多个具有相同名称和相同数量参数的函数,但是参数的类型是不同的。例如,在这个程序中,我们有两个 sum()函数,第一个得到两个整数参数,第二个得到两个双参数。

// first definition
int sum(int x, int y)
{
    cout<< x+y;
}

// second overloaded defintion
double sum(double x, double y)
{
    cout << x+y;
}

int main()
{
    sum (10,20);
    sum(10.5,20.5);
} 

30 31.0


带有默认参数的函数

当我们在声明函数时提到参数的默认值时,它被称为默认参数。在这种情况下,即使我们调用该函数而没有传递该参数的任何值,该函数也将采用指定的默认值。

sum(int x, int y=0)
{
    cout << x+y;
} 

在这里,我们在函数定义过程中为 y 提供了一个默认值。

 int main()
{
    sum(10);
    sum(10,0);
    sum(10,10);
} 

10 10 20

前两个函数调用将产生完全相同的值。

对于第三个函数调用,y 将取 10 作为值,输出将变成 20。

通过设置默认参数,我们也重载了函数。默认参数还允许您在不同的情况下使用相同的函数,就像函数重载一样。


使用默认参数的规则

  1. 只有最后一个参数必须给定默认值。您不能在默认参数后接非默认参数。

     sum (int x,int y);    
    sum (int x,int y=0);  
    sum (int x=0,int y);  // This is Incorrect 
    
  2. 如果你默认一个参数,那么你必须默认其后的所有参数。

     sum (int x,int y=0);
    sum (int x,int y=0,int z);  // This is incorrect
    sum (int x,int y=10,int z=10);  // Correct 
    
  3. 您可以给任何值一个默认值作为参数,与它的数据类型兼容。


带有占位符参数的函数

当函数中的参数在没有任何标识符的情况下声明时,它们被称为占位符参数。

void sum (int, int); 

此类参数也可以与默认参数一起使用。

void sum (int, int=0);


C++ 中的构造器和析构器

原文:https://www.studytonight.com/cpp/constructors-and-destructors-in-cpp

构造器是执行每个对象初始化的特殊类函数。每当创建对象时,编译器都会调用构造器。将存储分配给对象后,构造器将值初始化为对象成员。

而另一方面,析构器用于销毁类对象。

在继续学习 C++ 语言中的构造器和析构器之前,请查看以下主题以更好地理解这个概念:

  • c++ 中的函数
  • c++ 中的类和对象
  • 数据成员

让我们先从构造器开始,下面是在类中定义构造器的语法:

class A
{
    public:
    int x;
    // constructor
    A()
    {
        // object initialization
    }
}; 

定义构造器时,您必须记住构造器的名称将与类名称相同,并且构造器永远不会有返回类型。

可以使用类名和范围解析::运算符在类定义内部或类定义外部定义构造器。

class A
{
    public:
    int i;
    A(); // constructor declared
};

// constructor definition
A::A()   
{
    i = 1;
}

C++ 中构造器的类型

构造器有三种类型:

  1. 默认构造器
  2. 参数化构造器
  3. 复制构造器

默认构造器

默认构造器是不接受任何参数的构造器。它没有参数。

语法:

class_name(parameter1, parameter2, ...)
{ 
    // constructor Definition 
} 

例如:

class Cube
{
    public:
    int side;
    Cube()
    {
        side = 10;
    }
};

int main()
{
    Cube c;
    cout << c.side;
}

Ten

在这种情况下,一旦创建了对象,就调用构造器来初始化其数据成员。

默认构造器对于对象成员的初始化非常重要,即使我们没有显式定义构造器,编译器也会隐式提供默认构造器。

class Cube
{
    public:
    int side;
};

int main()
{
    Cube c;
    cout << c.side;
} 

0 或任何随机值

在这种情况下,将调用编译器提供的默认构造器,该构造器将对象数据成员初始化为默认值,在这种情况下,默认值为 0 或任何随机整数值。


参数化构造器

这些是带参数的构造器。使用此构造器,您可以通过传递适当的值作为参数,为不同对象的数据成员提供不同的值。

例如:

class Cube
{
    public:
    int side;
    Cube(int x)
    {
        side=x;
    }
};

int main()
{
    Cube c1(10);
    Cube c2(20);
    Cube c3(30);
    cout << c1.side;
    cout << c2.side;
    cout << c3.side;
} 

10 20 30

通过在上面的例子中使用参数化构造器,我们已经用用户定义的值初始化了 3 个对象。我们可以在一个构造器中有任意数量的参数。


复制构造器

这些是特殊类型的构造器,以一个对象为参数,用于将一个对象的数据成员的值复制到另一个对象中。我们后面会详细学习复制构造器。


C++ 中的构造器重载

就像其他成员函数一样,构造器也可以重载。事实上,当您在类中定义了默认和参数化构造器时,您就拥有了重载构造器,一个不带参数,另一个带参数。

一个类中可以有任意数量的构造器,但参数列表不同。

class Student
{
    public:
    int rollno;
    string name;
    // first constructor
    Student(int x)
    {
        rollno = x;
        name = "None";
    }
    // second constructor
    Student(int x, string str)
    {
        rollno = x;
        name = str;
    }
};

int main()
{
    // student A initialized with roll no 10 and name None
    Student A(10);

    // student B initialized with roll no 11 and name John
    Student B(11, "John");
} 

在上面的例子中,我们定义了两个具有不同参数的构造器,因此重载了构造器。

还有一点很重要,如果您显式定义了任何构造器,那么编译器将不会提供默认构造器,您必须自己定义它。

在上面的情况下,如果我们在 main() 中写Student S;,会导致编译时出错,因为我们没有定义默认构造器,编译器也不会提供它的默认构造器,因为我们定义了其他参数化的构造器。


C++ 中的析构器

析构器是一种特殊的类函数,一旦对象的作用域结束,它就销毁对象。当对象超出范围时,编译器会自动调用析构器。

析构器的语法与构造器的语法相同,析构器的名称使用类名,前缀为~

class A
{
    public:
    // defining destructor for class
    ~A() 
    {
        // statement
    }   
};

析构器永远不会有任何参数。


查看如何调用构造器和析构器的示例

下面我们有一个简单的类A,它有一个构造器和析构器。我们将创建类的对象,看看什么时候调用构造器,什么时候调用析构器。

class A
{
    // constructor
    A()
    {
        cout << "Constructor called";
    }

    // destructor
    ~A()
    {
        cout << "Destructor called";
    }
};

int main()
{
    A obj1;   // Constructor Called
    int x = 1
    if(x)
    {
        A obj2;  // Constructor Called
    }   // Destructor Called for obj2
} //  Destructor called for obj1 

构造器调用构造器调用析构器调用析构器调用

创建对象时,调用该类的构造器。对象引用在其范围结束时被销毁,通常是在创建它的代码块的右花括号}之后。

if块结束时,对象obj2被破坏,因为它是在if块内创建的。当main()功能结束时,对象obj1被破坏。


默认构造器和参数化构造器的单一定义

在本例中,我们将使用默认参数为 defualt 和参数化构造器定义一个定义。

class Dual
{
    public:
    int a;
    Dual(int x=0)
    {
        a = x;
    }
};

int main()
{
    Dual obj1;
    Dual obj2(10);
} 

这里,在这个程序中,一个单一的构造器定义将负责这两个对象初始化。我们不需要单独的默认构造器和参数化构造器。



C++ 中的初始化列表

原文:https://www.studytonight.com/cpp/initializer-list-in-cpp.php

初始化列表用于初始化数据成员。语法以冒号(:)开头,然后用逗号分隔每个变量及其值。初始值设定项列表不以分号结束。

语法:

Constructorname(datatype value1, datatype value2):datamember(value1),datamember(value2)
{
    ...
}

例如:

#include<iostream>
using namespace std;

class Base
{
    private:
    int value;
    public:
    // default constructor
    Base(int value):value(value)
    {
        cout << "Value is " << value;
    }
};

int main()
{
    Base il(10);
    return 0;
}

值为 10

上面的代码只是一个理解 Initializer 列表语法的例子。在上面的代码中,value也可以很容易地在构造器内部初始化,因此我们不必使用初始化列表。


C++ 中初始化列表的使用

有些情况下,构造器内部的数据成员初始化不起作用,必须使用初始化列表。以下是这种情况:

1)当没有基类默认构造器时

在继承中,基类构造器首先被调用(构造器调用的顺序),然后是子类构造器。

因此,在下面的例子中Base_类构造器将在InitilizerList_类构造器之前被调用,因此下面的程序将抛出编译错误:“基类不存在默认构造器”。

#include<iostream>
using namespace std;

class Base_
{
    public:
    // parameterized constructor
    Base_(int x)
    {
        cout << "Base Class Constructor. Value is: " << x << endl;
    }
};

class InitilizerList_:public Base_
{
    public:
    // default constructor
    InitilizerList_()
    {
        Base_ b(10);
        cout << "InitilizerList_'s Constructor" << endl;
    }
};

int main()
{
    InitilizerList_ il;
    return 0;
}

上面的代码示例可以使用初始化列表重写,并且会顺利执行,没有任何错误。

以下是新代码:

#include<iostream>
using namespace std;

class Base_
{
    public:
    // parameterized constructor
    Base_(int x)
    {
        cout << "Base Class Constructor. Value is: " << x << endl;
    }
};

class InitilizerList_:public Base_
{
    public:
    // default constructor using initializer list
    InitilizerList_():Base_(10)
    {
        cout << "InitilizerList_'s Constructor" << endl;
    }
};

int main()
{
    InitilizerList_ il;
    return 0;
}

基类构造器的值是 10 InitilizerList _ 的构造器


2)当使用引用类型时

如果有数据成员作为引用类型,则必须在初始化列表中对其进行初始化。引用是不可变的,因此只能初始化一次。

#include<iostream>
using namespace std;

class Base
{
    private:
    int &ref;
    public:
    Base(int &ref):ref(ref)
    {
        cout << "Value is " << ref;
    }
};

int main()
{
    int ref=10;
    Base il(ref);
    return 0;
}

值为 10


3)用于初始化const数据成员

const数据成员只能初始化一次,因此必须在初始化列表中进行初始化。

#include<iostream>
using namespace std;

class Base
{
    private:
    const int c_var;
    public:
    Base(int c_var):c_var(c_var)
    {
        cout << "Value is " << c_var;
    }
};

int main()
{
    Base il(10);
}

值为 10


4)当数据成员和参数同名时

#include<iostream>
using namespace std;

class Base
{
    private:
    int value;
    public:
    Base(int value):value(value)
    {
        cout << "Value is " << value;
    }
};

int main()
{
    Base il(10);
    return 0;
}

值为 10


5)为了提高性能

如果在构造器体内部赋值,那么将创建一个临时对象,提供给赋值运算符。临时对象将在赋值语句结束时被销毁。使用初始化列表可以避免创建临时对象。



在 C++ 中创建和使用命名空间

原文:https://www.studytonight.com/cpp/namespace-in-cpp.php

命名空间是标识符的容器。它将其成员的名称放在不同的空间中,这样它们就不会与其他名称空间或全局名称空间中的名称冲突。


创建命名空间

创建命名空间类似于创建类。

namespace MySpace
{
    // declarations
}

int main() 
{
    // main function
}

这将创建一个名为 MySpace 的新名称空间,我们可以在其中放置我们的成员声明。


创建命名空间的规则

  1. 命名空间定义必须在全局范围内完成,或者嵌套在另一个命名空间内。

  2. 命名空间定义不像类定义那样以分号结束。

  3. You can use an alias name for your namespace name, for ease of use.

    别名示例:

    namespace StudyTonightDotCom
    {
        void study();
        class Learn 
        {  
            // class defintion
        };
    }
    
    // St is now alias for StudyTonightDotCom
    namespace St = StudyTonightDotCom; 
    
  4. 您不能创建命名空间的实例。

  5. There can be unnamed namespaces too. Unnamed namespace is unique for each translation unit. They act exactly like named namespaces.

    未命名命名空间示例:

    namespace
    {
        class Head 
        { 
            // class defintion
        };
        // another class
        class Tail 
        { 
            // class defintion
        };
        int i,j,k;
    }
    
    int main() 
    { 
        // main function
    } 
    
  6. A namespace definition can be continued and extended over multiple files, they are not redefined or overriden.

    例如,下面是一些头 1.h 头文件,我们在其中定义了一个名称空间:

    namespace MySpace
    {
        int x;
        void f();
    }
    

    然后,我们可以将头 1.h 头文件包含在其他一些头 2.h 头文件中,并向现有名称空间添加更多内容:

    #include "header1.h";
    
    namespace MySpace
    {
        int y;
        void g();
    }
    

在 C++ 中使用命名空间

在程序中使用命名空间有三种方法,

  1. 范围解析运算符(::)
  2. using指令
  3. using宣言

带范围解析运算符(::)

命名空间中声明的任何名称(标识符)都可以使用命名空间的名称和带有标识符的范围解析::运算符来显式指定。

namespace MySpace
{
    class A
    {
        static int i;
        public:
        void f();
    };

    // class name declaration
    class B;    

    //gobal function declaration
    void func();   
}

// Initializing static class variable
int MySpace::A::i=9;      

class MySpace::B
{
    int x;
    public:
    int getdata()
    {
        cout << x;
    }
    // Constructor declaration
    B();   
}

// Constructor definition
MySpace::B::B()   
{
    x=0;
} 

using指令

using关键字允许您将整个命名空间导入到具有全局范围的程序中。它可以用来将一个命名空间导入到另一个命名空间或任何程序中。

包含头文件命名空间 1.h :

namespace X
{
    int x;
    class Check
    {
        int i;
    };
}

Namespace2.h 文件中包含上述命名空间头文件:

include "Namespace1.h";

namespace Y
{
    using namespace X;
    Check obj;
    int y;
}

我们将命名空间X导入到命名空间Y中,因此类Check现在将在命名空间Y中可用。

因此我们可以在一个单独的文件中编写下面的程序,比如说 program1.cpp

#include "Namespace2.h";

void test()
{
    using Namespace Y;
    // creating object of class Check
    Check obj2;
}

因此,using指令使得在任何地方使用名称空间变得更加容易。


using宣言

当我们使用using指令时,我们导入名称空间中的所有名称,它们在整个程序中都是可用的,也就是说它们有一个全局范围。

但是通过using声明,我们一次导入一个特定的名称,该名称仅在当前范围内可用。

:用using声明导入的名称可以覆盖用using指令导入的名称

考虑一个文件命名空间。

namespace X
{
    void f()
    {
        cout << "f of X namespace\n";
    }
    void g() 
    {
        cout << "g of X namespace\n";
    }
}

namespace Y
{
    void f()
    {
        cout << "f of Y namespace\n";
    }
    void g() 
    {
        cout << "g of Y namespace\n";
    }
}

现在我们用下面的代码创建一个名为 program2.cpp 的新程序文件:

#include "Namespace.h";

void h()
{
    using namespace X;  // using directive
    using Y::f; // using declaration
    f();    // calls f() of Y namespace
    X::f(); // class f() of X namespace
} 

命名空间的 f

在使用声明时,我们在导入函数时从不提及它的参数列表,因此如果一个命名空间重载了函数,就会导致歧义。



C++ 中的static关键字

原文:https://www.studytonight.com/cpp/static-keyword.php

Static 是 C++ 中的一个关键字,用来给元素赋予特殊的特性。静态元素在程序生命周期中只在静态存储区被分配一次存储。他们有一个直到程序生命周期的范围。static关键字可用于以下情况:

  1. 函数中的静态变量
  2. 静态类对象
  3. 类中的静态成员变量
  4. 类中的静态方法

函数内部的静态变量

静态变量在函数中使用时只初始化一次,然后即使通过函数调用也保持在那里。

这些静态变量存储在静态存储区,而不是栈中。

void counter()
{
    static int count=0;
    cout << count++;
}

int main(0
{
    for(int i=0;i<5;i++)
    {
        counter();
    }
}

0 1 2 3 4

让我们在不使用静态变量的情况下,se 同一个程序的输出

void counter()
{
    int count=0;
    cout << count++;
}

int main(0
{
    for(int i=0;i<5;i++)
    {
        counter();
    }
}

0 0 0 0 0

如果我们不使用static关键字,变量计数将在每次调用counter()函数时被重新初始化,并在每次counter()函数结束时被销毁。但是,如果我们将其设为静态,一旦初始化,count 将有一个作用域,直到main()函数结束,并且它也将通过函数调用携带其值。

如果不初始化静态变量,默认情况下它们被初始化为零。


静态类对象

static关键字对于类对象也是如此。声明为静态的对象被分配到静态存储区的存储中,并具有直到程序结束的范围。

静态对象也像其他普通对象一样使用构造器进行初始化。赋值为零,使用static关键字仅适用于原始数据类型,不适用于用户定义的数据类型。

class Abc
{
    int i;
    public:
    Abc()
    {
        i=0;
        cout << "constructor";
    }
    ~Abc()
    {
        cout << "destructor";
    }
};

void f()
{
    static Abc obj;
}

int main()
{
    int x=0;
    if(x==0)
    {
        f();
    }
    cout << "END";
} 

构造器 END 析构器

你一定在想,为什么析构器没有被调用到if条件范围的末尾,对象obj的引用应该被销毁。这是因为对象是static,它的作用域一直持续到程序的生命周期,因此当main()函数退出时,这个对象的析构器被调用。


类中的静态数据成员

类的静态数据成员是所有对象共享的成员。静态数据成员有一个单独的存储区,不能像其他非静态数据成员一样作为每个对象的单独副本。

静态成员变量(数据成员)不使用构造器初始化,因为它们不依赖于对象初始化。

此外,它必须显式初始化,总是在类之外。如果没有初始化,链接器将给出错误。

class X
{
    public:
    static int i;
    X()
    {
        // construtor
    };
};

int X::i=1;

int main()
{
    X obj;
    cout << obj.i;   // prints value of i
}

one

static数据成员一旦定义,用户就不能重新定义。不过,算术运算可以在上面进行。


静态成员函数

这些函数对整个类起作用,而不是对类的特定对象起作用。

可以使用对象和直接成员访问.操作符调用。但是,更典型的是使用类名和作用域解析::运算符单独调用静态成员函数。

例如:

class X
{
    public:
    static void f()
    {
        // statement
    }
};

int main()
{
    X::f();   // calling member function directly with class name
} 

这些函数不能访问普通数据成员和成员函数,只能访问静态数据成员和静态成员函数。

它没有任何“这个”关键字,这就是它无法访问普通成员的原因。我们后面会研究关于“这个”的关键字。



C++ 中的const关键字

原文:https://www.studytonight.com/cpp/const-keyword.php

常量是不变的东西。在 C 语言和 C++ 中,我们使用关键字const使程序元素保持不变。const关键字可以在 C++ 程序的许多上下文中使用。它可以用于:

  1. 变量
  2. 两颗北极指极星
  3. 函数参数和返回类型
  4. 类数据成员
  5. 班级成员功能
  6. 物体

1)c++ 中的常量变量

如果使用const关键字将任何变量设为常量,则不能更改其值。此外,常量变量必须在声明时初始化。

int main
{
    const int i = 10;
    const int j = i + 10;     // works fine
    i++;    // this leads to Compile time error   
}

在上面的代码中,我们将i设为常量,因此如果我们试图改变它的值,我们将会得到编译时错误。虽然我们可以用它来替代其他变量。


2)c++ 中带const关键字的指针

指针也可以使用 const 关键字来声明。当我们将const与指针一起使用时,我们可以通过两种方式来实现,要么我们可以将const应用于指针所指向的内容,要么我们可以将指针本身设为常量。

指向const变量的指针

这意味着指针指向一个const变量。

const int* u;

这里,u是一个可以指向const int类型变量的指针。我们也可以这样写,

char const* v;

它仍然有同样的意义。在这种情况下,v也是指向const类型的char的指针。

指向const变量的指针非常有用,因为这可以用来使任何字符串或数组不可变(即它们不能被更改)。

const指针

要使指针恒定,我们必须将const关键字放在*的右边。

int x = 1;
int* const w = &x;

这里,w是一个指针,也就是const,指向一个int。现在我们不能改变指针,这意味着它将总是指向变量x,但是可以通过改变x的值来改变它所指向的值。

指向变量的常量指针在需要可以改变值但不能在内存中移动的存储时非常有用。因为指针总是指向同一个内存位置,因为它是用const关键字定义的,但是那个内存位置的值是可以改变的。

:我们也可以有一个const指针指向一个const变量。

const int* const x;

3) const函数参数和返回类型

我们可以将函数的返回类型或参数设为const。那我们就不能改变任何一个。

void f(const int i)
{
    i++;    // error
}

const int g()
{
    return 1;
}

需要记住的几个要点

  1. 对于内置数据类型,返回一个const或非常量值,没有任何区别。

    const int h()
    {
        return 1;
    }
    
    int main()
    {
        const int j = h();
        int k = h();
    }
    

    jk都将被赋值1。不会出现错误。

  2. 对于用户定义的数据类型,返回const,将阻止其修改。

  3. 程序执行时创建的临时对象总是const类型。

  4. 如果一个函数有一个非常量参数,在进行调用时就不能给它传递const参数。

    void t(int*) 
    { 
        // function logic
    }
    

    如果我们给函数t传递一个const int*参数,它会给出错误。

  5. 但是,具有const类型参数的函数可以被传递一个const类型参数和一个非常量参数。

    void g(const int*) 
    {
        // function logic
    }
    

    这个函数可以有int*以及const int*类型的参数。


4)将类数据成员定义为const

这些是类中的数据变量,它们是使用const关键字定义的。它们在声明过程中不会初始化。它们的初始化在构造器中完成。

class Test
{
    const int i;
    public:
    Test(int x):i(x)
    {
        cout << "\ni value set: " << i;
    }
};

int main()
{
    Test t(10);
    Test s(20);
}

在这个程序中,i是一个常量数据成员,在每个对象中都有它的独立副本,因此它是用构造器用每个对象初始化的。一旦初始化,它的值就不能改变。以上初始化类成员的方式在 C++ 中称为 初始化列表


5)将类对象定义为const

当使用const关键字声明或创建对象时,在对象的生命周期内,其数据成员永远不能更改。

语法:

const class_name object;

例如,如果在上面定义的类Test中,我们想要定义一个常量对象,我们可以这样做:

const Test r(30);

6)将类的成员函数定义为const

成员函数从不修改对象中的数据成员。

语法:

return_type function_name() const;

常量对象和常量成员函数示例

class StarWars
{
    public:
    int i;
    StarWars(int x)    // constructor
    { 
        i = x; 
    }

    int falcon() const  // constant function
    { 
        /* 
            can do anything but will not
            modify any data members
        */
        cout << "Falcon has left the Base";
    }

    int gamma()
    { 
        i++; 
    }
};

int main()
{
    StarWars objOne(10);        // non const object
    const StarWars objTwo(20);      // const object

    objOne.falcon();     // No error
    objTwo.falcon();     // No error

    cout << objOne.i << objTwo.i;

    objOne.gamma();     // No error
    objTwo.gamma();     // Compile time error
}

猎鹰已经离开基地猎鹰已经离开基地 10 20

这里我们可以看到,const成员函数从不改变类的数据成员,它既可以和const一起使用,也可以和非常量 objecta 一起使用。但是const对象不能与试图改变其数据成员的成员函数一起使用。


mutable关键字

mutable关键字与类的成员变量一起使用,即使对象是const类型,我们也要更改。因此,mutable对象的数据成员可以被修改。

class Zee
{
    int i;
    mutable int j;
    public:
    Zee()
    {
        i = 0; 
        j = 0;
    }

    void fool() const
    { 
        i++;    // will give error
        j++;    // works, because j is mutable
    }
};

int main()
{
    const Zee obj;
    obj.fool();
}


C++ 中的引用

原文:https://www.studytonight.com/cpp/references-in-cpp.php

引用就像自动取消引用的常量指针。这是给现有存储的新名称。因此,当您访问引用时,您实际上是在访问该存储。

int main()
{ 
    int y=10;
    int &r = y;  // r is a reference to int y
    cout << r;
} 

Ten

不需要使用*来取消引用引用变量。


引用和指针的区别

参考 两颗北极指极星
创建引用时必须对其进行初始化。 指针可以随时初始化。
一旦初始化,我们就不能重新初始化引用。 指针可以被重新初始化任何次数。
您永远不能有空引用。 指针可以为空。
引用被自动取消引用。 *用于取消引用指针。

函数中的引用

引用通常用于函数参数列表和函数返回值,就像指针一样。

在函数中使用引用的规则

  1. 当我们在参数列表中使用引用时,我们必须记住,对函数内部引用的任何更改都会导致函数外部原始参数的更改。
  2. 当我们从函数中返回一个引用时,您应该看到,当 fnction 结束时,无论该引用连接到什么,都不应该超出范围。要么使全局静态

解释引用使用的示例

下面我们有一个简单的代码示例来解释 C++ 中引用的使用,

 int* first (int* x)
{ 
    (*x++);
    return x;   // SAFE, x is outside this scope
}

int& second (int& x)
{ 
    x++;
    return x;   // SAFE, x is outside this scope
}

int& third ()
{ 
    int q;
    return q;   // ERROR, scope of q ends here
}

int& fourth ()
{ 
    static int x;
    return x;   // SAFE, x is static, hence lives till the end.
}

int main()
{
    int a=0;
    first(&a);   // UGLY and explicit
    second(a);   // CLEAN and hidden
} 

在上面的程序中,我们有四个不同的功能。

  • first() 以一个指针作为参数,返回一个指针,就可以了。返回的指针指向在 first()之外声明的变量,因此即使在 first()结束后它也将有效。

  • 同样的,秒()也会好好工作。返回的引用连接到有效存储,在这种情况下是int a

  • 但是在 third() 的情况下,我们在函数内部声明了一个变量q,并试图返回一个与之相连的引用。但是一旦函数 third()结束,局部变量 q 就会被销毁,因此不会返回任何东西。

  • 为了解决上述问题,我们在函数第四个()中将 x 设为静态,给它一个寿命,直到 main()结束,因此现在连接到 x 的引用在返回时将是有效的。


C++ 中的常量引用

Const reference 用于函数参数中,以防止函数更改参数。

void g(const int& x)
{ 
    x++; 
}   // ERROR

int main()
{
    int i=10;
    g(i);
}

我们无法更改函数中的参数,因为它是作为常量引用传递的。


参数传递指南

通常按值调用在函数调用期间使用,只是为了防止我们的对象或变量被更改或修改,但是每当我们按值传递参数时,它的新副本就会被创建。如果我们将一个对象作为参数传递,那么就会创建该对象的副本(调用构造器和析构器),这会影响效率。

因此,我们必须使用常量引用类型参数。当我们使用 const reference 时,只有一个地址在栈上传递,它在函数内部使用,函数不能改变我们的参数,因为它是 const 类型的。

因此,使用 const 引用类型参数减少了开销,也避免了我们的参数被更改。



C++ 中的复制构造器

原文:https://www.studytonight.com/cpp/copy-constructor-in-cpp.php

复制构造器是一种构造器,用于创建一个类类型的已有对象的副本。通常是 X (X & ) 的形式,其中 X 是类名。编译器为所有类提供默认的复制构造器。


复制构造器的语法

Classname(const classname & objectname)
{
    . . . .
}

由于它用于创建对象,因此被称为构造器。并且,它创建了一个新的对象,它是现有副本的精确副本,因此它被称为副本构造器

copy construction of objects

以下是复制构造器的示例程序:

#include<iostream>
using namespace std;
class Samplecopyconstructor
{
    private:
    int x, y;   //data members

    public:
    Samplecopyconstructor(int x1, int y1)
    {
        x = x1;
        y = y1;
    }

    /* Copy constructor */
    Samplecopyconstructor (const Samplecopyconstructor &sam)
    {
        x = sam.x;
        y = sam.y;
    }

    void display()
    {
        cout<<x<<" "<<y<<endl;
    }
};
/* main function */
int main()
{
    Samplecopyconstructor obj1(10, 15);     // Normal constructor
    Samplecopyconstructor obj2 = obj1;      // Copy constructor
    cout<<"Normal constructor : ";
    obj1.display();
    cout<<"Copy constructor : ";
    obj2.display();
    return 0;
}

普通构造器:10 15 复制构造器:10 15


浅复制构造器

通过实例说明了浅拷贝构造器的概念。两名学生正在通过网络共享的两台不同机器上同时在 excel 工作表中输入他们的详细信息。他们两人所做的更改将反映在 excel 工作表中。因为在两个位置都打开了同一个 excel 工作表。这就是浅拷贝构造器的情况。两个对象将指向相同的内存位置。

浅复制复制对原始对象的引用。编译器提供默认的复制构造器。默认复制构造器提供了一个浅复制,如下例所示。它是一个对象的逐位复制。

当类不处理任何动态分配的内存时,使用浅复制构造器。

Shallow Copy Constructor

在下面的例子中,你可以看到两个对象,c1 和 c2,指向同一个内存位置。当调用c1.concatenate()函数时,也会影响 c2。因此c1.display()c2.display()将给出相同的输出。

#include<iostream>
#include<cstring>
using namespace std;
class CopyConstructor
{
    char *s_copy;
    public:
    CopyConstructor(const char *str)
    {
        s_copy = new char[16]; //Dynamic memory allocation
        strcpy(s_copy, str);
    }
    /* concatenate method */
    void concatenate(const char *str)
    {
        strcat(s_copy, str); //Concatenating two strings
    }
    /* copy constructor */
    ~CopyConstructor ()
    { 
        delete [] s_copy;
    }
    void display()
    {
        cout<<s_copy<<endl;
    }
};
/* main function */
int main()
{
    CopyConstructor c1("Copy");
    CopyConstructor c2 = c1; //Copy constructor
    c1.display();
    c2.display();
    c1.concatenate("Constructor");    //c1 is invoking concatenate()
    c1.display();
    c2.display();
    return 0;
}

复制复制构造器复制构造器


深度复制构造器

让我们考虑一个解释深度复制构造器的例子。你应该明天提交一份作业,但你的时间不多了,所以你从你的朋友那里抄来的。现在你和你的朋友有相同的作业内容,但是不同的副本。因此,在你的作业副本中所做的任何修改都不会反映在你朋友的副本中。这就是深度复制构造器中发生的情况。

深度复制为复制的信息分配单独的内存。所以来源和复制是不同的。在一个内存位置进行的任何更改都不会影响在另一个位置的复制。当我们使用指针分配动态内存时,我们需要用户定义的复制构造器。两个对象将指向不同的内存位置。

Deep Copy Constructor

深度复制的一般要求:

  • 普通的构造器。
  • 删除动态分配的内存的析构器。
  • 复制构造器,用于复制动态分配的内存。
  • 重载赋值运算符。

在前面的例子中,你可以看到当 c1 调用concatenate()时,c1 和 c2 都会发生变化,因为两者都指向同一个内存位置。

在下面的示例中,您可以看到用户定义的复制构造器,即深度复制构造器。这里 c1 和 c2 都指向不同的存储位置。因此,在一个位置进行的更改不会影响另一个位置。

#include<iostream>
#include<cstring>
using namespace std;
class CopyConstructor
{
    char *s_copy;
    public:
    CopyConstructor (const char *str)
    {
        s_copy = new char[16];  //Dynamic memory alocation
        strcpy(s_copy, str);
    }

    CopyConstructor (const CopyConstructor &str)
    {
        s_copy = new char[16]; //Dynamic memory alocation
        strcpy(s_copy, str.s_copy);
    }

    void concatenate(const char *str)
    {
        strcat(s_copy, str); //Concatenating two strings
    }

    ~CopyConstructor()
    { 
        delete [] s_copy;
    }

    void display()
    {
        cout<<s_copy<<endl;
    }
};
/* main function */
int main()
{
    CopyConstructor c1("Copy");
    CopyConstructor c2 = c1;    //copy constructor
    c1.display();
    c2.display();
    c1.concatenate("Constructor");    //c1 is invoking concatenate()
    c1.display();
    c2.display();
    return 0;
}

复制复制构造器复制



C++ 中指向类成员的指针

原文:https://www.studytonight.com/cpp/pointer-to-members.php

就像指向普通变量和函数的指针一样,我们可以有指向类成员函数和成员变量的指针。

让我们看看这是如何工作的。


定义类类型的指针

我们可以定义类类型的指针,它可以用来指向类对象。

class Simple
{
    public:
    int a;
};

int main()
{
    Simple obj;
    Simple* ptr;   // Pointer of class type
    ptr = &obj;

    cout << obj.a;
    cout << ptr->a;  // Accessing member with pointer
} 

这里你可以看到我们已经声明了一个指向类的对象的类类型的指针。我们可以使用带有箭头->符号的指针名称来访问数据成员和成员函数。


指向类的数据成员的指针

我们可以使用指针来指向类的数据成员(成员变量)。

声明语法:

datatype class_name :: *pointer_name;

赋值语法:

pointer_name = &class_name :: datamember_name;

声明和赋值也可以在一个语句中完成。

datatype class_name::*pointer_name = &class_name::datamember_name ;

对对象使用指针

为了访问正常的数据成员,我们对对象使用点.操作符和指向对象的->指针。但是当我们有一个指向数据成员的指针时,我们必须去引用那个指针来得到它所指向的东西,因此它变成了,

Object.*pointerToMember

通过指向对象的指针,可以通过写入来访问它,

ObjectPointer->*pointerToMember

让我们举个例子,来理解完整的概念。

class Data
{
    public:
    int a;
    void print() 
    { 
        cout << "a is "<< a; 
    }
};

int main()
{
    Data d, *dp;
    dp = &d;     // pointer to object

    int Data::*ptr=&Data::a;   // pointer to data member 'a'

    d.*ptr=10;
    d.print();

    dp->*ptr=20;
    dp->print();
} 

a 是 10 a 是 20

语法非常难,因此它们只在特殊情况下使用。


指向类成员函数的指针

指针可以用来指向类的成员函数。

语法:

return_type (class_name::*ptr_name) (argument_type) = &class_name::function_name; 

下面是一个例子,展示我们如何使用 ppointer 来成员函数。

class Data
{ 
    public:
    int f(float) 
    { 
        return 1; 
    }
};

int (Data::*fp1) (float) = &Data::f;   // Declaration and assignment
int (Data::*fp2) (float);        // Only Declaration

int main(0
{
    fp2 = &Data::f;   // Assignment inside main()
} 

需要记住的几点

  1. 您可以在运行时更改这些指针的值和行为。这意味着,您可以将其指向其他成员函数或成员变量。

  2. 要拥有指向数据成员和成员函数的指针,您需要将它们公开。



高级概念

C++ 中的继承

原文:https://www.studytonight.com/cpp/overview-of-inheritance.php

继承是一个类从另一个类获取属性和特性的能力。属性被其他类继承的类称为父类基类超类类。并且,继承其他类属性的类称为派生类。

继承使代码可重用。当我们继承一个现有类时,它的所有方法和字段在新类中都变得可用,因此代码被重用。

注意:除了 Private 之外,类的所有成员都是继承的


C++ 中继承的目的

  1. 代码可重用性
  2. 方法覆盖(因此,运行时多态。)
  3. 虚拟关键字的使用

继承的基本语法

 class Subclass_name : access_mode Superclass_name 

在定义这样的子类时,必须在子类声明之前已经定义或至少声明了超类。

访问模式用于指定超类的属性继承到子类、公共类、私有类或受保护类的模式。


继承的例子

每当我们想在一个新的类中使用现有类中的东西时,我们可以使用 Inheritace 上的概念。这里有一个简单的例子,

Example for Inheritance in C++

class Animal
{ 
    public:
    int legs = 4;
};

// Dog class inheriting Animal class
class Dog : public Animal
{ 
    public:
    int tail = 1;
};

int main()
{
    Dog d;
    cout << d.legs;
    cout << d.tail;
} 

4 1


访问修饰符和继承:类成员的可见性

根据继承时使用的访问修饰符,子类中超类成员的可用性会发生变化。它可以是私有的、受保护的或公共的。

1)公共继承

这是最常用的继承模式。在这种情况下,超类的受保护成员成为子类的受保护成员,而公共成员成为公共成员。

class Subclass : **public** Superclass

2)私有继承

在私有模式下,超类的受保护成员和公共成员成为派生类的私有成员。

class Subclass : Superclass   // By default its private inheritance

3)受保护的继承

在受保护模式下,超级类的公共成员和受保护成员成为子类的受保护成员。

class subclass : **protected** Superclass

显示所有可见性模式的表格

衍生类别 衍生类别 衍生类别
基类 公共模式 私人模式 保护模式
--- --- --- ---
私人的 未继承 未继承 未继承
保护 保护 私人的 保护
公众 公众 私人的 保护


C++ 中的继承类型

原文:https://www.studytonight.com/cpp/types-of-inheritance.php

在 C++ 中,我们有 5 种不同类型的继承。也就是说,

  1. 单一继承
  2. 多重继承
  3. 分级继承
  4. 多级继承
  5. 混合继承(也称为虚拟继承)

C++ 中的单一继承

在这种类型的继承中,一个派生类只从一个基类继承。这是最简单的继承形式。

Single Inheritance in C++


C++ 中的多重继承

在这种类型的继承中,单个派生类可以从两个或两个以上的基类继承。

Multiple Inheritance in C++


C++ 中的层次继承

在这种类型的继承中,多个派生类从单个基类继承。

Hierarchical Inheritance in C++


C++ 中的多级继承

在这种类型的继承中,派生类从一个类继承,该类又从其他类继承。一个是超级类,另一个是子类。

Multilevel Inheritance in C++


C++ 中的混合(虚拟)继承

混合继承是层次继承和多层次继承的结合。

Hybrid Inheritance in C++



C++ 中带继承的构造器调用顺序

原文:https://www.studytonight.com/cpp/order-of-constructor-call.php

在本教程中,我们将学习 C++ 中构造器带继承调用的顺序。如果不熟悉 C++ 中的构造器,可以从 C++ 构造器教程中了解。

Order of constructor call

派生类构造器中的基类默认构造器:

当我们从基类派生一个类时,基类的所有数据成员都将成为派生类的成员。我们使用构造器来初始化数据成员,这里显而易见的情况是,当数据继承到派生类中时,谁将负责初始化它们?初始化继承的数据成员构造器是必要的,这就是为什么首先调用基类的构造器。在下面给出的程序中,我们可以看到继承中构造器的执行顺序如下:

#include <iostream>
using namespace std;
class Base
{
   int x;

public:
   // default constructor
   Base()
   {
      cout << "Base default constructor\n";
   }
};

class Derived : public Base
{
   int y;

public:
   // default constructor
   Derived()
   {
      cout << "Derived default constructor\n";
   }
   // parameterized constructor
   Derived(int i)
   {
      cout << "Derived parameterized constructor\n";
   }
};

int main()
{
   Base b;
   Derived d1;
   Derived d2(10);
}

基础默认构造器
基础默认构造器
派生默认构造器
基础默认构造器
派生参数化构造器

派生类构造器中的基类参数化构造器:

让我们看看如何在派生类中调用参数化构造器,在派生类中定义参数化构造器时,需要使用**:**运算符显式定义派生类的参数化构造器的调用。

#include <iostream>
using namespace std;
class Base
{ 
    int x;
    public:
    // parameterized constructor
    Base(int i)
    { 
        x = i;
        cout << "Base Parameterized Constructor\n";
    }
};

class Derived: public Base
{ 
    int y;
    public:
    // parameterized constructor
    Derived(int j):Base(j)
    { 
        y = j;
        cout << "Derived Parameterized Constructor\n";
    }
};

int main()
{
    Derived d(10) ;
}

基本参数化构造器
派生参数化构造器

这里有一些基本的规则来计算c++T3 中带继承的构造器调用顺序。

  • 施工总是从基础开始class。如果有多个基类,那么从最左边的基类开始构造。如果有virtual遗传,那么它被给予更高的优先权)。

  • 然后构造成员字段。它们按照声明的顺序初始化

  • 最后,构建class本身

  • 析构器的顺序正好相反

相关教程:

  • OOPS 基本概念

  • c++ 入门

  • c++ 中的函数

  • c++ 中的引用



C++ 中的向上转换

原文:https://www.studytonight.com/cpp/upcasting.php

向上转换是使用超类的引用或指针来引用子类的对象。或者我们可以说,将子类的引用或指针转换为其超类的引用或指针的行为称为向上转换。

Upcasting in C++

class Super
{ 
    int x;
    public:
    void funBase() 
    { 
        cout << "Super function"; 
    }
};

class Sub:public Super
{ 
    int y;
};

int main()
{
    Super* ptr;    // Super class pointer
    Sub obj;
    ptr = &obj;

    Super &ref;    // Super class's reference    
    ref=obj;
} 

向上转换的反面是向下转换,其中我们将 Super 类的引用或指针转换为派生类的引用或指针。稍后我们将学习更多关于向下预测的内容


从不继承的函数

  • 构造器和析构器永远不会被继承,因此永远不会被覆盖。(我们将在下一个教程中学习函数覆盖的概念)
  • 此外,赋值运算符=永远不会被继承。它可以重载,但不能被子类继承。

C++ 中的继承和静态函数

  1. 它们被继承到派生类中。
  2. 如果在派生类中重新定义静态成员函数,基类中的所有其他重载函数都将被隐藏。
  3. 静态成员函数永远不能是虚拟的。我们将在未来的主题中研究虚拟。

C++ 中的混合继承和虚拟类

在多重继承中,派生类从多个基类继承。因此,在多重继承中有很多模糊的机会。

class A
{ 
    void show(); 
};

class B:public A 
{
    // class definition
};

class C:public A 
{
    // class defintion
};

class D:public B, public C 
{
    // class definition
};

int main()
{
    D obj;
    obj.show();
} 

在这种情况下,B 类和 C 类都从 a 类继承了函数show(),因此 D 类有两个继承的函数show()。在 main()函数中,当我们调用函数show()时,就会出现歧义,因为编译器不知道该调用哪个show()函数。因此我们在继承类时使用虚拟关键字。

class B : virtual public A 
{
    // class definition
};

class C : virtual public A 
{
    // class definition
};

class D : public B, public C 
{
    // class definition
}; 

现在通过添加虚拟关键字,我们告诉编译器调用两个show()函数中的任何一个。


混合继承和构造器调用

众所周知,每当派生类对象被实例化时,基类构造器总是被调用。但是在混合继承的情况下,如上例所述,如果我们创建一个类 D 的实例,那么将调用以下构造器:

  • 在 D 类的构造器之前,将调用其超类的构造器,因此将调用 B 类、C 类和 A 类的构造器。
  • 当 B 类和 C 类的构造器被调用时,它们将再次调用它们的超类的构造器。

这将导致对类 A 的构造器的多次调用,这是不可取的。由于有一个虚拟基类的实例被继承它的多个类共享,因此基类的构造器只被具体类的构造器调用一次,在我们的例子中是类 d

如果在 B 类或 C 类中有任何初始化 A 类构造器的调用,而在创建 D 类对象时,所有这样的调用都将被跳过。



C++ 中的多态和方法覆盖

原文:https://www.studytonight.com/cpp/function-overriding.php

在本教程中,我们将介绍 C++ 中的多态和 C++ 中的函数覆盖的概念。我们还将通过简单的代码示例看到这两者的作用。


C++ 中的多态

多态意味着一件事情有多种形式。在继承中,当超类和子类都有相同声明但定义不同的成员函数时,就通过方法覆盖来实现多态。


C++ 中的方法覆盖

如果我们将一个类继承到派生类中,并在派生类中再次为基类的一个函数提供定义,那么该函数被称为覆盖,这种机制被称为函数覆盖


覆盖函数的要求

  1. 传承应该在那里。函数覆盖不能在类中完成。为此,我们需要一个派生类和一个基类。
  2. 被重定义的函数在基类和派生类中必须具有完全相同的声明,这意味着相同的名称、相同的返回类型和相同的参数列表。

C++ 中函数覆盖的例子

class Base
{
    public:
    void show()
    {
        cout << "Base class";
    }
};

class Derived:public Base
{
    public:
    void show()
    {
        cout << "Derived Class";
    }
}

在本例中,函数show()在派生类中被覆盖。现在让我们研究这些被覆盖的函数是如何在main()函数中被调用的。


用类对象绑定函数调用

将函数调用连接到函数体称为绑定。当它在程序运行前完成时,称为早期绑定或静态绑定或编译时绑定。

class Base
{
    public:
    void shaow()
    {
        cout << "Base class\n";
    }
};

class Derived:public Base
{
    public:
    void show()
    {
        cout << "Derived Class\n";
    }
}

int main()
{
    Base b;       //Base class object
    Derived d;     //Derived class object
    b.show();     //Early Binding Ocuurs
    d.show();   
} 

基类派生类

在上面的例子中,我们使用基类和派生类对象来调用覆盖函数。基类对象将调用函数的基版本,派生类的对象将调用函数的派生版本。


使用基类指针的函数调用绑定

但是当我们使用基类的指针或引用来保存派生类的对象时,函数调用 Binding 会给出一些意想不到的结果。

class Base
{
    public:
    void show()
    {
        cout << "Base class\n";
    }
};

class Derived:public Base
{
    public:
    void show()
    {
        cout << "Derived Class\n";
    }
}

int main()
{
    Base* b;       //Base class pointer
    Derived d;     //Derived class object
    b = &d;
    b->show();     //Early Binding Occurs
} 

基类

在上面的示例中,虽然对象属于派生类,但是仍然调用基类的方法。这是由于早期绑定造成的。

编译器在看到基类的指针时,设置对基类的show()函数的调用,而不知道实际的对象类型。



C++ 中的虚函数

原文:https://www.studytonight.com/cpp/virtual-functions.php

虚函数是基类中的一个函数,在派生类中被覆盖,它告诉编译器对这个函数执行后期绑定

Virtual关键字用于使基类的成员函数虚拟化。


C++ 中的后期绑定

在后期绑定中,函数调用在运行时被解析。因此,现在编译器在运行时确定对象的类型,然后绑定函数调用。后期绑定也称为动态绑定或运行时绑定。


没有虚拟关键字的问题

让我们试着了解一下virtual关键字修复的问题是什么,

class Base
{
    public:
    void show()
    {
        cout << "Base class";
    }
};

class Derived:public Base
{
    public:
    void show()
    {
        cout << "Derived Class";
    }
}

int main()
{
    Base* b;       //Base class pointer
    Derived d;     //Derived class object
    b = &d;
    b->show();     //Early Binding Ocuurs
} 

基类

当我们使用基类的指针来保存派生类的对象时,基类指针或引用将总是调用函数的基版本


在 C++ 中使用虚拟关键字

我们可以在声明基类的方法时使用 virtual 关键字使它们虚拟化。虚拟关键字将导致该方法的后期绑定。

class Base
{
    public:
    virtual void show()
    {
        cout << "Base class\n";
    }
};

class Derived:public Base
{
    public:
    void show()
    {
        cout << "Derived Class";
    }
}

int main()
{
    Base* b;       //Base class pointer
    Derived d;     //Derived class object
    b = &d;
    b->show();     //Late Binding Ocuurs
} 

衍生类别

在基类的函数中使用 Virtual 关键字时,会发生后期绑定,并且会调用函数的派生版本,因为基类指针指向派生类对象。


使用虚拟关键字和访问派生类的私有方法

我们可以借助 virtual 关键字,从基类指针调用派生类的 private 函数。编译器仅在编译时检查访问说明符。所以在运行时,当后期绑定发生时,它不会检查我们是在调用私有函数还是公共函数。

#include <iostream>
using namespace std;

class A
{
    public:
    virtual void show()
    {
        cout << "Base class\n";
    }
};

class B: public A
{
    private:
    virtual void show()
    {
        cout << "Derived class\n";
    }
};

int main()
{
    A *a;
    B b;
    a = &b;
    a->show(); 
} 

衍生类别


C++ 中后期绑定的机制

mechanism of Late binding in C++

为了完成后期绑定,编译器为每个具有虚函数的类创建虚拟表。虚函数的地址被插入到这些表中。每当创建这样一个类的对象时,编译器都会秘密地插入一个名为的指针,指向该对象的 VTABLE。因此,当调用函数时,编译器能够通过使用 vpointer 绑定正确的函数来响应调用。


需要记住的要点

  1. 只有基类方法的声明需要虚拟关键字,而不是定义。
  2. 如果一个函数在基类中被声明为虚化,那么它在它的所有派生类中将是虚化的。
  3. 虚拟功能的地址放在 VTABLE 中,复印机使用 VPTR (虚拟指针)指向虚拟功能。


C++ 中的抽象类和纯虚函数

原文:https://www.studytonight.com/cpp/abstract-class-and-pure-virtual.php

抽象类是至少包含一个纯虚函数的类。抽象类用于为其子类提供接口。继承抽象类的类必须为纯虚函数提供定义,否则它们也将成为抽象类。


抽象类的特征

  1. 抽象类不能被实例化,但是指针和抽象类类型的引用可以被创建。
  2. 抽象类可以有普通函数和变量以及一个纯虚函数。
  3. 抽象类主要用于上播,使其派生类可以使用其接口。
  4. 继承抽象类的类必须实现所有纯虚函数,否则它们也会变成抽象的。

C++ 中的纯虚函数

纯虚函数是没有定义的虚函数。它们以虚拟关键字开始,以= 0结束。下面是纯虚函数的语法,

virtual void f() = 0;

C++ 中抽象类的例子

下面我们有一个简单的例子,我们定义了一个抽象类,

//Abstract base class
class Base          
{
    public:
    virtual void show() = 0;    // Pure Virtual Function
};

class Derived:public Base
{
    public:
    void show()
    { 
        cout << "Implementation of Virtual Function in Derived class\n"; 
    }
};

int main()
{
    Base obj;   //Compile Time Error
    Base *b;
    Derived d;
    b = &d;
    b->show();
} 

虚拟函数在派生类中的实现

在上面的例子中,基类是抽象的,具有纯虚拟的 show() 函数,因此我们不能创建基类的对象。


为什么我们不能创建抽象类的对象?

当我们在抽象类中创建一个纯虚函数时,我们在 VTABLE 中为一个函数保留了一个槽(在上一个主题中研究过),但是没有在那个槽中放置任何地址。因此,VTABLE 将不完整。

由于抽象类的 VTABLE 是不完整的,因此编译器不会允许为这样的类创建对象,并且每当您尝试这样做时都会显示一条错误消息。


纯虚拟定义

  • 可以在抽象类中给纯虚函数一个小的定义,您希望所有的派生类都有这个定义。仍然不能创建抽象类的对象。
  • 另外,纯虚函数必须在类定义之外定义。如果你在类定义中定义它,编译器会给出一个错误。内嵌纯虚拟定义是非法的。
// Abstract base class
class Base         
{
    public:
    virtual void show() = 0;     //Pure Virtual Function
};

void Base :: show()     //Pure Virtual definition
{
    cout << "Pure Virtual definition\n";
}

class Derived:public Base
{
    public:
    void show()
    { 
        cout << "Implementation of Virtual Function in Derived class\n"; 
    }
};

int main()
{
    Base *b;
    Derived d;
    b = &d;
    b->show();
} 

虚拟函数在派生类中的实现



C++ 中的虚析构器

原文:https://www.studytonight.com/cpp/virtual-destructors.php

基类中的析构器可以是虚函数。每当完成向上转换时,基类的析构器必须是虚拟的,以便在程序退出时正确地销毁对象。

注意: 构造器永远不是虚的,只有析构器可以是虚的。


C++ 中不带虚析构器的向上转换

让我们首先看看当我们没有虚拟基类析构器时会发生什么。

class Base
{
    public:
    ~Base() 
    {
        cout << "Base Destructor\n"; 
    }
};

class Derived:public Base
{
    public:
    ~Derived() 
    { 
        cout<< "Derived Destructor\n"; 
    }
}; 

int main()
{
    Base* b = new Derived;     // Upcasting
    delete b;
} 

摧毁基地

在上面的例子中,delete b将只调用基类析构器,这是不可取的,因为派生类的对象仍然没有被构造,因为它的析构器从未被调用过。这会导致内存泄漏。


C++ 中虚析构器的向上转换

现在让我们看看。当我们在基类中有虚析构器时会发生什么。

class Base
{
    public:
    virtual ~Base() 
    {
        cout << "Base Destructor\n"; 
    }
};

class Derived:public Base
{
    public:
    ~Derived() 
    { 
        cout<< "Derived Destructor"; 
    }
}; 

int main()
{
    Base* b = new Derived;     // Upcasting
    delete b;
} 

派生析构器基析构器

当基类中有虚析构器时,首先调用派生类的析构器,然后调用基类的析构器,这是期望的行为。


C++ 中的纯虚析构器

  • 纯虚析构器在 C++ 中是合法的。此外,必须定义纯虚析构器,这与纯虚拟行为相反。
  • 虚析构器和纯虚析构器的唯一区别是,纯虚析构器将使其基类抽象,因此您不能创建该类的对象。
  • 不需要在派生类中实现纯虚析构器。
class Base
{
    public:
    virtual ~Base() = 0;     // Pure Virtual Destructor
};

// Definition of Pure Virtual Destructor
Base::~Base() 
{ 
    cout << "Base Destructor\n"; 
} 

class Derived:public Base
{
    public:
    ~Derived() 
    { 
        cout<< "Derived Destructor"; 
    }
}; 


C++ 中的运算符重载

原文:https://www.studytonight.com/cpp/operator-overloading.php

运算符重载是 C++ 中的一个重要概念。这是多态,在这种多态中,运算符被重载以赋予它用户定义的含义。重载运算符用于对用户定义的数据类型执行操作。例如,可以重载“+”运算符来对各种数据类型执行加法,如整数、字符串(串联)等。

operator overloading example

几乎任何运算符都可以在 C++ 中重载。然而,很少有操作符不会过载。未超载的运算符如下

  • 范围运算符- ::
  • sizeof
  • 成员选择器- .
  • 成员指针选择器- *
  • 三元运算符- ?:

运算符重载语法

Syntax of operator overloading


在 C++ 中实现运算符重载

运算符重载可以通过实现一个函数来完成,该函数可以是:

  1. 成员函数
  2. 非成员函数
  3. 友元函数

如果左操作数是该类的对象,运算符重载函数可以是成员函数,但是如果左操作数不同,则运算符重载函数必须是非成员函数。

如果需要访问类的私有和受保护成员,运算符重载函数可以成为友元函数。


C++ 中运算符重载的限制

以下是实现运算符重载时要记住的一些限制。

  1. 运算符的优先级和结合性不能更改。
  2. Arity(操作数)不能更改。一元运算符保持一元,二元保持二元等。
  3. 不能创建新的运算符,只能重载现有的运算符。
  4. 不能重新定义过程的含义。您不能更改整数的添加方式。


C++ 中使用文件流的文件处理

原文:https://www.studytonight.com/cpp/file-streams-in-cpp.php

文件表示用于存储数据或信息的存储介质。流指的是字节序列。在文件中,我们永久存储数据,即文本或二进制数据,并通过传输字节数据以输入输出操作的形式使用这些数据进行读取或写入。所以我们使用术语文件流/文件处理。我们使用头文件<fstream>

  • ofstream: 表示输出流,用于写入文件。
  • ifstream: 表示输入流,用于读取文件。
  • 流:它代表输出流和输入流。所以它可以从文件中读取和写入文件。

文件处理中的操作:

  • 创建文件:open()
  • 读取数据:read()
  • 写入新数据:write()
  • 关闭文件:close()

创建/打开文件

我们通过指定文件的新路径和操作模式来创建/打开文件。操作可以是读取、写入、追加和截断。文件创建语法:FilePointer.open("Path",ios::mode);

  • 打开进行写入的文件示例:st.open("E:\studytonight.txt",ios::out);
  • 打开读取的文件示例:st.open("E:\studytonight.txt",ios::in);
  • 为追加打开的文件示例:st.open("E:\studytonight.txt",ios::app);
  • 为截断而打开的文件示例:st.open("E:\studytonight.txt",ios::trunc);
#include<iostream>
#include<conio>
#include <fstream>

using namespace std;

int main()
{
    fstream st; // Step 1: Creating object of fstream class
    st.open("E:\studytonight.txt",ios::out);  // Step 2: Creating new file
    if(!st) // Step 3: Checking whether file exist
    {
        cout<<"File creation failed";
    }
    else
    {
        cout<<"New file created";
        st.close(); // Step 4: Closing file
    }
    getch();
    return 0;
}

写入文件

#include <iostream>
#include<conio>
#include <fstream>

using namespace std;

int main()
{
    fstream st; // Step 1: Creating object of fstream class
    st.open("E:\studytonight.txt",ios::out);  // Step 2: Creating new file
    if(!st) // Step 3: Checking whether file exist
    {
        cout<<"File creation failed";
    }
    else
    {
        cout<<"New file created";
        st<<"Hello";    // Step 4: Writing to file
        st.close(); // Step 5: Closing file
    }
    getch();
    return 0;
}

这里我们发送输出到一个文件。所以,我们使用 ios::out。如程序中所给,在“文件指针<<“后的引号内键入的信息将被传递到输出文件。


从文件中读取

#include <iostream>
#include<conio>
#include <fstream>

using namespace std;

int main()
{
    fstream st; // step 1: Creating object of fstream class
    st.open("E:\studytonight.txt",ios::in);   // Step 2: Creating new file
    if(!st) // Step 3: Checking whether file exist
    {
        cout<<"No such file";
    }
    else
    {
        char ch;
        while (!st.eof())
        {
            st >>ch;  // Step 4: Reading from file
            cout << ch;   // Message Read from file
        }
        st.close(); // Step 5: Closing file
    }
    getch();
    return 0;
}

这里我们从一个文件中读取输入。所以,我们使用 ios::in。如程序中所给,输出文件中的信息是借助以下语法“文件指针> >变量”获得的。


关闭文件

FilePointer.close()完成。

#include <iostream>
#include<conio>
#include <fstream>

using namespace std;

int main()
{
    fstream st; // Step 1: Creating object of fstream class
    st.open("E:\studytonight.txt",ios::out);  // Step 2: Creating new file
    st.close(); // Step 4: Closing file
    getch();
    return 0;
}

文件中的特殊操作

很少有重要功能可用于文件流,例如:

  • tellp() - It tells the current position of the put pointer.

    语法: filepointer.tellp()

  • tellg() - It tells the current position of the get pointer.

    语法: filepointer.tellg()

  • seekp() - It moves the put pointer to mentioned location.

    语法: filepointer.seekp(字节数,引用模式)

  • seekg() - It moves get pointer(input) to a specified location.

    语法: filepointer.seekg((字节数,参考点)

  • put() -它将单个字符写入文件。

  • get() -从文件中读取单个字符。

注:对于 seekp 和 seekg 传递三个参考点:
ios::beg -文件开始
ios::cur -文件中当前位置
ios::end -文件结束

下面是一个展示tellptellgseekpseekg重要性的程序:

#include <iostream>
#include<conio>
#include <fstream>

using namespace std;

int main()
{
    fstream st; // Creating object of fstream class
    st.open("E:\studytonight.txt",ios::out);  // Creating new file
    if(!st) // Checking whether file exist
    {
        cout<<"File creation failed";
    }
    else
    {
        cout<<"New file created"<<endl;
        st<<"Hello Friends"; //Writing to file

        // Checking the file pointer position
        cout<<"File Pointer Position is "<<st.tellp()<<endl;  

        st.seekp(-1, ios::cur); // Go one position back from current position

        //Checking the file pointer position
        cout<<"As per tellp File Pointer Position is "<<st.tellp()<<endl; 

        st.close(); // closing file
    }
    st.open("E:\studytonight.txt",ios::in);   // Opening file in read mode
    if(!st) //Checking whether file exist
    {
        cout<<"No such file";
    }
    else
    {
        char ch;
        st.seekg(5, ios::beg);  // Go to position 5 from begning.
        cout<<"As per tellg File Pointer Position is "<<st.tellg()<<endl; //Checking file pointer position
        cout<<endl;
        st.seekg(1, ios::cur); //Go to position 1 from beginning.
        cout<<"As per tellg File Pointer Position is "<<st.tellg()<<endl; //Checking file pointer position
        st.close(); //Closing file
    }
    getch();
    return 0;
}

新创建的文件文件指针位置为 13 根据文件指针位置为 12 根据文件指针位置为 5 根据文件指针位置为 6



C++ 中的异常处理

原文:https://www.studytonight.com/cpp/exception-handling-in-cpp.php

错误可以大致分为两种类型。我们将逐一讨论。

  1. 编译时错误
  2. 运行时错误

编译时错误–编译时捕获的错误称为编译时错误。编译时错误包括库引用、语法错误或不正确的类导入。

运行时错误 -它们也被称为异常。运行时捕获的异常会产生严重的问题。

错误阻碍程序的正常执行。异常处理是以不妨碍系统正常执行的方式处理错误和异常的过程。例如,用户将一个数字除以零,这将编译成功,但会出现异常或运行时错误,这将导致我们的应用程序崩溃。为了避免这种情况,我们将在代码中引入异常处理技术。

在 C++ 中,错误处理是使用三个关键字完成的:

  • 尝试
  • 捕捉

语法:

try
{
    //code
    throw parameter;
}
catch(exceptionname ex)
{
    //code to handle exception
}

try区块

可以抛出任何异常的代码被保存在try块中。然后,当代码将导致任何错误时,该错误/异常将被捕获在catch块中。

catch区块

catch块旨在捕获错误并处理异常情况。我们可以有多个 catch 块来处理不同类型的异常,并在异常发生时执行不同的操作。例如,我们可以显示描述性消息来解释发生任何特定异常的原因。

throw声明

它用于向异常处理程序抛出异常,即用于传递有关错误的信息。throw表达式接受一个参数,并将该参数传递给处理程序。

throw语句用于当我们明确希望发生异常时,那么我们可以使用throw语句来抛出或生成该异常。


理解异常处理的需求

让我们举一个简单的例子来理解尝试、接球和投掷的用法。

下面的程序编译成功,但程序在运行时失败,导致异常。

#include <iostream>#include<conio.h>
using namespace std;
int main()
{
    int a=10,b=0,c;
    c=a/b;
    return 0;
}

上面的程序不会运行,会在屏幕上显示运行时错误,因为我们试图用 0 除一个数,这是不可能的。

如何处理这种情况?我们可以使用异常处理来处理这种情况,并且可以通过显示一条消息来通知用户您不能将一个数字除以零。


使用trycatchthrow语句

现在我们将更新上面的程序,并在其中包含异常处理。

#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
    int a=10, b=0, c;
    // try block activates exception handling
    try 
    {
        if(b == 0)
        {
            // throw custom exception
            throw "Division by zero not possible";
            c = a/b;
        }
    }
    catch(char* ex) // catches exception
    {
        cout<<ex;
    }
    return 0;
}

除以零是不可能的

在上面的代码中,我们正在检查除数,如果它为零,我们将抛出一个异常消息,然后catch块捕获该异常并打印该消息。

这样做,用户永远不会知道我们的程序在运行时失败了,他/她只会看到“除以零不可能”的消息。

这是优雅地处理异常情况,这就是为什么使用异常处理。


使用多个catch

下面的程序包含多个catch块,以不同的方式处理不同类型的异常。

#include <iostream>
#include<conio.h>
using namespace std;

int main()
{
    int x[3] = {-1,2};
    for(int i=0; i<2; i++)
    {
        int ex = x[i];
        try 
        {
            if (ex > 0)
                // throwing numeric value as exception
                throw ex;
            else
                // throwing a character as exception
                throw 'ex';
        } 
        catch (int ex)  // to catch numeric exceptions
        {
            cout << "Integer exception\n";
        } 
        catch (char ex) // to catch character/string exceptions
        {
            cout << "Character exception\n";
        }
    }
}

整数异常字符异常

上面的程序不言而喻,如果数组x中整数的值小于 0,我们抛出一个数值作为异常,如果值大于 0,那么我们抛出一个字符值作为异常。我们有两个不同的catch块来捕捉这些异常。


C++ 中的广义catch

下面的程序包含一个通用的catch块来捕获任何未捕获的错误/异常。catch(...) block 处理所有类型的异常。

#include <iostream>
#include<conio.h>
using namespace std;

int main()
{
    int x[3] = {-1,2};
    for(int i=0; i<2; i++)
    {
        int ex=x[i];
        try 
        {
            if (ex > 0)
                throw ex;
            else
                throw 'ex';
        } 
        // generalised catch block
        catch (...) 
        {
            cout << "Special exception\n";
        }
    }
return 0;
}

特殊例外特殊例外

在上面的例子中,两个异常都被一个单独的catch块捕获。我们甚至可以有单独的catch块来处理整数和字符异常,以及通用的catch块。


C++ 中的标准异常

下的 C++ 中有一些标准的异常,我们可以在程序中使用。它们排列在父子类层次结构中,如下所示:

  • std::exception -所有标准 C++ 异常的父类。
  • 逻辑 _ 错误 -程序内部逻辑发生异常。
    • 域 _ 错误 -使用无效域导致异常。
    • 无效参数 -因无效参数导致异常。
    • 超出范围 -超出范围导致异常,即大小要求超过分配。
    • 长度 _ 误差 -长度误差导致异常。
  • 运行时 _ 错误 -运行时发生异常。
    • 范围 _ 错误 -由于内部计算中的范围错误而导致异常。
    • 溢出 _ 错误 -算术溢出错误导致异常。
    • 下溢 _ 错误 -由于算术下溢错误导致的异常
  • bad_alloc -使用 new()分配内存失败时出现异常。
  • bad_cast -动态 cast 失败时出现异常。
  • bad_exception - Exception 是专门设计在动态异常说明符中列出的。
  • 坏 _ type id-type id 抛出异常。


C++ 中的动态内存分配

原文:https://www.studytonight.com/cpp/memory-management-in-cpp.php

以下是任何 C++ 程序使用的基本内存架构:

Memory Management in C++

  • 代码段:带有执行指令的编译程序保存在代码段中。它是只读的。为了避免栈和堆的过度写入,代码段保持在栈和堆的下面。
  • 数据段:全局变量和静态变量保存在数据段中。它不是只读的。
  • :栈通常是预分配的内存。栈是后进先出数据结构。每个新变量都被推送到栈上。一旦变量超出范围,内存就会被释放。一旦栈变量被释放,该内存区域就可用于其他变量。当函数推送和弹出局部变量时,栈会增长和收缩。它存储本地数据、返回地址、传递给函数的参数以及内存的当前状态。
  • :程序执行时分配内存。使用新操作符分配内存,使用删除操作符释放内存。

使用new关键字分配堆内存

这里我们将学习如何使用new关键字为变量或类对象分配堆内存。

语法:

datatype pointername = new datatype

例如:

int *new_op = new int;
// allocating block of memory
int *new_op = new int[10];

如果在中没有足够的内存可用,则通过抛出类型为std::bad_alloc的异常来指示,并返回一个指针。


使用delete关键字释放内存

一旦使用new关键字将堆内存分配给变量或类对象,我们就可以使用delete关键字取消分配该内存空间。

语法:

delete pointer variable

例如:

delete new_op;

对象的范围或对象的生存期是在程序执行期间对象保留在内存中的时间。堆内存分配比慢。在堆中,内存分配没有特定的顺序,就像在栈中一样。


理解 C++ 中的内存泄漏

内存泄漏是由于内存分配和释放管理不善造成的。多发生在动态内存分配的情况下。C++ 中没有像 Java 那样的自动垃圾收集,所以程序员负责释放指针使用的内存。

现实生活中滥用建筑物中的电梯是内存泄漏的一个例子。假设你住在一栋 19 层的公寓楼里。你想去 10 层所以你按了按钮叫电梯。电梯状态显示为地下室 20 分钟。然后你意识到有些不对劲,经过调查你发现孩子们在地下室玩耍,他们堵住了电梯门。

类似地,一旦指针完成了它的操作,它应该释放它所使用的内存。以便其他变量可以使用内存,并且可以有效地管理内存。

通过使用delete关键字,我们可以删除分配的内存:

例如:

*ex= new Example();
delete ex;

但是在上面的例子中悬空指针的问题可能会发生。等等!什么是悬空指针?


什么是悬空指针?

指向已删除对象的内存位置的指针被称为悬挂指针。

Memory Management

  • 在第一幅图中,指针指向包含值 25 的存储单元 1100。
  • 在第二幅图中,指针指向删除对象的存储位置。

悬空指针是由于对象破坏而产生的,当对象引用被删除或解除分配时,不修改指针的值,因此指针将继续指向相同的内存位置。这个问题可以通过将指针初始化为NULL来避免。

例如:

*ex = new Example();
Delete ex;
// assigning the pointer to NULL
ex = NULL;

什么是智能指针?

智能指针用于管理动态分配对象的生存期。它们确保正确销毁动态分配的对象。智能指针在内存头文件中定义。

智能指针是内置指针,我们不用担心删除它们,它们是自动删除的。

下面是一个智能指针的例子:

S_ptr *ptr = new S_ptr();
ptr->action();
delete ptr;


C++ 中的多线程

原文:https://www.studytonight.com/cpp/multithreading-in-cpp.php

多线程意味着两个或多个线程同时运行,每个线程处理不同的任务。当你登录你的脸书个人资料时,在你的新闻提要上,你可以看到实时视频,你可以评论或点击一个喜欢的按钮,一切都同时进行。这是多线程的最好例子。多线程环境允许您同时运行许多活动;其中不同的线程负责不同的活动。

多线程有多种用途,其中一些是:

  • 更好的资源利用。
  • 更简单的程序设计。
  • 反应更灵敏的程序。

什么是线?

线程通常被称为轻量进程。每个线程执行程序的不同部分。每个线程共享内存、文件描述符和其他系统资源。在 Linux 中,所有线程函数都是在 < pthread.h > 头文件中声明的。但是它在标准的 C++ 库中不可用。


在 Linux(C++)中创建线程

  1. pthread_create(): It creates a new thread. Below is the syntax:

    pthread_create(threadID, attr, start_routine, arg)
    

    在上面的代码中:

    线程号:是每个线程的唯一标识符。使用pthread_equal()功能比较线程的线程 ID。

    属性:可以用来设置各种线程属性的属性对象。它控制线程与程序其余部分的交互。

    start_routine :线程一旦创建就要执行的 C++ 例程。

    arg :单个参数必须作为 void 类型的指针通过引用传递。如果不传递参数,可以使用 null。

  2. pthread_exit():用于终止任意线程。

下面是一个用 C++ 创建线程的简单程序:

#include <iostream>
#include <pthread.h>
using namespace std;

char* str = "Child thread";

void* func(void *str)
{
    cout << "Child thread Created: " << (char*)str;
}
// main function
int main()
{
    s = ctime(&Time);
    // Step 1: Declaring thread
    pthread_t t;    
    // Step 2: Calling create thread function
    pthread_create(&t, NULL, &func, (void*)str); 
    /*
        Syntax for pthread_create is:
        pthread_create(threadID,attr,start_routine,arg)
        Here,
        threadID = t, arg = (void*)str, atrr = Null, start_routine = func
    */
    cout << "Main thread created" << endl;
    pthread_join(t, NULL);
    //Exiting after completion
    exit(EXIT_SUCCESS); 
    return 0;
}

主线程已创建子线程已创建:子线程


连接和分离螺纹

我们可以使用两种方法来连接或分离线程:

join()功能

通过使用线程类的join()函数来连接线程。它使主线程和子线程相互依赖。主线程仅在子线程终止后终止,即主线程等待子线程完成执行。

语法:

threadname.join();

一旦所有功能完成,它就会返回。当一个线程被分配给另一个线程或调用join()detach()时,它是不可连接的。

语法:

/* 
    It checks whether a thread is joinable. 
    It returns bool value.
*/
threadname.joinable(); 

detach()功能

detach()函数从父线程中分离一个线程。它允许主线程和子线程独立执行。

语法:

threadname.detach();

使用join()方法的程序示例

让我们举一个简单的例子来演示使用join()函数连接两个线程:

#include <iostream>
#include <unistd.h>   // To include sleep function
#include<ctime>   // To get system time
#include <pthread.h>
using namespace std;

string s;
time_t Time = time(0);

void* func(void*)
{
    s = ctime(&Time);
    sleep(1);   //C alls sleep function
    cout << "Child thread Created " << s << endl;
}

// main function
int main()
{
    s = ctime(&Time);
    //Step 1: Declaring thread
    pthread_t t1[5];
    for(int i=0; i<5; i++)
    {
        cout << "Thread T[" << i << "] is Created " << s << endl;
        // Step 2: calling create thread function
        pthread_create(&t1[i], NULL, &func, NULL); 
        // Joining threads, main thread waits for child thread to complete
        pthread_join(t1[i], NULL); 
}
//Exiting after completion
exit(EXIT_SUCCESS); 
return 0;
}

线程 T[0]于 2017 年 11 月 1 日星期三 02:30:57 创建子线程于 2017 年 11 月 1 日星期三 02:30:57 创建线程 T[1]于 2017 年 11 月 1 日星期三 02:30:57 创建子线程于 2017 年 11 月 1 日星期三 02:30:57 创建线程 T[2]于 2017 年 11 月 1 日星期三 02:30:57 创建子线程 T[3]于 2017 年星期三创建


使用detach()方法的程序示例

让我们举一个简单的例子来演示使用join()函数分离两个线程:

#include <iostream>
#include <unistd.h>   // To include sleep function
#include<ctime>   // To get system time
#include <pthread.h>
using namespace std;

string s;
time_t Time = time(0);

void* func(void*)
{
    s = ctime(&Time);
    sleep(1);   // Calls sleep function
    cout << "Child thread Created " << s << endl;
}

// main function
int main()
{
    s = ctime(&Time);
    // Step 1: Declaring thread
    pthread_t t1[5]; 
    for(int i=0; i<5; i++)
    {
        cout << "Thread T[" << i << "] is Created " << s << endl;
        // Step 2: Calling create thread function
        pthread_create(&t1[i], NULL, &func, NULL); 
        // Step 3: main thread doesn't waits for child thread to complete
        pthread_detach(t1[i]); 
}
// Exiting after completion
exit(EXIT_SUCCESS); 
return 0;
}

线程 T[0]于 2017 年 11 月 1 日星期三 02:38:14 创建线程 T[1]于 2017 年 11 月 1 日 02:38:14 创建线程 T[2]于 2017 年 11 月 1 日 02:38:14 创建线程 T[3]于 2017 年 11 月 1 日 02:38:14 创建线程 T[4]于 2017 年 11 月 1 日 02:38:14 创建

Hoope 你已经理解了 C++ 中线程创建的概念。



STL

容器

STL 简介:标准模板库

原文:https://www.studytonight.com/cpp/stl/stl-introduction

STL 是标准模板库的缩写。它是一组 C++ 模板类,提供可用于实现数据结构和算法的泛型类和函数。STL 主要由以下部分组成:

  1. 算法
  2. 容器
  3. 迭代程序

Introduction to STL

STL 提供了大量的容器和算法,在复杂编程中非常有用,例如在 STL 中使用容器库的列表容器,可以非常容易地在一条语句中定义一个链表,省时省力。

STL 是一个通用库,即相同的容器或算法可以在任何数据类型上操作,您不必为不同类型的元素定义相同的算法。

例如,排序算法将对给定范围内的元素进行排序,而不考虑它们的数据类型,我们不必为不同的数据类型实现不同的排序算法。


c++:STL 中的算法

STL 提供了许多可以在任何容器中使用的算法,而不考虑它们的类型。算法库包含在数据结构上执行复杂算法的内置函数。

例如:可以用reverse()功能反转一个范围,用sort()功能排序一个范围,用binary_search()搜索一个范围等等。

算法库提供了抽象,也就是说你不一定需要知道算法是如何工作的。


c++:STL 中的容器

STL 中的容器库提供了用于创建数据结构的容器,如数组、链表、树等。

这些容器是通用,它们可以保存任何数据类型的元素,例如: vector 可以用来创建 char、integer、float 和其他类型的动态数组。


c++:STL 中的迭代器

STL 中的迭代器用于指向容器。迭代器实际上充当了容器和算法之间的桥梁。

例如:sort()算法有两个参数,开始迭代器和结束迭代器,现在 sort()比较这些迭代器中的每一个指向的元素,并按照排序的顺序排列它们,因此容器的类型是什么并不重要,相同的 sort()可以用于不同类型的容器。


STL 的使用与应用

STL 是一个通用库,它提供了可用于存储和操作不同类型数据的容器和算法,因此它使我们不必从头定义这些数据结构和算法。因为有了 STL,现在我们不用每次做新程序都定义我们的排序函数,也不用为不同的数据类型定义同一个函数两次,取而代之的是我们可以只使用 STL 中的泛型容器和算法。

这在编程过程中节省了大量的时间、代码和精力,因此 STL 在竞争性编程中被大量使用,而且它可靠且快速。



什么是 STL 中的容器?

原文:https://www.studytonight.com/cpp/stl/stl-overview-of-containers

STL 中的容器库给了我们容器,用最简单的话来说,可以描述为用于包含数据的对象,或者更确切地说是对象的集合。容器帮助我们非常容易地实现和复制简单和复杂的数据结构,如数组、列表、树、关联数组等等。

容器被实现为通用类模板,这意味着一个容器可以用来容纳不同种类的对象,并且它们本质上是动态的!

以下是一些常见的容器:

  • 向量:复制数组
  • 队列:复制队列
  • 堆叠:复制堆叠
  • 优先级队列:复制堆
  • 列表:复制链表
  • 设置:复制树木
  • 映射:关联数组

STL 中容器的分类

容器分为四类:

  • 序列容器:用于实现数组(array)和链表(list)等本质上是序列的数据结构。
  • 关联容器:用于实现映射、集合等排序后的数据结构。
  • 无序关联容器:用于实现无序的数据结构。
  • 容器适配器:用于为序列容器提供不同的接口。

在 STL 中使用容器库

下面是一个实现链表的例子,首先通过使用结构,然后通过列表容器。

#include <iostream>

struct node
{
    int data;
    struct node * next;
}

int main ()
{
    struct node *list1 = NULL;
}

上面的程序只是创建了一个列表节点,没有定义插入和删除函数,要做到这一点,你需要写更多的代码。

现在让我们看看如何使用容器库来简化它。当我们使用列表容器来实现链表时,我们只需要包含列表头文件,并使用列表构造器来初始化列表。

#include <iostream>
#include <list>

int main ()
{
    list<int> list1; 
} 

就这样!我们有一个列表,不仅如此,容器库还提供了所有不同的方法,可用于对列表执行不同的操作,如插入、删除、遍历等。

因此,您可以看到,使用容器库实现数据结构非常容易。



STL 中的偶对模板

原文:https://www.studytonight.com/cpp/stl/stl-pair-template

注意:虽然 Pair 和 Tuple 实际上不是容器库的一部分,但是我们仍然会讨论它们,因为它们是编程竞赛中非常常见的需求,并且它们使得某些事情非常容易实现。

对的语法是:

pair<T1,T2>  pair1, pair2 ;

上面的代码创建了两对,即第一对 1 和第二对 2,它们都有第一个 T1 类型的对象和第二个 T2 类型的对象。

现在 T1 将被称为第一个,T2 将被称为配对 1 和配对 2 的第二个成员。

Example of Pair


偶对模板:一些常用函数

以下是偶对模板一些功能:

  • 运算符=:给一对赋值。
  • 交换:交换配对的内容。
  • make_pair():创建并返回一个包含由参数列表定义的对象的对。
  • 运算符(==,!=,>,< , <= , > =):按字典顺序比较两对。

演示结偶对模板的程序

#include <iostream>

using namespace std;    

int main ()
{
   pair<int,int> pair1, pair3;    //creats pair of integers
   pair<int,string> pair2;    // creates pair of an integer an a string

   pair1 = make_pair(1, 2);     // insert 1 and 2 to the pair1
   pair2 = make_pair(1, "Studytonight") // insert 1 and "Studytonight" in pair2
   pair3 = make_pair(2, 4)
   cout<< pair1.first << endl;  // prints 1, 1 being 1st element of pair1
   cout<< pair2.second << endl; // prints Studytonight

   if(pair1 == pair3)
        cout<< "Pairs are equal" << endl;
   else
        cout<< "Pairs are not equal" << endl;

   return 0;
} 


STL 中的元组

原文:https://www.studytonight.com/cpp/stl/stl-tuple-template

tuplepair的结构非常相似。就像配对一样,我们可以配对两个异构对象,在元组中,我们可以配对三个异构对象。

元组的语法是:

// creates tuple of three object of type T1, T2 and T3
tuple<T1, T2, T3> tuple1; 

Tuple Template


元组模板:一些常用函数

与 pair 类似,tuple 模板有自己的成员和非成员函数,下面列出了其中的一些函数:

  • 构造新元组的构造器
  • 运算符 = :为元组赋值
  • 交换:交换二元组的值
  • make_tuple():创建并返回一个包含由参数列表描述的元素的元组。
  • 运算符(==,!=,>,< , <= , > =):按字典顺序比较两对。
  • 元组元素:返回元组元素的类型
  • 联系:将元组的值与其引用联系起来。

演示元组模板的程序

#include <iostream>

int main ()
{
   tuple<int, int, int> tuple1;   //creates tuple of integers
   tuple<int, string, string> tuple2;    // creates pair of an integer an 2 string

   tuple1 = make_tuple(1,2,3);  // insert 1, 2 and 3 to the tuple1
   tuple2 = make_pair(1,"Studytonight", "Loves You");
   /* insert 1, "Studytonight" and "Loves You" in tuple2  */

   int id;
   string first_name, last_name;

   tie(id,first_name,last_name) = tuple2;
   /* ties id, first_name, last_name to 
   first, second and third element of tuple2 */

   cout << id <<" "<< first_name <<" "<< last_name;
   /* prints 1 Studytonight Loves You  */

   return 0;
} 


STL 中的数组容器

原文:https://www.studytonight.com/cpp/stl/stl-container-array

众所周知,数组是同质对象的集合。STL 中的数组容器为我们提供了静态数组的实现,尽管它在竞争性编程中很少使用,因为它本质上是静态的,但我们仍然会讨论数组容器,因为它提供了一些成员函数和非成员函数,这使它比经典定义的数组有优势,比如 int array_name[array_size]。

数组容器的语法:

array<object_type, array_size> array_name;

上面的代码创建了一个空的对象类型数组,其最大大小为数组大小。但是,如果要创建一个包含元素的数组,只需使用 = 操作符即可,下面是一个例子:

#include <vector>

int main()
{
    array<int, 4> odd_numbers = { 2, 4, 6, 8 };
} 

上面的语句将创建一个数组,数组中的数据为 2,4,6,8。请注意,只有在 c++ 17 中才能使用{}括号进行初始化。


数组模板的成员函数

以下是数组模板中最重要和最常用的成员函数。

at功能

此方法返回数组中给定范围内的值。如果给定范围大于数组大小,则抛出超出范围异常。下面的代码片段解释了这个操作符的用法:

#include <iostream>
#include <array>

using namespace std;

int main ()
{
    array<int,10> array1 = {1,2,3,4,5,6,7,8,9};

    cout << array1.**at**(2)     // prints 3
    cout << array1.**at**(4)     // prints 5

}

[ ]运算符

运算符 [ ] 的使用与普通数组相同。它返回数组中给定位置的值。示例:在上面的代码中,语句cout << array1[5];将在控制台上打印 6,因为 6 在数组 1 中有索引 5。

front()功能

此方法返回数组中的第一个元素。

back()功能

此方法返回数组中的最后一个元素。这里需要注意的是,如果数组没有完全填充,back()将返回数组中最右边的元素。

fill()功能

此方法将给定值赋给数组的每个元素,例如:

 #include <array>
int main()
{
    array<int,8> myarray;
    myarray.**fill**(1);
} 

这将在数组 myarray 的所有 8 个可用位置用值 1 填充数组 my array。

swap功能

此方法交换相同类型和相同大小的两个数组的内容。它按索引方式交换,因此第一个数组的索引 i 的元素将与第二个数组的索引 i 的元素交换,如果交换这两个元素中的任何一个都需要 execption,swap()将引发异常。下面是一个演示其用法的示例:

 #include <array>

int main()
{
    array<int,8> a = {1,2,3,4,5,6,7,8};
    array<int,8> b = {8,7,6,5,4,3,2,1};

    a.**swap**(b)  // swaps array a and b

    cout << "a is : ";
    for(int i=0; i < 8; i++) {
    cout << a[i] <<" ";
    }
    cout << endl;
    cout << "b is : ";
    for(int i=0; i < 8; i++) {
    cout << a[i] <<" ";
    }
    /* ouput will be 
    a is : 8 7 6 5 4 3 2 1
    b is : 1 2 3 4 5 6 7 8 */
} 

运算符(==,!=,>,< , > =,< =)

所有这些运算符都可以用来按字典顺序比较两个数组的值。

empty功能

这个方法可以用来检查数组是否为空。

语法:array_name.empty(),如果数组为空则返回真,否则返回假。

size功能

此方法返回数组中存在的元质数量。

max_size功能

此方法返回数组的最大大小。

begin功能

这个方法返回指向数组第一个元素的迭代器。迭代器就像指针,我们将在以后的课程中讨论它们,因为现在你可以把迭代器想象成指向数组的指针。

Begin and End in array

end功能

这个方法返回一个迭代器,指向数组中最后一个元素旁边的元素,例如上面的数组有 4 个元素,end()调用将返回指向数组第 4 个索引的迭代器。



STL 中的向量容器

原文:https://www.studytonight.com/cpp/stl/stl-container-vector

当我们必须实现像数组这样的顺序数据结构时,一个数组工作得很好,除了它是静态的,也就是说,我们必须在它的初始化期间定义它的最大大小,并且它不能包含大于它的最大大小的元素。现在假设,如果在程序执行期间,我们必须存储超过其大小的元素,或者如果我们正在读取元素的输入流,并且我们不知道元质数量的上限,则很有可能出现 index_out_bound 异常或程序意外终止。

我们可以做一件事,用编译器允许的最大尺寸初始化数组,即每个数组10^6个元素,但这是一种非常消耗空间的方法,如果要输入的元质数量太少,就会浪费空间,因此这种方法在编程中从未使用过。

上述问题的解决方案是动态数组!它们具有动态大小,即它们的大小可以在运行时改变。容器库提供向量来复制动态数组。

创建向量的语法是:vector< object_type > vector_name;

例如:

#include <vector>

int main()
{
    std::**vector**<int> my_vector;
} 

Vector 是一个动态数组,在声明过程中不需要大小,因此上面的代码将创建一个空白向量。有很多方法可以初始化一个向量,

#include <vector>

int main()
{
    std::**vector**<string> v {"Pankaj" ,"The" ,"Java" ,"Coder"};
} 

Vector declaration and data entry

请注意,这种类型的初始化仅适用于 C++ 11 及更高版本。您也可以根据其他向量的范围初始化向量,例如:

#include <vector>

int main()
{
    std::**vector**<string> v(v1.begin(), v1.end());
} 

上面的代码通过由 v1.begin()和 v2.end()返回的迭代器所指向的元素来初始化向量,begin()和 end()是我们用数组研究过的相同函数,它们对向量的工作方式相同。

您也可以用一个元素初始化一个向量一定次数,例如:

#include <vector>

int main()
{
    std::**vector**<string> v(4 , "test");
} 

same element at all positions in vector

这些是初始化向量的方法之一,但是请记住,使用另一个向量或直接使用元素来初始化向量并不会限制它的大小,它的大小将始终是动态的,并且在需要时可以在向量中插入更多的元素。


向量的成员函数

以下是 STL 中矢量容器最常用的一些函数:

push_back功能

push_back()用于在向量末尾插入一个元素。如果 push_back()中作为参数传递的对象类型与向量的类型不同,或者不可相互转换,则会引发异常。

下图将显示 push_back()的工作原理:

push_back working

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    **vector**<int>  v;
    v.**push_back**(1);  *//insert 1 at the back of v*
    v.**push_back**(2);  *//insert 2 at the back of v*
    v.**push_back**(4);  *//insert 3 at the back of v*

    for(vector<int>::iterator i = v.begin(); i != v.end(); i++) 
    {
          cout << *i <<" ";   *// for printing the vector*
    }
} 

1 2 4

insert功能

insert(itr, element)方法将向量中的元素插入迭代器 itr 指向的位置之前。

下图将展示插入是如何工作的:

insert one element in vector

插入函数可以被第三个参数重载,计数也一样。此 count 参数定义元素在指向位置之前插入的次数。

insert single element multiple times in vector

这个方法也可以用来插入给定范围内任何其他向量的元素,由两个迭代器指定,定义范围的起点和终点。

v.insert(i, v2.begin(), v2.end());

上面的代码将在 i 所指向的索引之前插入从 v2.begin()到 v2.end()的元素。

pop_back功能

pop_back()用于从向量中移除最后一个元素。它将向量的大小减少了一。

下面是一个例子:

pop_back example

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    **vector**<int> v1 {10,20,30,40};

    v1.**pop_back**();  

    vector<int>::iterator it;

    for(it = v.begin(); it != v.end(); it++) 
    {
        cout << *it <<" ";   // for printing the vector
    }
} 

10 20 30

erase功能

erase(itr_pos)移除迭代器指向的元素。erase 方法也可以重载一个额外的迭代器,指定要移除的范围的终点,即erase(itr_start, itr_end)

以下代码将说明擦除:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vecto<int>v1 {10,20,30,40};
    vector<int>iterator:: it = v.begin();

    v.**erase**(it);   //removes first element from the vector

    v.**erase**(v1.begin(), v1.end() - 2 )  
    /*removes all the elements except last two */

    for(it = v.begin(); it != v.end(); it++) 
    {
        cout << *it <<" ";   // for printing the vector
    }
}

30 40

resize功能

resize(size_type n, value_type val)方法将向量调整到 n 元素。如果向量的当前大小大于 n ,则从向量中移除尾部元素,如果当前大小小于nn,则在向量后面插入额外的 val 元素。

例如,如果现在向量的大小为 4,元素为{10,20,30,40},我们使用resize方法将其大小调整为 5。那么默认情况下,值为 0 的第五个元素将被插入到矢量中。我们可以指定数据不为零,在调用 resize 方法时将其显式地称为 val

swap功能

这个方法交换两个向量的值。

如果我们有两个向量 v1 和 v2,我们想交换其中的元素,你只需要调用v1.swap(v2),这将交换两个向量的值。

clear功能

该方法清除整个向量,从向量中移除所有元素,但不删除向量。

语法:clear()

对于向量 vv.clear()会清除它,但不会删除它。

size功能

这个方法返回向量的大小。

empty功能

如果向量为空,此方法返回 true,否则返回 false。

capacity功能

此方法根据分配给向量的内存返回可插入向量的元质数。

at功能

这个方法在向量的情况下和在数组的情况下一样有效。vector_name.at(i)返回向量向量 _ 名称中带有索引的处的元素。

frontback功能

vector_name.front()重新运行向量前面的元素(即最左边的元素)。而vector_name.back()返回向量后面的元素(即最右边的元素)。



STL 中的列表容器

原文:https://www.studytonight.com/cpp/stl/stl-container-list

数组和向量是连续的容器,即它们将数据存储在连续的内存中,因此向量/数组中间的插入操作非常昂贵(就操作数量和处理时间而言),因为我们必须移动所有元素,链表克服了这个问题。链表可以通过使用列表容器来实现。

使用列表模板创建新链接列表的语法为:

#include <iostream>
#include <list>

int main()
{
    std::**list**<int> l;
}
/* Creates a new empty linked list l */ 

类似于向量和数组,列表也可以用参数初始化,

#include <iostream>
#include <list>

using namespace std;

int main()
{
    std::**list**<int> l{1,2,3};
}
/* Creates a new linked list l */ 

List creation example

以下是我们初始化列表的更多方法:

#include <iostream>
#include <list>

int main()
{
    **list**<int> myList{1,2,3};
    /* creates list with 1,2,3 in it */

    **list**<int> myNewList = 1;
    /*  create list myNewList of integer 
        and copies value of 1 into it*/
} 

列表容器的成员函数

insert功能

顾名思义,这个方法在列表中的特定位置插入一个元素。insert()有三种变体,如下所示:

  • insert(iterator, element):在列表中迭代器指向的位置之前插入元素
  • insert(iterator, count, element):在列表中迭代器指向的位置前插入元素,计数次。
  • insert(iterator, start_iterator, end_iterator):在迭代器指向的位置之前,将 start_iterator 指向的元素插入 end_iterator 指向的元素
#include <iostream>
#include <list>

using namespace std;

int main()
{
    **list**<int> l = {1,2,3,4,5};
    **list**<int>::iterator it = l.begin();           

    l.**insert** (it+1, 100);    // insert 100 before 2 position
    /* now the list is 1 100 2 3 4 5 */

    **list**<int> new_l = {10,20,30,40};   // new list

    new_l.**insert** (new_l.**begin()**, l.**begin()**, l.**end()**);
    /* 
        insert elements from beginning of list l to end of list l 
        before 1 position in list new_l */

    /* now the list new_l is 1 100 2 3 4 5 10 20 30 40 */

    l.**insert**(l.**begin()**, 5, 10);  // insert 10 before beginning 5 times
    /* now l is 10 10 10 10 10 1 100 2 3 4 5 */

    return 0;
}

push_backpush_front功能

push_back(element)方法用于将元素从后面推入列表。

Push elements from back in Lists

push_front(element)方法用于将元素从前面推入列表。

Push elements from front in Lists

#include <iostream>
#include <list>

using namespace std;

int main()
{
    **list**<int> l{1,2,3,4,5};

    l.**push_back**(6);
    l.**push_back**(7);
    */* now the list becomes 1,2,3,4,5,6,7 */*

    l.**push_front**(8);
    l.**push_front**(9);
    */* now the list becomes 9,8,1,2,3,4,5,6,7 */*

}

pop_backpop_front功能

pop_front()从列表开始处移除第一个元素。而pop_back()从列表末尾移除第一个元素。

#include <iostream>
#include <list>

using namespace std;

int main()
{
    **list**<int> l{1,2,3,4,5};

    l.**pop_back()**();
    */* now the list becomes 1,2,3,4 */*

    l.**pop_front()**();
    */* now the list becomes 2,3,4 */*
} 

empty功能

如果列表为空,此方法返回 true,否则返回 false。

size功能

此方法可用于查找列表中存在的元质数量。

front and back功能

front()用于从开始获取列表的第一个元素,而back()用于从后面获取列表的第一个元素。

swap功能

交换两个列表,如果在交换任何元素时有异常抛出,swap()抛出异常。要交换的两个列表必须是相同的类型,即不能用字符串列表交换整数列表。

reverse功能

此方法可用于完全反转列表。

#include <iostream>
#include <list>

using namespace std;

int main()
{
    **list**<int> l{1,2,3,4,5};

    l.**reverse**();
    */* now the list becomes 5,4,3,2,1 */*
} 

sort功能

sort()方法对给定列表进行排序。它不会创建新的排序列表,但会更改现有列表中元素的位置以对其进行排序。这种方法有两种变体:

  • sort():对列表中的元素进行升序排序,对于此功能,列表中的元素应该是数字。
  • sort(compare_function):这种排序()是在我们不得不改变排序方式的时候使用的。它对非数字元素非常有帮助。我们可以定义如何在 compare _ funtion 中对列表元素进行排序。例如,字符串列表可以按字符串的长度排序,也可以按降序排序。
#include <iostream>
#include <list>

using namespace std;

bool compare_function( string& s1 , string& s2 )
{
    return ( s1.length() > s2.length() );
}

int main()
{
    **list**<int> list1 = {2,4,5,6,1,3};
    **list**<string> list2 = {"h", "hhh", "hh"};

    list1.**sort**();
    */* list1 is now 1 2 3 4 5 6 */*

    list2.**sort**(compare_function);
    */* list2 is now h hh hhh */* 
}

splice功能

splice()方法将元素从一个列表转移到另一个列表。拼接有三种版本:

  • splice(iterator, list_name):在迭代器指向的位置传送完整的列表列表名
  • splice(iterator, list_name, iterator_pos):将迭代器 _pos 指向的元素从列表 _ 名称转移到迭代器指向的位置。
  • splice(iterator, list_name, itr_start, itr_end):从列表名称迭代器指向的位置开始, itr_startitr_end 指定的传送范围。
#include <iostream>
#include <list>

using namespace std;

int main ()
{
    **list**<int> list1 = {1,2,3,4};
    **list**<int> list2 = {5,6,7,8};
    **list**<int>::iterator it;

    it = list1.**begin**();
    ++it;   *//pointing to second position*           

    list1.**splice**(it, list2);
    */* transfer all elements of list2 at position 2 in list1 */
    /* now list1 is 1 5 6 7 8 2 3 4 and list2 is empty */*

    list2.**splice**(list2.**begin**(), list1, it);
    */* transfer element pointed by it in list1 to the beginning of list2 */
    /* list2 is now 5 and list1 is 1 6 7 8 2 3 4*/*

    return 0;
}

merge功能

合并两个排序列表。必须首先对这两个列表进行排序。merge()合并两个列表,使得每个元素都被放置在结果列表中的适当位置。合并的语法是list1.merge(list2)

作为参数传递的列表不会被删除,调用 merge()的列表将成为合并列表

#include <iostream>
#include <list>

using namespace std;

int main ()
{
    **list**<int> list1 = {1,3,5,7,9};
    **list**<int> list2 = {2,4,6,8,10};

    */* both the lists are sorted. In case they are not , 
    first they should be sorted by sort function() */*

    list1.**merge**(list2);

    */* list list1 is now 1,2,3,4,5,6,7,8,9,10  */*

    cout << list1.**size**() << endl;    *// prints 10* 
}

词典式比较列表

由于列表是元素的集合,因此它们没有自己的标准值。因此,为了比较列表或向量,我们按照字典顺序比较它们的元素。

例如,让 list1 = { 1,2,3}和 list2 = { 1,3,2 },现在,如果我们想检查 list1 是否大于 list2,我们只需按照列表中出现的顺序检查每个列表的元素。因为列表 1 中的 1 等于列表 2 中的 1,我们继续,现在列表 1 中的 2 比列表 2 中的 3 小,因此列表 2 在词典上大于列表 1。

运算符==><<=>=可用于按字典顺序比较列表。



STL 中的映射容器

原文:https://www.studytonight.com/cpp/stl/stl-container-map

映射用于复制关联数组。映射包含排序的键值对,其中每个键都是唯一的,不能更改,可以插入或删除,但不能更改。与键关联的值可以更改。我们可以在O(n)时间复杂度内搜索、移除和插入映射。

例如:以卷号为键,以为值的学生映射,可以图形化表示为:

First example of Maps in STL

请注意,键是按升序排列的,因为映射总是按排序顺序排列键。如果键是字符串类型的,则按字典顺序排序。


用 C++ STL 创建映射

使用以下语句可以轻松创建映射:

**map**<key_type , value_type> *map_name*;

这将创建一个键类型为键类型为值类型为值类型为的映射。需要记住的一点是,映射的键和相应的值总是成对插入,您不能在映射中只插入键或值。

下面是一个程序,将说明如何以不同的方式创建映射:

 #include <iostream>
#include <map>

using namespace std;

int main ()
{
    **map**<int,int> m{ {1,2} , {2,3} , {3,4} };
    */* creates a map m with keys 1,2,3 and 
        their corresponding values 2,3,4 */*  

    **map**<string,int> map1; 
    */*  creates a map with keys of type character and 
      values of type integer */*

    map1["abc"]=100;    *// inserts key = "abc" with value = 100*
    map1["b"]=200;      *// inserts key = "b" with value = 200*
    map1["c"]=300;      *// inserts key = "c" with value = 300*
    map1["def"]=400;    *// inserts key = "def" with value = 400*

    **map**<char,int> map2 (map1.begin(), map1.end());
    */* creates a map map2 which have entries copied 
        from map1.begin() to map1.end() */* 

    **map**<char,int> map3 (m);
    */* creates map map3 which is a copy of map m */*
} 

C++ STL 中映射的成员函数

以下是 STL 中映射容器的一些常用功能:

at[ ]

位于和[ ]都用于访问映射中的元素。它们之间唯一的区别是处的在被访问的键不在映射中时抛出异常,另一方面,如果该键不在映射中,运算符[ ]将该键插入到映射中。

#include <iostream>
#include <map>

using namespace std;

int main ()
{
    **map**<int,string> m{ {1,”nikhilesh”} , {2,”shrikant”} , {3,”ashish”} };

    cout << m.**at**(1) ;  *// prints value associated with key 1 ,i.e nikhilesh*
    cout << m.**at**(2) ;  *// prints value associated with key 2 ,i.e shrikant*

    */* note that the parameters in the above at() are the keys not the index */*

    cout << m[3] ; *// prints value associated with key 3 , i.e ashish*

    m.**at**(1) = "vikas";   *// changes the value associated with key 1 to vikas*
    m[2] = "navneet";   *// changes the value associated with key 2 to navneet*

    m[4] = "doodrah";   
    */* since there is no key with value 4 in the map, 
        it insert a key-value pair in map with key=4 and value = doodrah */*

    m.**at**(5) = "umeshwa"; 
    */* since there is no key with value 5 in the map , 
     it throws an exception  */* 
} 

emptysizemax_size

empty()如果映射为空,则返回布尔真,否则返回布尔假。size()返回映射中的条目数,一个条目由一个键和值组成。max_size()根据分配给映射的内存,返回映射可以包含的条目上限(最大可能条目数)。

insertinsert_or_assign

insert()用于在映射中插入条目。因为键在映射中是唯一的,所以它首先检查给定的键是否已经存在于映射中,如果存在,则不在映射中插入条目,并且返回现有键的迭代器,否则在映射中插入新的条目。

insert()有两种变体:

  • insert(pair<key_type value_type="">)</key_type> :在这个变体中,一对键和值被插入到映射中。插入的键对总是被插入到适当的位置,因为键是按排序顺序排列的。
  • insert(start_itr , end_itr):该变体在另一个映射的 start_itrend_itr 定义的范围内插入条目。

insert_or_assing()的工作方式与 insert()完全相同,只是如果给定的键已经存在于映射中,那么它的值会被修改。

#include <iostream>
#include <map>

using namespace std;

int main ()
{
    **map**<int,int> m{{1,2} , {2,3} , {3,4} };

    m.**insert**( pair<int,int> (4,5));
    */* inserts a new entry of key = 4 and value = 5 in map m */*

    */* make_pair() can also be used for creating a pair */*
    m.**insert**( make_pair(5, 6));
    */* inserts a new entry of key = 5 and value = 6 */*

    map<int>::iterator i , j;
    i = m.**find**(2);   * // points to entry having key =2*
    j = m.**find**(5);    *// points to entry having key =5*

    **map**<int,int> new_m;

    new_m.**insert**(i,j);
    * /* insert all the entries which are pointed 
     by iterator i to iterator j*/* 

    m.**insert**( make_pair(3,6));  
    * // do not insert the pair as map m already contain key = 3 */* 

    m.**insert_or_assign**( make_pair(3,6));  *// assign value = 6 to key =3  * 
}</int> 

eraseclear

erase()从迭代器指向的映射中移除条目(作为参数传递),但是如果我们想从映射中移除所有元素,我们可以使用clear(),它会清除映射并将其大小设置为 0。

擦除有两种变体:

  • erase(iterator_itr):这将从迭代器迭代器 _itr 指向的映射中移除条目,将映射的大小减少 1。
  • erase(start_iterator, end_iterator):删除开始迭代器结束迭代器指定范围内的元素。

beginendfind

begin、end 和 find 返回一个迭代器。begin()将迭代器返回到映射的起始条目,end()将迭代器返回到映射中最后一个条目旁边,find()将迭代器返回到具有等于给定键的键的条目(作为参数传递)。

begin, end and find function for maps



STL 中的栈容器

原文:https://www.studytonight.com/cpp/stl/stl-container-stack

栈容器用于在 c++ 中复制栈,插入和删除总是在栈的顶部执行。

要了解更多关于栈数据结构的信息,请访问:栈数据结构

以下是在 stl 中定义栈的语法:

**stack**<object_type> *stack_name*; 

上面的语句将创建一个名为对象类型的栈名。


栈容器的成员函数

以下是 STL 中栈容器最常用的一些函数:

push功能

push()用于将元素插入到栈中,元素被插入到栈的顶部。

Push method of Stacks

#include <iostream>      
#include <stack>

using namespace std;   

int main ()
{
    **stack**<int> s;   *// creates an empty stack of integer s* 

    s.**push**(2);   *// pushes 2 in the stack  , now top =2*
    s.**push**(3);   *// pushes 3 in the stack  , now top =3*

}

pop功能

此方法用于从栈中移除单个元素。它将栈的大小减少了 1。移除的元素始终是栈的最顶层元素(最近添加的元素)。pop()方法不返回任何东西。

Pop method of Stacks

top功能

此方法返回栈的最顶层元素。请注意,与 pop()不同,此方法返回元素,而不是移除它。

语法:top()

sizeempty功能

size()返回栈中存在的元质数量,而empty()检查栈是否为空。如果栈为空,则 empty 返回 true,否则返回 false。

swap功能

此方法交换两个栈的元素。

#include <iostream>      
#include <stack>

using namespace std;  

int main ()
{
    **stack**<int> s; 

    *// pushing elements into stack*
    s.**push**(2);   
    s.**push**(3);   
    s.**push**(4);   

    cout << s.**top**();   *// prints 4, as 4 is the topmost element* 

    cout << s.**size**();  *// prints 3, as there are 3 elements in* 
} 


STL 中的队列容器

原文:https://www.studytonight.com/cpp/stl/stl-container-queue

队列容器用于在 C++ 中复制队列,插入总是在队列的后面进行,删除总是在队列的前面进行。

以下是定义队列的语法:

**queue**< object_type >  *queue_name;*

上面的语句将创建一个名为 queue_name 的队列,类型为 object_type。


队列容器的成员函数

以下是 STL 中队列容器的一些常用函数:

push功能

push()用于将元素插入队列。元素被插入到队列的后面。

push method of queue

#include <iostream>      
#include <queue> 

using namespace std;   

int main ()
{
    queue <int> q;   *// creates an empty queue of integer q* 

    q.**push>**(2);   *// pushes 2 in the queue  , now front = back = 2*
    q.**push**(3);   *// pushes 3 in the queue  , now front = 2 , and back = 3*
}

pop功能

此方法从队列的前面移除单个元素,因此将其大小减少 1。移除的元素是首先输入的元素。pop()不返回任何内容。

pop method of queue

#include <iostream>      
#include <queue> 

using namespace std;   

int main ()
{
    queue <int> q;   *// creates an empty queue of integer q* 

    q.**push>**(2);   *// pushes 2 in the queue  , now front = back = 2*
    q.**push**(3);   *// pushes 3 in the queue  , now front = 2 , and back = 3*

    q.**pop**() ;  // removes 2 from the stack , front = 3
}

front and back功能

front()返回队列的前面元素,而back()返回队列的后面元素。请注意,两者都返回元素,而不是删除它,这与 pop() 不同。

sizeempty功能

size()返回队列中存在的元质数量,而empty()检查队列是否为空。如果队列为空,则 empty 返回 true,否则返回 false。

Swap功能

方法swap()交换两个队列的元素。



C++ STL 中的优先级队列容器

原文:https://www.studytonight.com/cpp/stl/stl-container-priority-queue

priority_queue就像一个正常的队列,只是从队列中移除的元素总是队列中所有元素中最大的,因此这个容器通常用于在 C++ 中复制 Max Heap 。元素可以任意顺序插入,并且插入的时间复杂度为O(log(n))

以下是创建优先级队列的语法:

**priority_queue**<int> *pq*; 

优先级队列的成员函数

下面是 STL 中优先级队列容器的一些常用函数:

push功能

这个方法在 priority_queue 中插入一个元素。元素的插入具有对数时间的时间复杂度。

#include <iostream>>     
#include <queue>

using namespace std;

int main ()
{
    **priority_queue**<int> pq1;

    pq1.**push**(30);  *// inserts 30 to pq1 , now top = 30*
    pq1.**push**(40);  *// inserts 40 to pq1 , now top = 40 ( maxinmum element)*
    pq1.**push**(90);  *// inserts 90 to pq1 , now top = 90* 
    pq1.**push**(60);	*// inserts 60 to pq1 , top still is 90*	

    return 0;
}

pop功能

此方法从 priority_queue(最大元素)中移除最顶端的元素,将优先级队列的大小减少 1。

#include <iostream>>     
#include <queue>

using namespace std;

int main ()
{
    **priority_queue**<int> pq1;

    pq1.**push**(30);  *// inserts 30 to pq1 , now top = 30*
    pq1.**push**(40);  *// inserts 40 to pq1 , now top = 40 ( maxinmum element)*
    pq1.**push**(90);  *// inserts 90 to pq1 , now top = 90* 
    pq1.**push**(60);	*// inserts 60 to pq1 , top still is 90*	

    pq1.**pop**();  *// removes 90 ( greatest element in the queue* 

    return 0;
}

top功能

此方法返回优先级队列顶部的元素,这是队列中最大的元素。

emptysize功能

size()返回 priority _queue 中存在的元质数量,而如果 priority_queue 为空,则empty()返回布尔值 true,否则返回布尔值 false。

swap功能

这个方法交换两个 priority_queue 的元素。



C++ STL 中的 DEQUE 容器

原文:https://www.studytonight.com/cpp/stl/stl-container-deque

Deque 是双端队列的简写。Deque 允许在队列的两端快速插入和删除。虽然我们也可以在向量容器的两端使用向量容器进行插入和删除,但是在数组的前面插入和删除比在后面更昂贵,在 deque 的情况下但是 deque 内部更复杂。

创建德格的语法是:

**deque**< object_type > *deque_name*;

德清的成员职能

下面是一些在 STL 中常用的 Deque 容器函数:

push_backpush_frontinsert功能

push_back(element e)在德格后面插入元素 epush_front(element e)在德格前面插入元素 e

insert()方法有三种变体:

  • insert(iterator i, element e):在德格中迭代器 i 指向的位置插入元素 e
  • insert(iterator i, int count, element e):插入元素 e从迭代器 i 指向的位置开始计算的次数。
  • insert(iterator i, iterator first, iterator last):将范围[第一个,最后一个]中的元素插入到迭代器 i 所指向的位置。
#include <iostream>
#include <deque>
#include <vector>

using namespace std;

int main ()
{

    int a[] = { 1,5,8,9,3 };
    **deque**<int> dq(a, a+5);
    */* creates s deque with elements 1,5,8,9,3  */*

    dq.**push_back**(10);
    */* now dq is : 1,5,8,9,3,10 */*

    dq.**push_front**(20);
    */* now dq is : 20,1,5,8,9,3,10  */*

    **deque**<int>::iterator i;

    i=dq.**begin**()+2;
    */* i points to 3rd element in dq */*

    dq.**insert**(i,15);
    */* now dq 20,1,15,5,8,9,3,10  */*

    int a[]={7,7,7,7};

    d1.**insert**(dq.**begin**() , a , a+4 );
    */* now dq is 7,7,7,7,20,1,15,5,8,9,3,10  */*
}

pop_backpop_front功能

pop_back()从德格的后面移除一个元素,而pop_front从德格的前面移除一个元素,两者都将德格的大小减少一。

#include <iostream>
#include <deque>
#include <vector>

using namespace std;

int main ()
{

    int a[] = { 1,5,8,9,3,5,6,4 };
    **deque**<int> dq(a,a+8);
    */* creates s deque with elements 1,5,8,9,3,5,6,4  */*

    dq.**pop_back**();
    */* removes an element from the back */*
    */* now the deque dq is : 1,5,8,9,3,5,6 */*

    dq.**pop_front**();
    */* now dq is : 1,5,8,9,3,5,6  */*
}

emptysizemax_size功能

empty()如果 deque 为空,则返回布尔值 true,否则返回布尔值 false。size()返回德格中存在的元质数量,max_size()返回给定德格可以容纳的元质数量。

swap功能

这个方法可以用来交换两个 deq 的元素。



迭代器

C++ STL 中迭代器概述

原文:https://www.studytonight.com/cpp/stl/stl-iterator-library

正如我们前面讨论的,迭代器用于指向 STL 中的容器,因为迭代器,算法可以操作不同类型的数据结构/容器。

STL 中的算法不在容器上工作,而是在迭代器上工作,它们操作迭代器指向的数据。因此,容器的类型并不重要,正因为如此,算法将适用于任何类型的元素,我们不必为不同类型的容器定义相同的算法。

Overview of Iterators in STL

上图显示了迭代器 ij ,指向一个向量的开始和结束。


在 STL 中定义迭代器

定义迭代器的语法是:

**container_type** <*parameter_list*>::**iterator** *iterator_name*;

让我们看一个更好地理解迭代器的例子:

 #include<iostream>
#include<vector>

using namespace std;

int main()
{
    vector<int>::iterator **i**;
    */* create an iterator named i to a vector of integers */*

    vector<string>::iterator **j**;
    */* create an iterator named j to a vector of strings */*

    list<int>::iterator **k**;
    */* create an iterator named k to a vector of integers */*

    map<int, int>::iterator **l**;
    */* create an iterator named l to a map  of integers */*
} 

迭代器可以用来遍历容器,我们可以去引用迭代器来获取它所指向的元素的值。这里有一个例子:

 #include<iostream>
#include<vector>
int main()
{
    vector<int> v(10);
    */* creates an vector v : 0,0,0,0,0,0,0,0,0,0  */*

    vector<int>::iterator i;

    for(i = v.begin(); i! = v.end(); i++)
    cout << *i <<"  ";
    */* in the above for loop iterator I iterates though the 
    vector v and *operator is used of printing the element 
    pointed by it.  */*

return 0;
} 


STL 中迭代器的运算

原文:https://www.studytonight.com/cpp/stl/stl-operations-on-iterators

下面是迭代器可以用来执行各种操作的操作。

  • 预先的
  • 距离
  • 然后
  • 上一个
  • 开始
  • 目标

advance()操作

它会将迭代器 i 增加距离值。如果距离值为负,则迭代器将递减。

语法:advance(iterator i ,int distance)

 #include<iostream>
#include<vector>

int main()
{
    vector<int>  v(10) ;    *// create a vector of 10 0's*
    vector<int>::iterator **i**;  *// defines an iterator i to the vector of integers*

    i = v.begin();
    */* i now points to the beginning of the vector v */*

    **advance**(i,5);
    */* i now points to the fifth element form the 
    beginning of the vector v */*

    **advance**(i,-1);
    */* i  now points to the fourth element from the 
    beginning of the vector */* 
} 

distance()操作

它将返回元素的数量,或者我们可以说第一个迭代器和最后一个迭代器之间的距离。

语法:distance(iterator first, iterator last)

 #include<iostream>
#include<vector>

int main()
{
    vector<int>  v(10) ;    *// create a vector of 10 0's*
    vector<int>::iterator **i**, **j**;  *// defines iterators i,j to the vector of integers*  

    **i** = v.begin();
    */* i now points to the beginning of the vector v */*

    **j** = v.end();
    */* j now points to the end() of the vector v */*

    cout << **distance**(i,j) << endl;
    */* prints 10 , */*

} 

next()操作

它会将第 n 个迭代器返回到 i ,即从 I 所指向的元素指向第 n 个元素的迭代器

语法:next(iterator i ,int n)


prev()操作

它会将第 n 个前置元素返回到 i ,即从 I 所指向的元素指向第 n 个前置元素的迭代器

**语法:prev(iterator i, int n)


begin()操作

这个方法返回一个迭代器到给定容器的开始。

语法:begin()


end()操作

这个方法返回一个迭代器到给定容器的末尾。

语法:end()



STL 中的算法

C++ STL 算法概述

原文:https://www.studytonight.com/cpp/stl/stl-overview-of-algorithms

STL 提供了不同类型的算法,可以在迭代器的帮助下在任何容器上实现。因此,现在我们不必定义复杂的算法,而是使用 STL 中算法库提供的内置函数。

如前所述,算法库提供的算法函数在迭代器上工作,而不是在容器上。因此,一个算法函数可以用于任何类型的容器。

使用 STL 的算法可以节省时间、精力和代码,并且非常可靠。

例如,为了在 C++ 中实现二分搜索,我们必须编写一个函数,例如:

bool **binary_search**( int l , int r , int key ,int a[])
{
    if(l > r)
        return -1;
    else
    {
        int mid=(l+r)/2;

        if(a[mid] == key) 
        {
            return true;
        }
        else if(a[mid] > key) 
        {
            return **binary_search**(l, mid-1, key, a);
        }
        else if(a[mid] < key) 
        {
            return **binary_search**(mid+1, r, key, a);
        }
    }
} 

请注意,只有当数组由整数和字符组成时,上述函数才有效。

但是在 STL 中我们可以只使用算法库提供的binary_search()来执行二分搜索。它已经在库中定义为:

return binary_search(a, a+a.size())

此外,上述功能适用于任何类型的容器。


算法库中的算法类型

  1. 排序算法
  2. 搜索算法
  3. 非修改算法
  4. 修改算法
  5. 数字算法
  6. 最小和最大操作。


STL 中的排序算法

原文:https://www.studytonight.com/cpp/stl/stl-sorting-algorithms

我们将在排序算法下研究三种方法,即:

  • 分类
  • 被排序
  • 部分排序

sort方法

这个函数对给定范围的内容进行排序。sort()有两个版本:

  1. sort(start_iterator, end_iterator ):对迭代器 start_iterator 和 end_iterator 定义的范围进行升序排序。
  2. sort(start_iterator, end_iterator, compare_function):这也会对给定的范围进行排序,但是您可以定义如何通过 compare_function 进行排序。
 #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

bool **compare_function**(int i, int j)
{
   return i > j;    // return 1 if i>j else 0
}
bool **compare_string**(string i, string j)
{ 
  return (i.size() < j.size()); 
}

int main()
{
    int arr[5] = {1,5,8,4,2};

    **sort**(arr , arr+5);    *// sorts arr[0] to arr[4] in ascending order*
    */* now the arr is 1,2,4,5,8  */*

    vector<int> **v1**;

    v1.push_back(8);
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(1);

    */* now the vector v1 is 8,4,5,1 */*
    vector<int>::iterator i, j;

    i = v1.begin();   *// i now points to beginning of the vector v1*
    j = v1.end();     *// j now points to end of the vector v1*

    **sort**(i,j);      *//sort(v1.begin() , v1.end() ) can also be used*
    */* now the vector v1 is 1,4,5,8 */*

    */* use of compare_function */*
    int a2[] = { 4,3,6,5,6,8,4,3,6 };

    **sort**(a2,a2+9,compare_function);  *// sorts a2 in descending order* 
    */* here we have used compare_function which uses operator(>), 
    that result into sorting in descending order */*

    */* compare_function is also used to sort non-numeric elements such as*/*

    string s[]={"a" , "abc", "ab" , "abcde"};

    **sort**(s,s+4,compare_string);
    */* now s is "a","ab","abc","abcde"  */*
} 

partial_sort方法

partial_sort()对给定范围内的前半部分元素进行排序,另一半元素保持最初的状态。partial_sort()也有两种变体:

  • partial_sort(start, middle, end ):从开始到结束对范围进行排序,中间之前的元素按升序排列,是范围内最小的元素。
  • partial_sort(start, middle, end, compare_function):从开始到结束对范围进行排序,排序方式是借助 compare_function 对中间之前的元素进行排序,并且是范围内最小的元素。
 #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main()
{
    int a[] = {9,8,7,6,5,4,3,2,1};

    **partial_sort**(a, a+4, a+9); 
    */* now a is 1,2,3,4,9,8,7,6,5  */* 

    int b[] = {1,5,6,2,4,8,9,3,7};

    */* sorts b such that first 4 elements are the greatest elements
    in the array and are in descending order */*
    **partial_sort**(b, b+4, b+9);  
    */* now b is  9,8,7,6,1,2,4,3,5 */*
} 

is_sorted方法

STL 的这个函数,如果给定的范围被排序,返回真。is_sorted()有两个版本:

  1. is_sorted(start_iterator, end_iterator):按升序检查迭代器 start_iterator 和 end_iterator 定义的范围。
  2. is_sorted(start_iterator, end_iterator, compare_function):它也检查给定的范围,但是你可以定义排序必须如何进行。
 #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main()
{
  int a[5] = {1,5,8,4,2}; 
  cout<<**is_sorted**(a, a+5);
  */* prints 0 , Boolean false  */*

  vector<int> **v1**;

  v1.push_back(8);
  v1.push_back(4);
  v1.push_back(5);
  v1.push_back(1);

  */* now the vector v1 is 8,4,5,1 */*
  cout<<is_sorted(v1.begin() , v1.end() );
  */* prints 0 */*
  **sort**(v1.begin() , v1.end() );
  */* sorts the vector v1 */*
  cout<<**is_sorted**(v1.begin() , v1.end());
  */*  prints 1 , as vector v1 is sorted */*    
} 


STL 中的二分搜索算法

原文:https://www.studytonight.com/cpp/stl/stl-searching

如果元素出现在给定的范围内,此函数返回布尔值 true,否则返回布尔值 false。binary_search()有两种变体:

  • binary_search(first, last, value):如果存在满足条件(!(一<值)& &!(值< a))在给定的范围内,即从第一个到最后一个,换句话说,运算符(
  • binary_search(first, last, value, compare_function):如果在给定的范围内存在一个元素,即从第一个到最后一个,这个版本返回 true。

注意,第一个和最后一个是迭代器,最后一个指向的元素被排除在搜索之外。

这里我们不需要首先对元素容器进行排序,binary_search()将为我们完成所有的工作,我们只需要给出一个要搜索的范围和值。

#include <iostream>    
#include <algorithm>
#include <vector>
using namespace std;

bool **compare_string_by_length** (string i,string j)
{
    return (i.size() == j.size());
}

int main () 
{
    int inputs[] = {7,8,4,1,6,5,9,4};
    vector<int> v(inputs, inputs+8);

    cout<<**binary_search**(**v**.begin() , **v**.end() , 7 );  *//prints 1 , Boolean true*

    cout<<**binary_search**(**v**.begin() , **v**.end() , 217); *//prints 0 , Boolean false*

    */* compare_function can be used to search 
    non numeric elements based on their properties */* 

    string s[] = { "test" , "abcdf" , "efghijkl" , "pop" };

    cout<<binary_search(s, s+4, "nickt" , **compare_string_by_length**);
    */* search for the string in s which have same length as of "nicky" */*

} 

STL 中的等距离算法equal_range

equal_range()返回一对迭代器,其中迭代器代表给定范围内等于给定值或满足 compare_function 的元素的子范围。给定的范围应该已经排序。相等范围有两种变化:

  • equal_range(first, last, value):返回一对迭代器,表示元素等于值的(第一个,最后一个)的子范围。
  • equal_range(first, last, value, compare_function):返回一对迭代器,表示(第一个,最后一个)的子范围,其中的元素满足 compare_function 的值。
#include <iostream>    
#include <algorithm>    
#include <vector>
using namespace std;

bool **compare_function** (int i,int j) 
{ 
    return (i <= j); 
}

int main () 
{
    int input[] = {1,1,1,2,2,2,3,3,6,7,7,7,7,7,8,9};
    vector <int>v(input, input+16);

    **pair**< vector<int>::iterator, vector<int>::iterator > sub_range;
    */* defining the pair of two iterators to an integer vector */*

    sub_range = **equal_range** (v.begin(), v.end(), 2);
    */* now sub_range.first points to 4th element in the vector v and 
     sub_range.second points to 7th element , 
     note that sub_range.secong points to the element 
     which is next to the element in the subrange  */* 

    sub_range = **equal_range** (v.begin(), v.end(), 20, compare_function);
    */* sub_range.first points to first element in the vector v , 
    as it satisfy the condition exerted by compare_function , <= , 
     sub_range.second points to 7th element in the vector . */*
}</int> 


STL 中的上界和下界搜索算法

原文:https://www.studytonight.com/cpp/stl/stl-searching-lower-upper-bound

upper_bound()返回给定范围内元素的迭代器,该迭代器的比较结果不大于给定值。给定的范围应该已经排序,以便 upper_bound()正常工作。换句话说,它返回给定排序范围内给定元素上限的迭代器。

#include <iostream>    
#include <algorithm> 
#include <vector>
using namespace std;

int main ()
{
    int input[] = {1,2,2,3,4,4,5,6,7,8,10,45};
    vector<int> v(input, input+12);

    vector<int>::iterator it1 , it2;

    it1 = **upper_bound**(v.begin(), v.end(), 6); 
    */* points to eight element in v */* 

    it2 = **upper_bound**(v.begin(), v.end(), 4);
    */* points to seventh element in v */*
} 

lower_bound方法

lower_bound()返回给定范围内元素的迭代器,该迭代器不小于给定值。给定的范围应该已经排序,以便 lower_bound()正常工作。换句话说,它返回给定排序范围内给定元素下限的迭代器。

#include <iostream>     
#include <algorithm>   
#include <vector>
using namespace std;

int main ()
{
    int input[] = {1,2,2,3,4,4,5,6,7,8,10,45};
    vector<int> **v**(input,input+12);

    vector<int>::iterator it1 , it2;

    it1 = **lower_bound**(**v**.begin(), **v**.end(), 4); 
    */* points to fifth element in v */* 

    it2 = **lower_bound** (**v**.begin(), **v**.end(), 10);
    */* points to second last element in v */*
} 


C++ STL 中的非修改算法

原文:https://www.studytonight.com/cpp/stl/stl-non-modifying-algorithms

以下是我们将介绍的标准模板库中的一些非修改算法:

  • 数数
  • 平等的
  • 错配
  • 搜索
  • 搜索

count方法

count()返回给定范围内等于给定值的元素个数。计数的语法是:

count(first ,last ,value) : This will return number of the element in range defined by iterators first and last ( excluded ) which are equal ( == ) the value .

#include <iostream>   
#include <algorithm>
#include <vector>
using namespace std;

int main ()
{
    int values[] = {5,1,6,9,10,1,12,5,5,5,1,8,9,7,46};

    int count_5 = **count**(values, values+15, 5);
    */* now count_5 is equal to 4 */*

    vector<int> v(values, values+15);

    int count_1 = **count**(v.begin(), v.end(), 1);
    */* now count_1 is equal to  */*

    return 0;
} 

equal方法

equal()比较两个范围内的元素,如果一个范围内的所有元素与另一个范围内对应的元素比较相等,则返回布尔值 true,否则返回布尔值 false。它有两种变体:

  • equal(first1, last1, first2):该函数比较 first1 和 last1(不包括)所指范围内的元素与起始位置 first2 的范围内的元素是否相等。如果所有元素都相等,则返回 true,否则返回 false。
  • equal(first1 ,last1 ,first2 ,cmp_function):这里 cmp_function 用来决定如何检查两个元素是否相等,对于字符串、对象等非数字元素很有用。
#include <iostream> 
#include <algorithm>
#include <vector>      
using namespace std;

bool **cmp_string**(string i, string j)
{
    return (i.size() == j.size());
}

int main()
{
    int inputs1[] = { 1,2,3,4,5,6,7,8};
    int inputs2[] = { -1,2,1,2,3,4,6,7,8,9};

    vector<int>  v1(inputs1 , inputs1+9 );
    vector<int>  v2(inputs2 , inputs2+10 );

    cout<<**equal**(v1.begin(), v1.end(), v2.begin()+2 ) ;  *// prints 0 , boolean false*

    */* use of compare function */*
    string s1[] = { "abc" , "def" , "temp" , "testing" };
    string s2[] = { "xyz" , "emp" , "resr" , "testing" };

    cout<<equal( s1 , s1+4 , s2 , cmp_string);   // prints 1 
    */* note that the stings in s1 and s2 are not actually 
    equal but still equal() returns 1 , beacause we are defining 
    equality of two string by their length in cmp_function */*
} 

mismatch方法

这个方法返回一对迭代器,其中第一个迭代器指向第一个容器中的元素,第二个迭代器指向第二个容器中出现不匹配的元素。mismatch()有两种变体。

  • mismatch(first1, last1, first2):这里第一个 1最后一个 1 是指定范围的第一个容器的迭代器第一个 2 是指定位置的第二个容器的迭代器,开始比较。默认情况下,检查元素是否相等 == ,返回迭代器对,给出发生不匹配的元素的位置。
  • mismatch(first1, last1, first2, compare_function):除了 compare_function 用于检查元素是否被认为相等之外,本版本的工作原理与上一版本相同。
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

bool **cmp_string**(string i , string j)
{
    return ( i.size() == j.size() );
}

int **main**()
{
    int inputs1[] = {1,2,3,4,5,6,7,8};
    int inputs1[] = {-1,2,1,2,3,4,6,7,8,9};

    vector<int> **v1**(inputs1 ,inputs1+9);
    vector<int> **v2**(inputs2 ,inputs2+9);

    pair<vector<int<::iterartor, vector<int>::iterator>  **position**;
    */* defining a pair of iterator to the vector of integer */*

    position = **mismatch**(**v1**.begin(), **v1**.end(), **v2**.begin()+2) ;

    */* now position.first is an iterator pointing 
    to the 5th element in the vector v1 and position.second 
    points to the 7th element in the vector v2 */*

    */* use of compare function */*
    string s1[] = {"abc", "def", "temp", "testing"};
    string s2[] = {"xyz", "emp", "res", "testing"};

    pair<string::iterator, string::iterator> position2;

    position2 = **mismatch**( s1, s1+4, s2, cmp_string);
    */* now position2.first is an iterator pointing
    to the 3rd element in s1 and position2.second points 
    to the 3rd element in the s2 */*
} 

search方法

该功能用于在给定的范围内搜索给定的序列search()有两种变体:

  • search(first1 ,last1 ,first2 ,last2):该功能在第一次 1最后 1 范围内搜索第一次 2最后 2 定义的顺序(其中不包括最后 1)。如果匹配,则返回序列中第一个元素的迭代器[first1,last1],否则返回 last1 的迭代器。
  • search(first1 ,last1 ,first2 ,last2 ,cmp_functions):这里 cmp_function 用来决定如何检查两个元素的相等性,对于字符串、对象等非数字元素很有用。
#include<iostream>
#include<algorithm>
#include<vector>   
using namespace std;

int main()
{
    int inputs1[] = { 1,2,3,4,5,6,7,8};
    int inputs2[] = { 2,3,4};

    vector<int> **v1**(inputs1, inputs1+9);
    vector<int> **v2**(inputs2, inputs2+3);

    vector<int>::iterator i ,j;

    i = **search**(v1.begin(), v1.end(), v2.begin(), v2.end()); 

    */* now i points to the second element in v1 */*

    j = **search**(v1.begin()+2, v1.end(), v2.begin(), v2.end());

    */* j now points to the end of v1 as no sequence is equal to 2,3,4 in 
    [v1.begin()+2 ,v1.end()] */*
} 

search_n方法

此方法在给定范围内搜索计数值序列。search()有两种变体:

  • search(first1, last1, count, value):该方法在迭代器 first1last1 定义的范围内搜索计数的序列(不包括 last1)。如果匹配,则返回序列中第一个元素的迭代器[first1,last1],否则返回 last1 的迭代器。
  • search(first1, last1, count, value, cmp_functions):这里 cmp_function 用来决定如何检查两个元素的相等性,对于字符串、对象等非数字元素很有用。
#include<iostream>
#include<algorithm>
#include<vector>      
using namespace std;

int main()
{
    int inputs1[] = {1,2,3,4,4,4,8,5,6,7,8};

    vector<int> **v1**(inputs1, inputs1+11);
    vector<int>::iterator I;

    **i** = **search_n**(v1.begin(), v1.end(), 3, 4); 

    */* now i points to the 4th  element in v1 */*

    **j** = **search**(v1.begin()+2, v1.end(), 2, 5);

    */* j now points to the end of v1 as no sequence is equal to 5,5 in 
    [v1.begin()+2 ,v1.end() ). */*
} 


C++ STL 中的修改算法

原文:https://www.studytonight.com/cpp/stl/stl-modifying-algorithms

以下是我们将介绍的标准模板库中的一些修改算法:

  • 复制和复制 _n
  • 填充和填充 _n
  • 移动
  • 改变
  • 产生
  • 交换
  • 交换范围
  • 反面的
  • 反向复制
  • 辐状的
  • 独一无二的
  • 唯一副本

copycopy_n

让我们从copy方法开始,逐一介绍每种方法:

copy方法

这个方法将元素从两个迭代器第一个最后一个定义的范围复制到迭代器第一个 2 开始的范围。

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    vector<int> v1,v2;

    v1.push(2);
    v1.push(4); 
    v1.push(6);
    v1.push(8);
    v1.push(10);

    **copy**(v1.begin(), v1.end(), v2.begin());

    */* v2 is now 2,4,6,8,10 */*
} 

copy_n方法

该函数将第一个 n 元素从迭代器首先定义的位置复制到迭代器第一个 2 开始的范围内。

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    int values[] = {1,2,3,4,5,6,7,8,9}; 
    vector<int> **v1**(values, values+9), **v2**;

    **copy_n**(v1.begin(), 5, v2.begin()); *// copies first 5 elements from v1 to v2.*
    /* v2 is now 1,2,3,4,5 */ 
} 

fillfill_n

让我们从fill方法开始,逐一介绍每种方法:

fill方法

这个方法在两个迭代器第一个最后一个定义的范围内给元素赋值。 fill() 的语法是,fill(iterator first, iterator last, int value)

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    vector<int> v1(10); *// v1 is now 0,0,0,0,0,0,0,0,0,0*

    **fill**(v.begin(), v.end(), 5);

    */* now v1 is 5,5,5,5,5,5,5,5,5,5 */*

    **fill**(v.begin(), v.end() - 5, 3);

    */* now v11 is 3,3,3,3,3,5,5,5,5,5 */*
} 

fill_n方法

这个方法从迭代器第一个定义的位置给第一个 n 个元素一个给定值。 fill_n 的语法为fill_n(iterator first, iterator last, int value)

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    int values[] = {1,2,3,4,5,6,7,8,9}; 
    vector<int> v1(values, values+9);

    **fill_n**(v1.begin(), 5 ,10);
    */* v1 is now 10,10,10,10,10,6,7,8,9 */* 
} 

move方法

该方法将元素从当前容器中移出,并返回其参考。移动的语法是move(element)。move()在 C++ 11 及更高版本中可用。

#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int main () 
{
    string a = "nicky";
    string b = "Vicky";

    vector<string> **name**;

    // inserts "nicky" in name , a is still = nicky
    name.push_back(a);        
    // inserts "Vicky" in name , b is now NULL
    name.push_back(**move**(b));  
} 

transform

transform 对给定的范围应用一元/二元运算,并将结果复制到从迭代器 res 开始的范围中。transform()有两种版本,它们因对元素执行的操作类型而异。

  • transform(iterator first1, iterator last1, iterator res, unaryoperation op):此方法对范围【first1,last1】内的元素执行一元运算 op ,并将结果存储在从 res 开始的范围内。
  • transform(iterator first1, iterator last1, iterator first2, iterator res, unaryoperation op):该方法对范围【first1,last1】内的元素执行二进制运算 op ,范围内的元素从迭代器 first2 开始,并将结果存储在范围 res 开始。
#include <iostream>     
#include <algorithm>
#include <vector>
using namespace std;

int **unaryoperation** (int a)
{
    return a*2;
}

int main()
{
    vector<int> v1;
    vector<int> v2;
    vector<int> res1;
    vector<int> res2;

    for(int i=0; i < 10; i++)
    {
        v2.push_back(i);
        v1.push_back(i*10); 
    }

    */*   v2 : 1,2,3,4,5,6,7,8,9  */* 
    */*   v1 : 10,20,30,40,50,60,70,80,90  */*

    res2.resize(10);

    transform(v2.begin(), v2.end(), res1.begin(), unaryoperation);
    */* now res1 is : 2,4,6,8,10,12,14,16,18 */*
} 

generategenerate_n

让我们从generate方法开始,逐一介绍每种方法:

generate方法

此方法将给定范围内的所有元素分配给对函数 generate_element 的连续调用所返回的值。生成的语法是generate(iterator first, iterator last, generator_function generate_element)

generate_n方法

该方法将给定范围内的第一个 n 元素赋给对函数 generate_element 的连续调用所返回的值。生成的语法为generate(iterator first, int n, generator_function generate_element)

#include <iostream>     
#include <algorithm>
#include <vector>
#include <time.h>
#include <cstdlib>

using namespace std;

int **generate_random**()
{
    return rand()%10;
}

int main()
{
    **srand**(time(NULL));

    vector<int> v1 , v2;
    v1.resize(10);
    v2.resize(10);

    **generate**(v1.begin(), v1.end(), generate_random) ;

    */* this assign each element a random value generated 
    by the generate_random() */*

    **generate_n**(v2.begin(), 5, generate_random);

    */* this assign first 5 elements a random value 
    and rest of the elements are un changed */* 
} 

swap方法

此方法交换两个相同类型容器的元素。

#include <iostream>     
#include <utility>
#include <vector>

using namespace std;

int main ()
{
    int a = 6;
    int b = 9;

    **swap**(a,b);
    */* a = 9 , b=6 */* 

    */* you can also swap an entire container with swap */*

    vector<int> **v**, **c**;
    for(int j=0; j < 10; j++)
    {
        v.push_back(j);
        c.push_back(j+1);
    }

    **swap**(v,c);

    for(vector>int>::iterator i = **v**.begin(); i! = **v**.end(); i++)
    cout<<*i<<" ";

    cout<<endl;

    for(vector<int>::iterator k = **c**.begin(); k! = **c**.end(); k++)
    cout<< *k <<" ";
} 

swap_ranges方法

swap_ranges(iterator first1, iterato last1, iterato first2):从第一个 2 开始,它将范围【第一个 1,最后一个 1】中的元素与范围中的元素交换。

#include <iostream>     
#include <utility>
#include <vector>

int main ()
{
    vector<int> v, c;
    for(int j=0; j < 10; j++)
    {
        v.push_back(j);
        c.push_back(j+1);
    }

    **swap_ranges**(v.begin(), v.begin()+5, c.begin());

    */* swaps the first five element of 
    vector v by the elements of vector c */*

    for(vector<int>::iterator i = v.begin(); i!= v.end(); i++)
    cout<< *i <" ";

    cout<<endl;

    for(vector<int>::iterator k = c.begin(); k!= c.end(); k++)
    cout<<*k<<" ";
} 

reverse方法

reverse(iterator first, iterator last)用于反转范围内元素的顺序[第一个,最后一个]。

#include <iostream>     
#include <algorithm>
#include <vector>

using namespace std;

int main () 
{
    int a[] = {1,5,4,9,8,6,1,3,5,4};

    **reverse**(a, a+10);

    */* reverse all the elements of the array a*/ 
    /* now a is : 4,5,3,1,6,8,9,4,5,1 */*

    **reverse**(a, a+5);

    */* reverse first 5 elements of the array a */
    /* now a is : 6,1,3,5,4,8,9,4 */* 

    vector<int> v(a, a+10);

    **reverse**(v.begin(), v.end());

    */* reverse the elements of the vector v */
    /* vector is now 4,9,8,4,5,3,1,6 */*
} 

reverse_copy方法

此方法以相反的顺序复制给定范围内的元素。它不会改变原始容器的顺序。 reverse_copy 的语法是reverse_copy(iterator first ,iterator last ,iterator res),通过迭代器 res 以相反的顺序将范围【第一个,最后一个】中的元素复制到范围中。

#include <iostream>     
#include <algorithm>
#include <vector>

using namespace std; 

int main()
{
    int values[] = {1,4,8,9,5,6,2,7,4,1};

    vector<int> v1(values, values+10);
    */* v1 is now 1,4,8,9,5,6,2,7,4,1  */*

    vector<int> v2;

    v2.resize(v1.size());   *// allocate size for v2*

    **reverse_copy**(v1.begin(), v1.end(), v2.begin());
    */* copies elements of v1 in reverse order in v2 */* 

    */* now v2 is : 1,4,7,2,6,5,9,8,4,1  */*
} 

rotate方法

该方法用于rotate(iterator first, iterator middle, iterator last)给定范围【第一个,最后一个】内的元素,使得中间迭代器指向的元素成为第一个元素。

#include <iostream>     
#include <algorithm>
#include <vector> 

using namespace std;

int main () 
{
    int a[] = {1,5,9,8,4,6,9,2};
    vector<int> v(a,a+8);

    **rotate**(a,a+4,a+8);
    */* rotate a such that a[4] is now the first element of array a */
    /* now a is : 4,6,9,2,1,5,9,8 */*

    **rotate**(v.begin(), v.begin()+5, v.end());
    */* now vector v is :6,9,2,1,5,9,8,4  */*
} 

unique方法

此方法从给定范围中移除连续的重复元素。它有两种变体。它将迭代器返回到新范围最后一个元素的旁边。resize()可用于调整容器尺寸后的唯一()。

  • unique(iterator first, iterator last):除了[第一个,最后一个]范围内的第一个元素外,删除所有连续的重复元素。运算符==,用于检查金属线是否重复。
  • unique(iterator first, iterator last, bool compare_function):在这个版本中,我们使用 compare_function 来检查元素是否重复。
#include <iostream>     
#include <algorithm>
#include <vector>
#include <utility>

using namespace std;

bool **cmp_function**(int a , int b )
{
    return a+b;
}

int main ()
{
    int values[] = {10,5,5,5,9,6,6,4,4};
    vector<int> v (values,values+9) , v4;

    vector<int>::iterator it;

    it = **unique**(v.begin(), v.end());
    */* vector v is now : 10,5,9,6,4,-,-,-,-  */*

    */* - indicates that the elements are removed from the vector 
    and next elements are shifted to their position */

    /* now it is pointing to the first occurrence of the “-“ in 
    the vector , i.e the position next to the last element (4) */

    /* adjusting the size of vector v */*

    v.resize(distance(v.begin(),it));
    */* resize the vector by the size returned by distance function, 
    which returns the distance between the two iterators  */

    /* vector v is now 10,5,9,6,4  */

    /* using compare_function */*

    vector<int> v3(values, values+9);

    it = **unique**(v3.begin(), v3.end(), cmp_function);
    v3.resize(distance(v3.begin(), it));

    */* removes copies the duplicate  elements from v3*/*

    return 0;
} 

unique_copy方法

此方法从范围[第一个,最后一个]复制唯一元素,并将迭代器返回到新范围中最后一个元素旁边的位置。它有两种变体。它将迭代器返回到新范围最后一个元素的旁边。resize()可用于调整容器尺寸后的唯一()。

  • unique_copy(iterator first, iterator last):除了[第一个,最后一个]范围内的第一个元素外,删除所有连续的重复元素。运算符==,用于检查金属线是否重复。
  • unique_copy(iterator first, iterator last, bool compare_function):在这个版本中,我们使用 compare_function 检查元素是否重复。
#include <iostream>     
#include <algorithm>
#include <vector>

using namespace std;

bool **cmp_fuction**(int a , int b )
{
    return a+b;
}

int main ()
{
    int values[] = {10,5,5,5,9,6,6,4,4};
    vector<int> v (values,values+9);
    vector<int> v2;
    v2.resize(v.size());

    vector<int>::iterator it;

    it = **unique**(v.begin(), v.end());
    */* vector v2 is now : 10,5,9,6,4,-,-,-,-  */

    /* - indicates that the elements are removed from the vector 
    and next elements are shifted to their position */

    /* now it is pointing to the first occurrence of the “-“ 
    in the vector, i.e the position next to the last element (4) */

    /* adjusting the size of vector v */*

    v.**resize**(distance(v.begin(), it));
    */* resize the vector by the size returned by distance function, 
    which returns the distance between the two iterators  */

    /* vector v is now 10,5,9,6,4  */

    /* using compare_function */*

    vector<int> v3(values,values+9),v4;
    v4.resize(v3.size());

    it = **unique_copy**(v3.begin(), v3.end(), v4.begin(), cmp_fuction);
    v4.resize(distance(v4.begin(), it));

    */* copies the unique elements from v3 to v4 */*

    return 0;
} 


C++ STL 中的数值算法

原文:https://www.studytonight.com/cpp/stl/stl-numeric-algorithms

以下是我们将介绍的标准模板库中的一些数值算法:

  • 方法
  • 方法累加
  • 部分求和法

iota方法

此方法将范围[第一个,最后一个]中的所有连续元素指定为元素本身的递增值。它有 c++ 11 和更高版本。它的语法是iota(iterator first, iterator last, int value )

#include<iostream>
#include<numeric>
#include<vector>

using namespace std;

int main()
{
    vector<int> v(10);
    */* now vector v is : 0,0,0,0,0,0,0,0,0,0  */*

    **iota**(v.begin(), v.end(), 10 );

    */* now the vector v is 10,11,12,13,14,15,16,17,18,19  */*
} 

accumulate方法

此方法对范围[第一个,最后一个]中的所有元素执行操作 op ,并将结果存储到容器结果中。累加有两种变化,第一种是函数调用中没有定义二进制运算符,所以默认情况下执行加法,否则执行二进制运算符运算

以下是带有二进制运算符 op 的累加方法的语法:

accumulate(iterator first, iterator last, object_type result, binaryoperator op)

下面是一个演示累加用法的示例:

#include<iostream>
#include<numeric>
#include<vector>

using namespace std;

int **myoperator**(int a, int b )
{
    return a*b;
}

int main()
{
    vector<int> v;

    for(int i = 0 ; i < 10; i++) {
    v.push_back(i);
    }

    */* now vector v is : 0,1,2,3,4,5,6,7,8,9  */*

    int result;

    **accumulate**(v.begin(), v.end(), result) ;

    */* as no operator is specified, accumulate add all the elements 
    between v.begin() and v.end() and store the sum in result */ 

    /* now result = 45 */*

    **accumulate**(v.begin(), v.end(), result, myoperator) ;

    */* applies myoperator on all the elements in the range v.begin() and v.end() and store them in result */ 

    /* now result = 9!  */*
} 

partial_sum方法

该方法从迭代器开始对范围内的每一个元素赋值,迭代器的结果是对[第一个,最后一个]中的连续范围执行运算的结果。这里可以省略 binary_operation,如果没有指定二进制运算符,加法默认完成。

partial_sum 的语法是:

partial_sum(iterator first, iterator last, iterator result, binary_operation op)

下面是一个演示 partial_sum 用法的示例:

#include<iostream>
#include<numeric>
#include<vector>

using namespace std;

int **myoperator**(int a, int b)
{
    return a*b;
}

int main()
{
    int a[] = {1,2,3,4,5};
    vector<int> v (a,a+5);
    vector<int> v2;
    */* vector v is 1,2,3,4,5 */*
    v2.resize(v.size());

    **partial_sum**(v.begin(), v.end(), v2.begin());

    */* now v2 is : 1,3,6,10,15 */
    /* sum of the successive range in v.begin() and v.end() */*

    **partial_sum**(v.begin(), v.end(), v2.begin(), myoperator);

    */* now v2 is : 1,2,6,24,120 */*
}