C++ winhttp 实现文件下载器

article/2025/10/29 12:28:22

本篇内容讲述 C++ winHttp 实现下载器的简单 demo,使用了 WinHttpOpen、WinHttpConnect、WinHttpOpenRequest、WinHttpSendRequest、WinHttpReceiveResponse、WinHttpQueryDataAvailable、WinHttpReadData、WinHttpCloseHandle 等函数。

版权声明:本文为CSDN博主「1_bit」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/A757291228/article/details/129974019

文章参考 Microsoft doc WinHttp:https://learn.microsoft.com/zh-cn/windows/win32/WinHttp/winhttp-start-page
本机环境:VisualStudio 2022 、 Windows10
想要完整代码请到文章末尾

一、WinHttp

WinHttp 是 Windows 提供的可创建网络请求的一组 API,包括 http、https、代理等;WinHttp 的 Microsoft doc 链接为 https://learn.microsoft.com/zh-cn/windows/win32/WinHttp/winhttp-start-page,若需要查看详细的文档说明,可进入 Microsoft doc 进行查看。

二、WinHttp 的使用

本篇文章只简单的介绍如何使用 WinHttp,并不涉及其原理,包括 http、https 协议不再讲解。关于不讲解的原因为思考后,发现即使不会协议,也能很好的使用 WinHttp,当然可能对于某些“复杂”的业务逻辑或特殊需求并不好处理,可能也会对于某些错误信息无法判断,若出现这种情况,建议读者再去了解 http、https 等协议,当然本人之后也会出相关的协议讲解的文章,但在本篇,我们只讨论如何使用 C++ WinHttp 进行网络请求。

在 Microsoft doc 中,有介绍 C++ WinHttp 的使用流程,可以根据这个 流程图 学习接下来的知识点:

在这里插入图片描述

2.1 WinHttp 的 http 一般使用流程

使用 C++ WinHttp 发送一个 Http 请求,需要经过以下流程 :WinHttpOpen->WinHttpConnect->WinHttpOpenRequest->WinHttpSendRequest->WinHttpReceiveResponse->WinHttpQueryDataAvailable->WinHttpReadData->WinHttpCloseHandle

以上所述内容只需要先有一个印象,接下来会对其进行详细说明。

对于以上流程用中文的进行解释为:WinHttpOpen (初始化 WinHttp )->WinHttpConnect (指定 Http 请求的初始目标服务器 )->WinHttpOpenRequest (创建 HTTP 请求句柄)->WinHttpSendRequest (指定请求发送到 Http 服务器) ->WinHttpReceiveResponse (等待 WinHttpSendRequest 发起的 HTTP 请求的响应) ->WinHttpQueryDataAvailable (读取数据大小) ->WinHttpReadData**(读取数据)** ->WinHttpCloseHandle (关闭连接)

2.2 VisualStduio 环境准备

本机环境使用的 VS 版本为2022,打开后点击创建项目:

在这里插入图片描述
选择控制台程序:

在这里插入图片描述
接下来编写完项目名称点击下一步即可:
在这里插入图片描述
接下来在 右侧解决方案资源管理器 下的 SourceFiles 中找到 main.cpp 进行代码编写即可:

在这里插入图片描述

2.3 WinHttpOpen 初始化 WinHttp

在了解了 WinHttp 的一般步骤后,首先开始读 WinHttp 的初始化操作。一个 WinHttp 的函数圆形如下:

WINHTTPAPI HINTERNET WinHttpOpen([in, optional] LPCWSTR pszAgentW,[in]           DWORD   dwAccessType,[in]           LPCWSTR pszProxyW,[in]           LPCWSTR pszProxyBypassW,[in]           DWORD   dwFlags
);

WinHttpOpen 接收 5 个参数,分别是 pszAgentWdwAccessTypepszProxyWpszProxyBypassWdwFlags,其中:

  • pszAgentW:表示代理名称 agent name
  • dwAccessType:表示如何http(假定)如何进行请求 可选
  • pszProxyW:表示若使用代理则在此处填写对应的代理服务器和端口号 可选
  • pszProxyBypassW:表示绕过的代理服务器主机名
  • dwFlags:表示使用某些特定的组合选项

在以上的解释中,对于网络知识薄弱的同学可能会感到一头雾水,在此使用一个示例进行说明:

hSession = WinHttpOpen(
L"My User Agent Name",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);

以上是一个 WinHttpOpen 的代码示例,其中参数:

  • pszAgentW 设置为了 "My User Agent Name",这就是我们的代理名称为 "My User Agent Name",或者你想用其他名称也行。
  • dwAccessType 设置为了 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 表示使用默认代理设置,也就是说当前本机的默认网络代理设置是什么就是什么,或者说咱们没有什么特殊的代理需求时,设置为 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 即可。
  • pszProxyW 设置为了 WINHTTP_NO_PROXY_NAME 表示当前的请求不使用代理。毕竟在上一个设置时咱们设置了使用默认代理,那么理应设置成不适用代理(当然,你可能当前本机是有代理,默认了,那么也是走那个默认的代理去请求的)。
  • pszProxyBypassW 设置为了 WINHTTP_NO_PROXY_BYPASS 则表示不绕过任何的主机,则使用当前的默认代理进行访问。
  • dwFlags 设置为 0 表示打开会话时不使用特定的选项,该怎样就怎样。

以上设置中 dwAccessType 还可以设置成 WINHTTP_ACCESS_TYPE_NO_PROXYWINHTTP_ACCESS_TYPE_NAMED_PROXY,其中:

  • WINHTTP_ACCESS_TYPE_NO_PROXY 表示直接链接到目标服务器不使用代理
  • WINHTTP_ACCESS_TYPE_NAMED_PROXY 表示使用目标代理

接下来在 VS 2022 中添加 WinHttp 头文件对其引入:

#include <Winhttp.h>

并且需要添加对应的编译指示器,指定库文件链接:

#pragma comment(lib, "winhttp.lib")

为了方便接下来的操作,咱们顺势将其他头文件引入:

#include <Windows.h>
#include <iostream>

接着创建一个 HINTERNET 句柄对象用于接收 WinHttp 初始化后的句柄:

HINTERNET hSession = NULL;

此时还可以在之后进行判断,是否初始化成功:

if (!hSession) {std::cerr << "WinHttp 打开错误 \n";return 1;
}

接着就可以复制以上示例代码到 main.cpp 文件中了,此时的 main.cpp 文件代码如下:

#include "pch.h"
#include <Windows.h>
#include <iostream>
#include <Winhttp.h>
#pragma comment(lib, "winhttp.lib")using namespace winrt;
using namespace Windows::Foundation;int main()
{HINTERNET hSession = NULL;hSession = WinHttpOpen(L"My User Agent",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);if (!hSession) {std::cerr << "WinHttp 打开错误 \n";return 1;}
}

2.3 WinHttpConnect 指定 Http 请求的初始目标服务器

完成了 WinHttp 初始化后,使用 WinHttpConnect 指定 Http 的目标服务器,WinHttpConnect 函数原型如下:

WINHTTPAPI HINTERNET WinHttpConnect([in] HINTERNET     hSession,[in] LPCWSTR       pswzServerName,[in] INTERNET_PORT nServerPort,[in] DWORD         dwReserved
);

WinHttpConnect 接收 4 个参数:

  • hSession:为 WinHttp 初始化后的句柄
  • pswzServerName:为目标服务器名,域名或IP
  • nServerPort: 为指定的端口,如果是 HTTP 就是80,若是 HTTPS 就是 443
  • dwReserved:保留参数,设置为 0 即可,不用管,文档也是这样写的

以上参数中 nServerPort 可以设置为:

  • INTERNET_DEFAULT_HTTP_PORT:使用 HTTP 服务器的默认端口 (端口 80)
  • INTERNET_DEFAULT_HTTPS_PORT:使用 HTTPS 服务器的默认端口 (端口 443) 。

此时该函数可编写为:

HINTERNET hConnect = NULL;
hConnect = WinHttpConnect(hSession,L"demo.com",//此处填写你要进行 http 请求的 hostname 或 ip80,0
);

2.4 WinHttpOpenRequest 创建 HTTP 请求句柄

WinHttpOpenRequest 创建 HTTP 请求句柄,函数原型如下:

WINHTTPAPI HINTERNET WinHttpOpenRequest([in] HINTERNET hConnect,[in] LPCWSTR   pwszVerb,[in] LPCWSTR   pwszObjectName,[in] LPCWSTR   pwszVersion,[in] LPCWSTR   pwszReferrer,[in] LPCWSTR   *ppwszAcceptTypes,[in] DWORD     dwFlags
);
  • hConnectWinHttpConnect 返回的 HINTERNET 句柄。
  • pwszVerb 请求类型参数,例如 GET,需要大写
  • pwszObjectName url 请求参数
  • pwszVersion 指定 HTTP 版本,默认为 NULL,使用 HTTP/1.1
  • pwszReferrer 表示请求的来源地址,如果没有其他页面跳转到目标请求,那么设置为 NULL,也可以使用 WINHTTP_NO_REFERER 代替
  • ppwszAcceptTypes 表示 HTTP 请求可接受的 MIME 类型,例如 “application/json”“text/html”,设置为 WINHTTP_DEFAULT_ACCEPT_TYPES 表示使用 WinHTTP 默认的 MIME 类型设置
  • dwFlags 若不需要设置任何特殊标志和选项那么设置为 0 即可

dwFlags 参数还可以设置为 WINHTTP_FLAG_SECUREWINHTTP_FLAG_ESCAPE_PERCENTWINHTTP_FLAG_NULL_CODEPAGEWINHTTP_FLAG_BYPASS_PROXY_CACHE

  • WINHTTP_FLAG_SECURE 表示使用 HTTPS 链接,默认情况下 winHttp 使用 HTTP
  • WINHTTP_FLAG_ESCAPE_PERCENT 表示在请求之前对 URL 中的 % 进行转义
  • WINHTTP_FLAG_NULL_CODEPAGE 表示无需为响应的 Unicode 字符串指定代码页
  • WINHTTP_FLAG_BYPASS_PROXY_CACHE 表示绕过服务器缓存直接请求服务器内容

那么以上函数可写成:

HINTERNET hRequest = NULL;
hRequest = WinHttpOpenRequest(hConnect, L"GET",L"disk.exe",NULL,WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,0);
if (!hRequest) {std::cerr << "WinHttpOpenRequest 错误 \n";WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;
}

2.5 WinHttpSendRequest 指定请求发送到 Http 服务器

函数原型如下:

WINHTTPAPI BOOL WinHttpSendRequest([in]           HINTERNET hRequest,[in, optional] LPCWSTR   lpszHeaders,[in]           DWORD     dwHeadersLength,[in, optional] LPVOID    lpOptional,[in]           DWORD     dwOptionalLength,[in]           DWORD     dwTotalLength,[in]           DWORD_PTR dwContext
);

参数说明:

  • hRequestRequest WinHTTP 请求句柄
  • pwszHeaders:如果没有要添加的标头,则为 NULL 或者为 WINHTTP_NO_ADDITIONAL_HEADERS
  • dwHeadersLengthpwszHeaders 参数以字节为单位的长度,若 pwszHeadersNULL,则此参数为 0
  • lpOptional:要发送到服务器的数据,如果没有要发送的数据,则为 NULLWINHTTP_NO_REQUEST_DATA
  • dwOptionalLengthlpOptional 以字节为单位的长度,lpOptionalNULL,则此参数为 0
  • dwTotalLength:请求的总长度,没有标头也没有数据,则为 0
  • dwContext:用于指定调用方自定义的上下文值,在请求完成后可以通过回调函数获取该值,不需要设置回调则为 0

此时代码可以编写为如下:

bResults = WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS, 0,WINHTTP_NO_REQUEST_DATA, 0,0, 0);
if (!bResults) {std::cerr << "WinHttpSendRequest 错误 \n";WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;
}

2.6 WinHttpReceiveResponse 等待 WinHttpSendRequest 发起的 HTTP 请求的响应

函数原型如下:

WINHTTPAPI BOOL WinHttpReceiveResponse([in] HINTERNET hRequest,[in] LPVOID    lpReserved
);
  • hRequest :已通过 WinHttpSendRequest 函数发送请求并返回的 WinHTTP 请求句柄。
    等待 WinHttpSendRequest 完成此句柄,然后再调用 WinHttpReceiveResponse
  • lpReserved:保留参数设置为 NULL

此时代码如下:

bResults = WinHttpReceiveResponse(hRequest, NULL);
if (!bResults) {std::cerr << "WinHttpReceiveResponse 错误 \n";WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;
}

2.7 WinHttpQueryDataAvailable 读取数据大小

接下来使用 WinHttpQueryDataAvailable 读取数据大小,方便接下来读取数据到某一个 buf 之中。

WinHttpQueryDataAvailable 函数原型如下:

WINHTTPAPI BOOL WinHttpQueryDataAvailable([in]  HINTERNET hRequest,[out] LPDWORD   lpdwNumberOfBytesAvailable
);

hRequestWinHttpSendRequestWinHTTP 句柄
lpdwNumberOfBytesAvailable:尚未读取的响应数据的大小

此时代码如下:

DWORD dwSize = 0;
LPSTR pszOutBuffer = NULL;
dwSize = 0;
WinHttpQueryDataAvailable(hRequest, &dwSize);
pszOutBuffer = new char[dwSize + 1];
ZeroMemory(pszOutBuffer, dwSize + 1);//清空 pszOutBuffer 

2.8 WinHttpReadData 读取数据

WinHttpReadData 函数将会读取还没有读取的数据,函数原型如下:

WINHTTPAPI BOOL WinHttpReadData([in]  HINTERNET hRequest,[out] LPVOID    lpBuffer,[in]  DWORD     dwNumberOfBytesToRead,[out] LPDWORD   lpdwNumberOfBytesRead
);
  • hRequestWinHttpSendRequestWinHTTP 句柄
  • lpBufferbuf 指针 存储读取数据
  • dwNumberOfBytesToRead:读取数据的字节数大小
  • lpdwNumberOfBytesRead:此时实际读取数据的字节数

由于此时 WinHttpReadData 返回的是 BOOL,那么直接 while 进行读取即可,当然,也可以 lpdwNumberOfBytesRead 为 0 时 break

while (WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) {if (dwDownloaded == 0)break;
}

此时读取的是 exe 二进制流数据,咱们可以直接 cout 输出,代码如下:

std::cout << pszOutBuffer;
delete[] pszOutBuffer;
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);

结果如下:

在这里插入图片描述

下载器输出完整代码

该部分完整代码如下:

#include "pch.h"
#include <Windows.h>
#include <iostream>
#include <Winhttp.h>
#pragma comment(lib, "winhttp.lib")using namespace winrt;
using namespace Windows::Foundation;int main()
{HINTERNET hSession = NULL;HINTERNET hConnect = NULL;HINTERNET hRequest = NULL;DWORD dwSize = 0;LPSTR pszOutBuffer = NULL;DWORD dwDownloaded = 0;bool bResults = false;hSession = WinHttpOpen(L"My User Agent",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);if (!hSession) {std::cerr << "WinHttp 打开错误 \n";return 1;}hConnect = WinHttpConnect(hSession,L"hostname or ip",80,0);if (!hConnect) {std::cerr << "WinHttpConnect 错误 \n";WinHttpCloseHandle(hSession);return 1;}hRequest = WinHttpOpenRequest(hConnect, L"GET",L"disk.exe",NULL,WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,0);if (!hRequest) {std::cerr << "WinHttpOpenRequest 错误 \n";WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;}bResults = WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS, 0,WINHTTP_NO_REQUEST_DATA, 0,0, 0);if (!bResults) {std::cerr << "WinHttpSendRequest 错误 \n";WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;}bResults = WinHttpReceiveResponse(hRequest, NULL);if (!bResults) {std::cerr << "WinHttpReceiveResponse 错误 \n";WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;}dwSize = 0;WinHttpQueryDataAvailable(hRequest, &dwSize);pszOutBuffer = new char[dwSize + 1];ZeroMemory(pszOutBuffer, dwSize + 1);while (WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) {if (dwDownloaded == 0)break;}std::cout << pszOutBuffer;delete[] pszOutBuffer;WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);}

三、代码更改成下载程序并保存

想要更改以上示例下载文件保存到磁盘步骤简单,首先引入 fstream 头文件:

#include <fstream>

接在在下图所示处开始添加代码:

在这里插入图片描述
此时添加的代码如下:

std::ofstream outfile("C:\\demo.exe", std::ios::binary);

此时表示输出内容到 C:\\demo.exe 下保存,当然 demo.exe 是你的文件名。

接着创建一个 BYTE 对象为缓冲区:

BYTE buffer[1024];

修改原有的 while 循环读取如下:

while (WinHttpReadData(hRequest, buffer, sizeof(buffer), &dwDownloaded)) {outfile.write(reinterpret_cast<const char*>(buffer), dwDownloaded);if (dwDownloaded == 0)break;
}
outfile.close();

此时读取到的缓冲区变成了 buffer,并且在读取后,在 使用 outfile.write 写入数据(不会的可以查一下文档,这个很简单)。

最后关闭 文件操作 即可。

运行程序完毕后,已下载内容到磁盘中:

在这里插入图片描述

下载器完整代码

此时修改过的完整下载器代码如下:

#include "pch.h"
#include <Windows.h>
#include <iostream>
#include <Winhttp.h>
#include <fstream>
#pragma comment(lib, "winhttp.lib")using namespace winrt;
using namespace Windows::Foundation;int main()
{HINTERNET hSession = NULL;HINTERNET hConnect = NULL;HINTERNET hRequest = NULL;DWORD dwSize = 0;LPSTR pszOutBuffer = NULL;DWORD dwDownloaded = 0;bool bResults = false;hSession = WinHttpOpen(L"My User Agent",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);if (!hSession) {std::cerr << "WinHttp 打开错误 \n";return 1;}hConnect = WinHttpConnect(hSession,L"hostname",80,0);if (!hConnect) {std::cerr << "WinHttpConnect 错误 \n";WinHttpCloseHandle(hSession);return 1;}hRequest = WinHttpOpenRequest(hConnect, L"GET",L"disk.exe",NULL,WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,0);if (!hRequest) {std::cerr << "WinHttpOpenRequest 错误 \n";WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;}bResults = WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS, 0,WINHTTP_NO_REQUEST_DATA, 0,0, 0);if (!bResults) {std::cerr << "WinHttpSendRequest 错误 \n";WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;}bResults = WinHttpReceiveResponse(hRequest, NULL);if (!bResults) {std::cerr << "WinHttpReceiveResponse 错误 \n";WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);return 1;}//dwSize = 0;//WinHttpQueryDataAvailable(hRequest, &dwSize);//pszOutBuffer = new char[dwSize + 1];//ZeroMemory(pszOutBuffer, dwSize + 1);std::ofstream outfile("C:\\demo.exe", std::ios::binary);BYTE buffer[1024];while (WinHttpReadData(hRequest, buffer, sizeof(buffer), &dwDownloaded)) {outfile.write(reinterpret_cast<const char*>(buffer), dwDownloaded);if (dwDownloaded == 0)break;}outfile.close();/*while (WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) {if (dwDownloaded == 0)break;}*///std::cout << pszOutBuffer;//delete[] pszOutBuffer;WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);}

http://chatgpt.dhexx.cn/article/Gb2Yy9yZ.shtml

相关文章

WinHTTP教程

最近有些忙&#xff0c;也没更新BLOG&#xff0c;这几天在捣鼓一个小玩意要用到WinHTTP API&#xff0c;发现资料很少&#xff0c;而且大都是些MFC封装的例子&#xff0c;看得我是一个头几个大。就把自己关于WinHTTP的学习总结了一下&#xff0c;仅供参考&#xff0c;各人理解可…

WinHttp c++ 介绍及应用

一、HTTP协议介绍 http协议的底层协议是TCP协议。TCP协议是基于数据流的传输方式。其又叫做“超文本传输协议”&#xff0c;为什么呢&#xff0c;因为它是将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器&#xff0c;通过因特网传送万维网文档的数据传送协议。 1…

WinHTTP

记录WinHTTP学习过程 一、什么是WinHTTP&#xff1f; WinHTTP的全称是Microsoft Windows HTTP Services&#xff0c; 它提供给开发者一个HTTP客户端应用程序接口(API)&#xff0c;通过这种API借助HTTP协议给其他的HTTP服务器发送请求。 二、WinHTTP访问流程 如上图&#xff0c;…

Java递归算法计算5的阶乘

递归 package com.etime.test019; //计算5的阶乘&#xff1b; public class Test15 {public static void main(String[] args) {//调用test1方法&#xff0c;且只调用一次int i test1(5);System.out.println(i);}//定义一个int类型返回值的静态方法public static int test1(i…

Java算法递归与递推

Java算法----递归与递推 递推实现递推思想递归实现递归思想递归实现递推思想递推实现递归思想四种方法的特点思维拓展 问题&#xff1a;给你一个整数n&#xff0c;如果n是奇数&#xff0c;就进行运算nn*31&#xff0c;如果n是偶数&#xff0c;就进行运算nn/2&#xff0c;直到n等…

Java开发 | 数据结构和算法之——递归算法

著名的Pascal之父——Nicklaus Wirth(沃斯)让他获得图灵奖的一句话就是他提出的著名公式:“程序=数据结构+算法”,这个公式对计算机科学的影响类似于爱因斯坦的质能方程在物理界的影响。 因此可以看出来数据结构和算法在我们开发程序中有多么的重要了,下面我们来简单认识…

java中递归算法的理解

Coding多了&#xff0c;递归算法是非常常见的&#xff0c;最近我一直在做树形结构的封装&#xff0c;所以更加的离不开递归算法。所以今天就简单说一下这个递归算法&#xff0c;用java实现一个非常经典的递归实例。 递归算法&#xff0c;其实说白了&#xff0c;就是程序的自身调…

【递归】java递归算法及替代方法

文章目录 菜单树递归&#xff08;树根往子节点递归&#xff09;需求&#xff1a; 取所有level小于2的节点 ( 返回结果为普通list格式) 为list格式的数据设置children&#xff08;非递归&#xff09;需求&#xff1a; 数据库查出来的原始list 如果有children就设置 使用循环代替…

Java递归

1.递归的概念&#xff1a; 一个方法在执行过程中调用自身, 就称为 "递归". 示例&#xff1a; //递归求n的阶乘 public static void main(String[] args) {int n 5;int ret factor(n);System.out.println("ret " ret); }public static int factor(int…

java递归算法(一)——详解以及几个经典示例

什么是递归 递归就是一个程序或函数在其中定义或说明有之间或者间接调用自身的一种方法&#xff0c;它通常把一个大型复杂的问题层层转化为一个原问题相似的规模较小的问题来求解&#xff0c;递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算&#xff0c;大…

Java 递归算法

一、概述&#xff1a; Java递归&#xff1a;简单说就是函数自身直接或间接调用函数的本身。 二、应用场景&#xff1a; 若&#xff1a;一个功能在被重复使用&#xff0c;并每次使用时&#xff0c;参与运算的结果和上一次调用有关&#xff0c;这时就可以使用递归来解决这个问题…

递归与递归算法实例(java实现)

一、递归介绍 递归算法&#xff08;英语&#xff1a;recursion algorithm&#xff09;在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。绝大 多数编程语言支持函数的自调用&#xff0c;在这些语言中函数可以通过调用自身来进行递归。 定义&#xff1…

Java的递归算法

递归算法设计的基本思想是&#xff1a;对于一个复杂的问题&#xff0c;把原问题分解为若干个相对简单类同的子问题&#xff0c;继续下去直到子问题简单到能够直接求解&#xff0c;也就是说到了递推的出口&#xff0c;这样原问题就有递推得解。 关键要抓住的是&#xff1a; &…

java递归算法实现

Coding多了&#xff0c;递归算法是非常常见的&#xff0c;最近我一直在做树形结构的封装&#xff0c;所以更加的离不开递归算法。所以今天就简单说一下这个递归算法&#xff0c;用java实现一个非常经典的递归实例。 递归算法&#xff0c;其实说白了&#xff0c;就是程序的自身调…

【Java】递归算法

文章目录 什么是递归&#xff1f;递归求阶乘递归求解斐波那契数列猴子吃桃问题 什么是递归&#xff1f; 程序 调用自身 的编程技巧成为 递归&#xff08;recursion&#xff09;。 递归算法是一种直接或间接调用、定义自身的函数或方法的算法&#xff0c;也就是调用自身。 递归…

Java递归算法

递归在程序语言中就是方法本身自己调用自己&#xff0c;而递归思想是算法的重要思想之一&#xff0c;就是利用递归来实现解决问题的算法。 递归也分为直接递归和间接递归。 那么什么叫直接递归什么又叫间接递归呢&#xff1f; //直接递归调用 function(){...function();... …

散布矩阵(scatter_matrix)及相关系数(correlation coefficients)实例分析

在进行机器学习建模之前&#xff0c;需要对数据进行分析&#xff0c;判断各特征(属性&#xff0c;维度)的数据分布及其之间的关系成为十分必要的环节&#xff0c;本文利用Pandas和Numpy的散布矩阵函数及相关系数函数对数据集特征及其关系进行实例分析。 散布矩阵(scatter_matri…

Probability And Statistics——CorrelationsCovariance

Skew&#xff08;偏度&#xff09; 在概率论和统计学中&#xff0c;偏度衡量实数随机变量概率分布的不对称性。偏度的值可以为正&#xff0c;可以为负或者甚至是无法定义。在数量上&#xff0c;偏度为负&#xff08;负偏态&#xff09;就意味着在概率密度函数左侧的尾部比右侧的…

structural covariance network

structural covariance network 结构协方差网络 结构协方差网络是一个较老的概念&#xff0c;只是近年受到了一定的重视。 大佬 Aaron Alexander-Bloch 在2013年通过一篇综述描述了这种结构协方差网络的应用意义及前景。 既往一般是在bold信号和fiber tracking建立连接&#xf…

_variant_t、CComVariant与COleVariant、CDBVariant

目前计算机语言多种多样&#xff0c;如C、Java、Basic、Pascal等&#xff0c;此外还有JavaScript、VBScript、ActionScript等脚本语言&#xff0c;它们各自维护自己的数据类型&#xff0c;当使用C这样强类型的语言来读取数据库或者与其他语言之间来交换数据时&#xff0c;它很有…