关于c++:通讯录管理系统的设计实现

一想到“管理系统”,咱们脑海里通常浮现四个字,增查删改。这也是必不可少的局部。我先把这个零碎我要实现的局部列举进去(当然,我的思路有很多有余,恳请大佬斧正,批评,不胜感激) cout << "***********1.增加联系人**********" << endl; cout << "***********2.显示联系人**********" << endl; cout << "***********3.删除联系人**********" << endl; cout << "***********4.查找联系人**********" << endl; cout << "***********5.批改联系人**********" << endl; cout << "***********6.清空联系人*********" << endl; cout << "***********0.退出零碎***********" << endl;(备注:退出也是其中一个性能哦) 首先,构建构造体变量 #define MAX 1000struct person{ string name; int sex{ }; int age{ }; string phonenumber; string address;};struct addressbook{ struct person personArr[MAX]; int person_size{ };增加联系人void addPerson(addressbook* aaa) //增加联系人模块{ if (aaa->person_size < MAX) { string name; cout << "请输出姓名:" << endl; cin >> name; aaa->personArr[aaa->person_size].name = name; int sex; cout << "请输出性别对应序号:(1--男 2--女)" << endl; while (true) { cin >> sex; if ((sex == 1) || (sex == 2)) { aaa->personArr[aaa->person_size].sex = sex; break; } else { cout << "您输出的有误,请查看后从新输出!" << endl; } } int age = 0; cout << "请输出年龄:" << endl; cin >> age; aaa->personArr[aaa->person_size].age = age; string phonenumber; cout << "请输出电话:" << endl; cin >> phonenumber; aaa->personArr[aaa->person_size].phonenumber = phonenumber; string address; cout << "请输出地址:" << endl; cin >> address; aaa->personArr[aaa->person_size].address = address; aaa->person_size++; cout << "增加联系人胜利!" << endl; } else { cout << "联系人已满,请删除局部联系人再增加!" << endl; } system("pause"); system("cls");}显示联系人void showperson(addressbook person){ if (person.person_size == 0) { cout << "联系人列表为空" << endl; } for (int i = 0; i < person.person_size; i++) { cout << i + 1 << "." << "姓名:" << person, personArr[i].name << " " << "性别:" << (person.personArr[i].sex == 1 ? "男":"女") << " " << "年龄:" << person.personArr[i].age << " " << "电话:" << person.personArr[i].phonenumber << " " << "住址:" << person.pearsonArr[i].address << " " << endl; } system("pause"); system("cls");}删除联系人void deleteperson(addressbook * person) ...

June 16, 2022 · 6 min · jiezi

关于c:安全目标

通信安全由许多不同的但互相关联的个性形成,这些个性广泛划分为三个次要类别: 保密性音讯完整性端点认证上面咱们挨个解释阐明: 1、保密性在思考齐全时,首先想到的可能就是保密性。保密性的意思就是对无关的人窃密。 举例说明:政府监听你的电话时,就是对你的保密性构成威胁。监听这种伎俩其实是一种被动攻打,如果监听者开始模拟你的声音和对方交换时这就形成主动攻击。个别咱们会通过一些伎俩避免或者扰乱窃听者. 比方:特务走进洗手间关上所有水龙头来扰乱窃听者时,就是需要保密性。2、音讯完整性音讯完整性,根本思维就是咱们要确信本人所收到的音讯就是发送者发送的音讯。 例如: 现代人们通过书信往来信息,尽管笔记很难从信中去除,然而能够减少一些笔记,或者间接找一个笔记模仿者从新写,而后再交给收信方,《水浒传》中就有这样的案例。在古代,通信音讯在网络中传输都是0101的比特位,看上去都很类似,所以在传输过程中摆弄起来音讯就很不便,攻击者去除、拷贝或者随便减少一些数据进去,而后被接收者接管,接收者却齐全不晓得。3、端点认证通过端点认证所要达到的目标其实就是要晓得通信中发送者就是咱们通信的端点。没有端点认证,要提供保密性和音讯完整性就十分艰难。 举例说明:如果咱们收到了一份来自Alice的音讯,但无奈确定该音讯是由Alice而不是攻击者发送的话,那么音讯的完整性对咱们来说毫无意义。当咱们向Bob发送一份机密消息,如果咱们实际上是将机密消息发送给了攻击者的话,对咱们来说就没有什么意义可言了。留神:端点认证能够是非对称的形式提供。当你给

June 16, 2022 · 1 min · jiezi

关于c++:OneFlow源码阅读5Global-Tensor

OneFlow的官网文档中提供了一个结构global tensor的例子。结构时指定placement和sbp参数就是全局视角的global tensor,数据能够散布在多个节点上。在单机CPU环境下,能够启动3个过程、每个过程设置不同的环境变量,运行如下Python代码就能够创立一个简略的global tensor。 # export MASTER_ADDR=127.0.0.1 MASTER_PORT=17789 WORLD_SIZE=3 RANK=0 LOCAL_RANK=0# export MASTER_ADDR=127.0.0.1 MASTER_PORT=17789 WORLD_SIZE=3 RANK=1 LOCAL_RANK=1# export MASTER_ADDR=127.0.0.1 MASTER_PORT=17789 WORLD_SIZE=3 RANK=2 LOCAL_RANK=2import oneflow as flowP0 = flow.placement("cpu", ranks=[0, 1])a0_sbp = flow.sbp.split(0)A0 = flow.Tensor([[1,2,3],[4,5,6]], placement=P0, sbp=a0_sbp)1 sbpsbp由split, broadcast, partial的首字母组合而成。 split示意物理设施上的tensor,是将global tensor切分失去的。broadcast示意global tensor会复制并播送到所有的物理设施上。partial示意global tensor与物理设施上的tensor的形态雷同,然而物理设施上的值,只是global tensor的一部分。Python端flow.sbp包定义了split等3种类型。其C++ binding代码在sbp_symbol.cpp中。这些类型都是SbpParallel类型,是protobuf message对象。三种类型通过oneof parallel_type共享存储。 其中broadcast和partial_sum都是空音讯,赋值时须要调用mutable办法显式表明oneof字段具体是哪种类型。split的值示意在tensor的哪个轴上切分数据。轴的index值是一个[[0, 5]之间的整数](https://github.com/Oneflow-In...)。所有的split SbpParallel对象被保留到一个动态vector中。 2 placement的结构placement属性指定tensor寄存在哪些物理设施上。或者,在纯CPU环境下,tensor寄存在哪些过程中。在上述例子中,flow.placement("cpu", ranks=[0, 1])创立一个placement对象。第一个参数是设施类型,目前反对cpu或cuda。ranks示意设施列表,tensor将散布在这些设施上(依据sbp的批示切分或播送数据)。ranks只列出了rank id(全局惟一),没有指定节点host。rank与host关系是依据环境变量确定的。环境变量RANK示意全局惟一的rank id,LOCAL_RANK示意节点内的本地rank id。在GPU环境下,个别一个过程对应一块设施。WORLD_SIZE示意所有节点的设施(过程)总数。 oneflow包在初始化时,会依据环境变量在各个节点间建设管制面通信连贯,以及数据面通信连贯。这样每个过程就晓得有多少个节点、有多少个设施/过程、以后过程在整个集群的地位。 通过placement的构造函数绑定能够晓得,其对应的C++类型是ParallelDesc。对象结构由函数CreateParallelDescSymbol实现。次要调用流程如下: 2.1 确定machine和deviceParseAndFormatRanks会将ranks数组[0, 1]转为形如"machine_id:device_id"的字符串数组,供后续解决应用。这里的逻辑决定了如何依据ranks中的id,确定tensor数据在节点和设施上的散布: machine_id = rank / NumOfProcessPerNodedevice_id = rank % NumOfProcessPerNode从上述公式能够看出,各个节点的设施/过程数量须要是统一的。 ...

June 15, 2022 · 1 min · jiezi

关于c:盲签名算法的原理与C语言实现

0x01 概述盲签名(Blind Signature) 是由Chaum,David提出的一种数字签名形式,其中音讯的内容在签名之前对签名者是不可见的(盲化)。通过盲签名失去的签名值能够应用原始的非盲音讯应用惯例数字签名验证的形式进行公开验证。盲签名能够无效的爱护隐衷,其中签名者和音讯作者不同,在电子投票系统和数字现金零碎中会被应用。 盲签名经常被类比成上面的场景:Alice想让Bob在本人的文件上签名,然而不心愿Bob看到文件内容,于是Alice在文件上方叠放了一张复写纸,而后将文件和复写纸放入信封密封起来交给Bob。Bob再拿到信封后验证了Alice的身份后,间接在密封好的信封上签字,这样尽管Bob是对密封后的信封签字,然而Alice拿到签名后的信封后,拆开信封就能够拿到通过Bob签字的文件。 0x02 RSA盲签名计划盲签名是一种音讯在签名之前就被盲化解决的数字签名计划,盲签名能够应用很多公钥加密计划来实现。这里只介绍最简略的一种实现,基于RSA加密算法的盲签名计划。假如音讯的持有者Alice心愿对音讯$m$应用盲签名计划进行签名,Bob是签名私钥的控制者,他们两方应该执行以下步骤: Alice抉择一个随机数$k$作为盲化因子Alice对原始的音讯进行计算,$m' = m k^e (mod \ n)$ 并把计算后(盲化)的音讯 $m'$发送给BobBob计算 $s' = (m')^d (mod \ n)$ 并把计算后的签名值 $s'$ 发送给AliceAlice计算 $s = s'k^{-1} (mod \ n)$,$s$ 就是Bob对原始音讯 $m$的数字签名证实: $(m')^d \equiv (m k^e)^d \equiv m^d k \ (mod \ n) $ $(m')^d k^{-1} = (m k^e)^d k^{-1} = m^d k^{e d} k^{-1} = m^d k k^{-1} \equiv m^d$ 0x03 C语言实现因为须要应用大数运算,能够应用你相熟的任何语言实现,也能够用任意成熟的大数运算库实现。这里我应用了mbedTLS的大数运算库。 //首先应用盲化银子blind_factor对原始的音讯m进行盲化,生成盲化音讯blind_messageint blindsignature_hide_message(mbedtls_mpi* m, mbedtls_mpi* blind_factor, mbedtls_mpi* e, mbedtls_mpi* n, mbedtls_mpi* blind_message){ int ret; mbedtls_mpi r; mbedtls_mpi_init(&r); // r = blind_factor ^ e mod n if ((ret = mbedtls_mpi_exp_mod(&r, blind_factor, e, n, NULL) ) != 0) { printf("Hide message: mbedtls_mpi_mod_init failed ret=%8X\r\n", ret); goto EXIT; } // m1 = m * r if ((ret = mbedtls_mpi_mul_mpi(blind_message, m, &r)) != 0) { printf("Hide message: mbedtls_mpi_mul_mpi failed ret=%08X\r\n", ret); goto EXIT; } // blind_message = m1 mod n if ((ret = mbedtls_mpi_mod_mpi(blind_message, blind_message, n)) != 0) { printf("Hide message: mbedtls_mpi_mod_mpi failed ret=%08X\r\n", ret); goto EXIT; }EXIT: mbedtls_mpi_free(&r); return 0;}//对盲化的音讯进行盲签名,过程同一般rsa签名一样int blindsignature_sign(mbedtls_mpi* blind_message, mbedtls_mpi* d, mbedtls_mpi* n, mbedtls_mpi* s){ int ret; mbedtls_mpi r; //s = m ^d mod n if ((ret = mbedtls_mpi_exp_mod(s, blind_message, d, n, NULL)) != 0) { printf("Blind signature: mbedtls_mpi_exp_mod failed ret=%08X\r\n", ret); goto EXIT; }EXIT: return 0;}//对签名后果blind_signature,应用blind_factor去盲化,失去签名值signatureint blindsignature_unblind_sign(mbedtls_mpi* blind_signature, mbedtls_mpi* blind_factor, mbedtls_mpi* n, mbedtls_mpi* signature){ int ret; mbedtls_mpi inv_blind_factor; mbedtls_mpi_init(&inv_blind_factor); if ((ret = mbedtls_mpi_inv_mod(&inv_blind_factor, blind_factor, n)) != 0) { printf("Unblind signature: mbedtls_mpi_inv_mod failed ret=%08X\r\n", ret); goto EXIT; } if ((ret = mbedtls_mpi_mul_mpi(signature, &inv_blind_factor, blind_signature)) != 0) { printf("Unblind signature: mbedtls_mpi_mul_mpi failed ret=%08X\r\n", ret); goto EXIT; } if ((ret = mbedtls_mpi_mod_mpi(signature, signature, n)) != 0) { printf("Unblind signature: mbedtls_mpi_mod_mpi failed ret=%08X\r\n", ret); goto EXIT; }EXIT: mbedtls_mpi_free(&inv_blind_factor); return 0;}0x04 总结RSA盲签名的代码、调用示例程序都曾经上传,能够间接检出测试,没有认真测试验证可能有各种问题,如果遇到问题,能够给我提issues。 ...

June 15, 2022 · 2 min · jiezi

关于c++:C出现cout不明确的问题的原因和解决方法

如果你有幸看到这个博客,那么我猜你应该曾经碰上这个问题,而且正急着寻求办法,因而,我先把解决办法用最简略的一句话写进去解决办法为:**将文件中原有的using namespace std;删除后保留cpp文件,再加上using namespace std;保留cpp文件。问题即可解决** 如果根据上述办法曾经解决了这个问题,感觉感兴趣,好奇怎么产生的这个问题,这里我大抵介绍下。 这个问题的知识点是namespace的用法:通过 namespace 关键字,能够申明命名空间,在命名空间内部须要通过齐全限定名拜访这些对象,通常状况下,申明的命名空间代码和调用的代码不在同一个文件里,因而在其余文件中应用,留神引入的门路要写正确,因而,呈现cout不明确的问题应该是门路不明确导致。 真挚的心愿这个简短的博客能够帮到遇到这个问题的敌人。

June 15, 2022 · 1 min · jiezi

关于c++:比特熊故事汇6月MVP英雄故事微软MVP-X-英特尔特邀专家一起消夏

夏日炎炎,吹着空调 共度一场直播时光 比特熊与新晋微软MVP和英特尔特邀嘉宾 带来全新技术主题和热门话题探讨 2022年6月17日(周五) 【比特熊故事汇】和你直播间相聚 比特熊消夏小礼物比特熊直播间心愿跟各位开发人和技术爱好者密切交换,大家能够通过直播互动和文章留言的形式一起参加!但凡转发本篇文章、在预报文章中踊跃发言或者参加直播弹幕互动的搭档,都有机会取得比特熊送出的小礼物。如果你对比特熊有话说,也能够留下你的声音。积极参与的小伙伴有机会取得比特熊精心筛选的礼物。 请大家积极参与的同时,退出“比特熊粉丝后援会”微信群,关注最新的流动信息和中奖名单。 P.S. –中奖信息将在本场直播后7个工作日内在“比特熊粉丝后援会”微信群中颁布。请留神接管高兴信息! 欢送大家继续关注【比特熊直播间】比特熊与你一起进阶,播种技能和高兴比特熊直播间,只做真直播 速速点击预约:B站 、CSDN 、流动行

June 13, 2022 · 1 min · jiezi

关于c#:C免注册调用大漠插件

免注册调用大漠插件,实际上是应用 dmreg.dll 来配合实现,这个文件有 2 个导出接口 SetDllPathW 和 SetDllPathA。 SetDllPathW 对应 unicode,SetDllPathA 对应 ascii 接口。 一、下载大漠插件下载地址:大漠插件解压实现后,如下图所示: 再解压 dm.rar、大漠类库生成工具.rar、免注册.rar,解压密码为:1234 解压实现后,如下图所示: 二、生成大漠类库#关上 大漠类库生成工具 文件夹,如下图所示: 关上 大漠类库生成工具 v24.0.exe 文件,如下图所示: 将 dm\7.2149\dm.dll 拖到 大漠类库生成工具 外面,如下图所示: 类名抉择应用自定义类名,指定类名输出 DmSoftCustomClassName(这里只是示例,你能够输出你喜爱的名字,如:abcde、aabbc、abab 等),如下图所示: 点击生成按钮,如下图所示: 关上 dm\7.2149\Output\C# 文件夹,能够看到生成的后果,如下图所示: 生成的 obj.cs 即是应用在 C# 平台下的类库封装,稍后在 C# 免注册调用大漠插件的示例中会用到。 三、创立控制台应用程序#我这里创立的是 .NET Core 3.1 的控制台应用程序,你也能够创立你喜爱的。 3.1 引入大漠插件 dll#在我的项目中创立 libs 文件夹,用于搁置大漠插件的 dll,如下图所示: dm.dll 在 dm\7.2149 文件夹下,如下图所示: DmReg.dll 在 免注册\不注册调用dm.dll的办法 v11.0 文件夹下,如下图所示: 设置 dll 属性 复制到输入目录 为 始终复制: 在 dm.dll 上单击鼠标右键,抉择 属性;在属性面板中,“复制到输入目录”选项,抉择“始终复制”;在 DmReg.dll 也反复下面的操作。 3.2 引入大漠类库#在我的项目中创立 DmSoft 文件夹,用于搁置大漠类库。 将之前生成的大漠类库(obj.cs)复制到我的项目中的 DmSoft 文件夹,并改名为 DmSoftCustomClassName(能够改名,也能够不改名,还能够改成任意名,你喜爱就好……),如下图所示: 3.3 创立 Resources 文件夹#在我的项目中创立 Resources 文件夹,用于搁置大漠插件应用到的资源,比方图片、字库等,如下图所示: ...

June 11, 2022 · 3 min · jiezi

关于c++:6-月-TIOBE-榜单C-即将超越-Java-进入-Top3PHP-热度再下滑

近日,TIOBE 出炉了 2022 年 6 月份的编程语言趋势榜单。本次数据显示,C++ 的热度和风行趋势行将超过 Java,而 PHP 热度再下滑,已跌出前十。 近年来,Java 语言的受欢迎趋势仿佛逐步处于“被超过”的状态。2020 年 4 月份,Java 还排在 TIOBE 指数榜单的第一位,起初 Java 却不得不将第一名让给 C。再起初的 2021 年榜单里,Python 也凭借势不可挡的趋势超过了 Java。而当初看来,C++ 或将成为下一个超过 Java 的编程语言。 C++ 为何体现如此杰出?要害起因在于高性能的高级编程。C++ 语言每三年订正一次,而这些订正蕴含了开创性的新个性,使语言与 C# 、Java 并驾齐驱,且没有垃圾收集器的性能损失。 TIOBE 6 月榜单:Java、PHP 热度上涨排在榜单前 3 位的编程语言别离为: Python(评级为 12.20%,评分上涨+0.35%)、C(评级为11.91%,评分降落-0.64%)、Java(评级为 10.47%,评分降落-1.07%)。 近年来 Python 编程语言热度一路上涨,相比去年 6 月,此前榜单第 2 的 Python 现在曾经来到了第 1 名的地位,与此前排名第位的 C 地位产生了调换。而本月排在第 3 位的 Java 则“奄奄一息”,数据降落了 1.07%,简直要被排在第 4 位的 C++(评级为 9.63%,评分上涨+2.26%)超过。 排在榜单第 5-10 位的别离为:C#(评级为 6.12%,评分上涨+1.79%)、Visual Basic(评级为 5.42%,评分上涨+1.40%)、JavaScript(评级为2.09% ,评估降落-0.24%)、SQL(评分为1.94%,评分降落+0.06%)、Assembly language(评级为1.85%、评分降落-0.21%)、Swift(评级为1.55%,评分上涨+0.44%)。 ...

June 11, 2022 · 1 min · jiezi

关于c#:MASA-Auth-从用户的角度看整体设计

用户在零碎里,用户是一个外围概念。它代表了一个人的惟一身份标识,除了与角色、团队、组织架构等无关,甚至还会影响到在同一个界面不同的用户操作流程与显示内容都会发生变化,再简单一点的话,或者在同一个零碎内的一个用户进入到不同产品后的身份也会变动 用户与角色用户能够领有一个或多个角色,让角色作为权限组,将一组或多组权限间接的调配给用户 用户与团队用户能够在多个团队中,每个团队能够领有一个或多个角色,将一组或多组权限通过角色与团队关联,并赋予团队内的成员 团队内成员能够是外部的,也能够是内部的。通过对立的用户表作为人的惟一身份标识。再通过Employee和ThirdPartyUser辨别用户身份属性。 用户与组织架构用户能够被指定在组织架构的某一个节点中 但组织架构是一个虚构的树形构造,它归属于业务,所以没有与权限间接关联 除此之外,组织架构有时候很难示意角色继承关系。在同一个组织架构节点中的不同成员经常会具备不同的角色,且上下级关系也未必会作为上下级节点紧贴在一起。有局部公司上下级之间可能隔了几个层级 组织架构在咱们晚期定义中是与权限关联且没有团队这个概念的。但实际上我的项目制在很多公司外部都存在,以我的项目制运行时,人员的权限和虚构组织关系会频繁变动。导致经常要在组织架构调整和大量集体权限微调上做抉择,为了彻底解决这种割裂的行为。咱们把组织架构看作虚构的树形构造来形容每个人的部门归属权,同时采纳团队的形式解决我的项目制下人员频繁进出和到处作战而引发的权限变更问题 用户与权限用户除了领有角色以外,可能还存在个别非凡业务下须要临时性授予或禁用局部权限 尽管与RBAC2有一点抵触,但事实上这样的场景确实存在,比方行将到职的财务须要长期发出付款性能,这里显著要违反互斥准则,在设计上咱们的抉择是扩大权限的优先级高于角色内蕴含的权限。这样能够通过对冲达到发出局部敏感权限的性能 用户类型用户有三种类型:终端用户,员工,驻场员工 举个例子: A是公司员工,领有外部权限。同时也是公司产品的终端用户B是驻场员工,领有局部外部权限。同时也是公司产品的终端用户 用户权限优先级用户的权限应该具备肯定的优先级,来解决同一个业务下多个权限同时失效时零碎该抉择激活哪一个 咱们将采纳以下规定: 超级管理员/管理员 超级管理员为系统管理员,管理员为指定我的项目的管理员用户的扩大配置权限用户的角色权限 用户的角色权限抵触时,回绝优先级高于容许,低于用户的扩大配置权限团队的默认角色权限团队中的父级角色权限 未来在团队反对上下级关系后,以后用户没有被调配到权限,且以后团队存在父级时将向上递归查找间隔最近的默认角色来取得权限列表用户权限类型用户的权限类型大略分为四类 菜单:是否能够通过菜单拜访某个页面页面元素:是否能够对页面内的元素进行操作,如按钮。页面元素须要挂在菜单下数据:是否显示指定字段。数据须要挂在菜单下 数据与页面元素相似,但与页面元素之间互相独立API:是否能够拜访指定API。API个别须要挂在菜单或页面元素下,如有须要也能够挂在数据下 权限层级 总结至此,咱们从一个用户的角度将角色和权限,前端与后端都串联了起来。但到目前为止还是概念的梳理阶段,做好一个权限核心很难。每个团队有本人的治理形式,如何在不同的团队需要中摘取到共同点把主线串联起来,既能满足绝大部分场景需要又留有扩大余地依然须要工夫去验证。 (本文章不代表最终设计) 参考: https://uxdesign.cc/design-pe... 开源地址MASA.BuildingBlocks:https://github.com/masastack/... MASA.Contrib:https://github.com/masastack/... MASA.Utils:https://github.com/masastack/... MASA.EShop:https://github.com/masalabs/M... MASA.Blazor:https://github.com/BlazorComp... 如果你对咱们的 MASA Framework 感兴趣,无论是代码奉献、应用、提 Issue,欢送分割咱们

June 7, 2022 · 1 min · jiezi

关于c++:OSG365-VS2017编译记录

OSG3.6.5 + VS2017编译记录网上有很多对于OSG的编译教程,也有他人编好的库(链接在这里)。然而看了很多,不如本人编译一次,上面记录下本人的编译过程。 一、源码下载官网下载地址,顺次下载源码、第三方库、数据。 1.osg 3.6.5源码,解压至OpenSceneGraph文件夹。 2.第三方库 下载对应VS版本的库,也能够本人用VS编译(太麻烦了),笔者间接应用曾经编译好的第三方库。下载后解压至3rdParty文件夹。 3.数据,下载后解压至data文件夹。 二、编译工具VS2017 + CMake3.19.8 三、编译流程cmake配置1.关上osg源码目录,新建build和install文件夹。关上cmake,别离抉择源码文件夹和bulid文件夹。 2.配置第三方库门路为3rdParty文件夹,编译后装置文件夹install,设置编译的是debug还是release版本 3.配置第三方库的门路,即osg依赖的各种lib的门路,具体的配置能够参考如下,本人能够依据名称在3rdparty的lib文件夹中寻找对应的lib,没找的能够临时不论。 4.点击左下角Configure按钮,抉择对应VS2017编译器,x64版本,点击确定。若无谬误,则会提醒configure done;若有谬误,则依据谬误提醒批改对应的配置即可。(碰到本人无奈解决的,能够分割我,尽全力帮忙解答^^) 5.点击Generate,即会生成VS2017的工程,生成实现后,点击Open Project按钮,也能够间接去build文件夹中关上。 6.关上工程后,先抉择debug-x64;再右键单击ALL_BUILD工程生成,若camke配置没问题的话,通过漫长的期待,提醒全副胜利;最初,右键单击Install工程生成,就会将生成的库拷贝到cmake设置的install门路下。 7.改成release-x64,反复步骤6即可。 最初,心愿大家都能编译胜利,若有问题,欢送交换!

June 7, 2022 · 1 min · jiezi

关于c++:简明的c笔记

1. 公有成员:private公有成员变量或函数在类的内部是不可拜访的,甚至是不可查看的。只有类和友元函数能够拜访公有成员。在类外面不写是什么类型,默认是 private 的。 就是说如果要拜访公有成员,必须是成员函数才能够拜访,内部不能间接赋值 2. 爱护成员:protected派生类的定义如下:派生类的成员函数能够被父类给复用 类外不能拜访protected成员3. 构造函数 4. 析构函数析构函数有助于在跳出程序(比方敞开文件、开释内存等)前开释资源5. 拷贝构造函数拷贝构造函数通常用于:* 通过应用另一个同类型的对象来初始化新创建的对象。* 复制对象把它作为参数传递给函数。* 复制对象,并从函数返回这个对象。参考链接 6. 友元函数它有权拜访类的所有公有(private)成员和爱护(protected)成员参考链接7.内联函数类定义中的定义的函数都是内联函数,即便没有应用 inline 说明符(如何应用,在变量类型后面加一个关键字inline就行)如果一个函数是内联的,那么在编译时,编译器会把该函数的代码正本搁置在每个调用该函数的中央。8. this指针每一个对象都能通过 this 指针来拜访本人的地址,友元没有this指针9. 指向类的指针 10.动态成员当咱们申明类的成员为动态时,这意味着无论创立多少个类的对象,动态成员都只有一个正本。动态成员在类的所有对象中是共享的参考链接11. 继承(基类和派生类) 一个派生类继承了所有的基类办法,但下列状况除外:* 基类的构造函数、析构函数和拷贝构造函数。* 基类的重载运算符。* 基类的友元函数。参考链接 12. 重载运算符和重载函数重载函数:函数同名但类型不同名// 留神重载和重写的区别运算符重载:例如间接实现同一个类的不同成员的相加,间接用运算符重载实现参考链接 13. 多态就是派生类继承他的父类可能会重写父类的办法如果多个派生类都重写了父类的办法,在同一时间内,多个派生都同时应用该办法,可能会呈现抵触,就要在父类中会被重写的办法减少关键字virtual14. 纯虚函数在基类中定义虚函数,以便在派生类中从新定义该函数更好地实用于对象,然而您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。参考链接15. 文件和文件流参考链接 16. 异样解决try throw catch参考链接17. 动态内存C++程序中的内存分为两个局部:栈:在函数外部申明的所有变量都将占用栈内存。堆:这是程序中未应用的内存,在程序运行时可用于动静分配内存参考链接 18.命名空间参考链接 19. 模板(泛型的根底)参考链接 20. 预处理器预处理器是一些指令,批示编译器在理论编译之前所需实现的预处理。#include <库函数名>#define __ __预约义宏参考链接 21. sleep函数 22. 援用和指针援用变量是一个别名 参考链接23. 枚举enum 24. typedeftypedef int int1;//给int1类型实质就是int类型#define int //1、定义一个构造体 typedef struct A { int a ; int b ; }A1;25. #define#define 与typedef 的区别sizeof();size()length()字符串和字符数组字符串是一个类,要应用要申明头文件#include <string.h>string a="1234";字符数组char arr[6];//这是一个字符数组,每一个数组元素存取一个char ...

June 3, 2022 · 1 min · jiezi

关于c#:NET-PDF中删除页面

PDF 文档通过页面来出现文字、图片等元素,一个 PDF 文档通常有多个页面。有时, PDF 文档中会有一些空白的,或全是不必要、无关内容的页面,尤其是在那些从网络取得的 PDF 文档中。咱们能够用 Spire.PDF for .NET 来删除这些页面。本文将教大家如何应用 Spire.PDF for .NET 删除PDF页面。 引入DLL一、 通过NuGet装置右键单击解决方案中的依赖项,找到“治理NuGet包”,在其中搜寻“FreeSpire.PDF”并增加到援用项中。复制上面代码到控制台装置PM> Install-Package FreeSpire.PDF 二、 手动增加DLL在Free Spire.PDF for .NET官网下载免费版后解压,在解决方案中找到依赖项,右键单击找到增加援用项,找到Spire.PDF.dll并增加到援用项中。 删除页面操作步骤用此工具删除页面非常简单,通过解决甚至可实现疾速删除多个文件的多个页面,具体操作步骤如下: 创立 PdfDocument 的对象。用 PdfDocument.LoadFromFile() 办法从磁盘载入 PDF 文档。用 PdfDocument.Pages.RemoveAt() 办法删除第三页和第二页。用 PdfDocument.SaveToFile() 办法保留 PDF 文档。C# 代码using System;using Spire.Pdf;namespace RemovePage{ internal class Program { static void Main(string[] args) { //创立 PdfDocument 的对象 PdfDocument pdf = new PdfDocument(); //从磁盘载入 PDF 文档 string input = @"D:\testp\示例.pdf"; pdf.LoadFromFile(input); //删除第三页和第二页 pdf.Pages.RemoveAt(1); pdf.Pages.RemoveAt(2); //保存文档 string output = "删除页面.pdf"; pdf.SaveToFile(output); } }}VB.NET 代码Imports SystemImports Spire.PdfModule Program Sub Main(args As String()) '创立 PdfDocument 的对象 Dim pdf As New PdfDocument() '从磁盘载入 PDF 文档 Dim input As String = "D:\testp\示例.pdf" pdf.LoadFromFile(input) '删除第三段和第二段 pdf.Pages.RemoveAt(2) pdf.Pages.RemoveAt(1) '保存文档 Dim output As String = "删除页面.pdf" pdf.SaveToFile(output) End SubEnd Module删除成果示意: ...

June 2, 2022 · 1 min · jiezi

关于c:CPT109-C-语言应用

CPT109 C Programming and Software Engineering 1 – ASSESSMENT 2Assessment Number 2Contribution to Overall Marks 50%Issue Date 08/11/2021Submission Deadline 06/12/2021 at 00:01Assessment OverviewThis assessment aims to test your ability to design a modular program which makes use offiles and structures. Application of the software development process (SDP) is also underassessment; the five steps required for your SDP report are: Problem specification: formulate the problem.Analysis: determine the inputs, outputs, variables, etcAlgorithm Design: define the list of steps (the algorithm) needed to solve the problem.Implementation: the C code has to be submitted as a separate file (.c).Just indicate here the name of the file. DO NOT paste your code into your report.Testing: explain how you have tested and verified your C program.Things to note:Submit only what is required.Include clear comments in your code to make it easy to understand.Use the C90 standard.ALL programs MUST compile and run in Visual Studio 2013.ExerciseThe game of hangman is a popular children’s word guessing game aimed at improvingspelling and general knowledge. A secret word is chosen (usually related to a chosen topice.g. a country or a fruit or vegetable) and the player tries to work out what the word is byguessing letters. Each time a player correctly guesses a letter in the word, then the lettersshould be filled in at their appropriate location in the word (see below). Note that the letterscan be guessed in any order. If the player guesses a letter incorrectly, then the hangman’sgallows (See Figure 1a) are constructed one line at a time for each wrong letter till the playerdies after 8 wrong guesses. A possible text-based version of the hangman’s gallows is shownin Figure 1b. Example game:Secret word entered by player 1 is: GuangzhouDisplayed on the screen is: Player 2 guesses: GDisplayed on the screen is: Figure 1a Hangman Picture Figure 1b Possible text-based drawingThe secret word should be either entered by a second user or randomly selected by theprogram from a file of words provided. Program users should create a unique passwordprotected account which will record their win/lose record, and which can be viewed.Program Requirements Allow users to create an account by selecting a username and password. The accountshould be saved in a file (unique to each user), which will contain a structure with thepassword and the win/lose history. Once a user is logged in they should be able to:Start a new gameReview their game historyClear their game historyLogout On starting a new game, there should be a choice either to play with a random secretword chosen from a data file (the filename should be provided) or for another user toenter a secret word. The player should guess letter one at a time. After each guess either the appropriate blankor blanks of the secret word are filled, or the next section of the picture is included, andboth the current word state and the current hangman picture are displayed. If the player completes the word before the hangman picture is complete, they win, if thepicture is complete first then they lose. All variables used must be local.Programming Suggestions/IdeasThe following points are only to provide you with ideas of how to implement the requiredfunctionality. They do not represent the “best” or only ways to implement the functions. All player accounts are structure variables and will be stored in a unique file i.e. one filefor each player account. Create new accounts by creating a new file with the usernameselected. The login process can be achieved by trying to open a file, if successful thestructure stored in the file can be copied into the program memory. When the player logsout only this one structure needs to be written back to the file. Try to create your own functions to simplify the programming task, for example use onefunction to draw the hangman picture. Consider how your program should function when there is an invalid input. You can design your own figure (it is your interpretation of the game). Consider the playability, how can you make the user interaction more interesting forexample add your own rule such as do not allow vowel letters (a, e, i, o ,u), or maybeonly 1 vowel letter is allowed. You may wish to display a list of the wrongly guessedletters as a reminder to the playerSubmissionYour assessment should be submitted electronically through the Learning Mall Online(LMO). Feedback and your grade will also be given through LMO.Software Development Process (SDP) report (5 steps) named: studentID_A2.pdfSourcecode (.c) file named: studentID_A2_1.cData file: data.txtThis is the file containing the words to be used when playing the game against the computerSubmission should be a single compressed file containing at least 3 files:1234567_A2_1.c1234567_A2.pdfdata.txt1234567_A2.zipCompressed folder can be of type .zip, .rar or .7zIf you have multiple program files please use the following naming convention: Sourcecode files (.c) you should number these accordingly e.g. 1234567_A2_2.c. Header files (.h (and associated .c file), name these: 1234657_A2_H1.h(1234567_A2_H1.c) if there are more than one number them accordingly (i.e. H1, H2..).MarkingOverall Report Quality 10%Problem Specification 10%Analysis 10%Algorithm Design 10%Implementation 40%Robustness 10%Testing 10%Please refer to the file “CPT109 Marking Guidelines for Assignment 2” on LearningMall for details on marking descriptions.You are responsible for ensuring that your C code will run in Visual Studio 2013. If it doesnot without documentary explanation you may get a 0 mark for your implementation.There will be a 5% deduction for incorrectly named files in your submission.Important notes:University late submission policy will be applied.University Academic Integrity policy will be applied rigorously. Plagiarism and collusionwill not be tolerated.You can find information relating to both of these in ebridge. ...

June 1, 2022 · 5 min · jiezi

关于c++:拯救工程师远程开发C的四大秘笈|视频教程

因为新冠疫情的影响,越来越多的国内公司开始反对近程办公 (https://github.com/LinuxSuRen...),OneFlow也是如此,简直所有的实习生与超过三分之一的全职研发人员都是近程办公。 作为一名技术人员,尤其是一名C++工程师,近程办公须要操心的首要问题可能就是“如何搭好用的近程开发环境”,具体包含本地和服务器的操作系统不统一怎么办?用不惯服务器上的编辑器、IDE怎么办?每次新机器都要从新配环境很苦楚怎么办? 只有想办,这些都不是问题。 从实践经验登程,B站Up主“不想吃糖liao”制作了“近程开发C++系列”手把手教学视频。不要被它的名字吓到了:C++的确很深奥,但那是其余系列要解决的问题。 在“近程开发C++系列”里,次要是介绍近程办公的必备工具、技能。置信有不少人对通过SSH登录服务器、Linux/Windows下对立的C++工程构建等操作并不相熟,从现在起,这些问题再也不必放心,Up主“不想吃糖liao”将向你分享近程开发的上手秘笈,请留神查收! 秘笈一:VS Code插件 Remote SSH https://www.bilibili.com/vide... 小糖展现了如何通过SSH登录一个服务器,同时介绍一款十分好用的VS Code插件Remote SSH,该插件能够让咱们在近程服务器开发像在本地开发一样简略。 秘笈二:不会在Linux/Windows下装置软件?Conda帮你一键搞定 https://www.bilibili.com/vide... 很多人都有这样的经验:想要疾速上手一个我的项目的时候,却发现搭环境都要耗个十天半个月,不是动静库找不到,就是头文件找不到,再者,跑起来又发现依赖的包的版本又不对。因而,小糖向大家举荐了一款环境治理神器Conda,同时介绍了Conda的根本应用和用Conda启动《入手深度学习》的学习环境。 秘笈三:编译C++我的项目必备CMake https://www.bilibili.com/vide... 秘笈四:Linux下如何打造C++完满开发IDE:clangd https://www.bilibili.com/vide... 个别咱们在Windows上做C++开发首选的IDE是Visual Studio,Visual Studio号称宇宙第一IDE,也的确十分好用,但如果须要在Linux上做C++开发,那该怎么办?托LLVM和VSCode的福,只有领有VSCode,再配上clangd插件,就能够使VSCode领有和IDE一样的体验。小糖在本期内容中为具体介绍了clangd插件的性能及其下载和应用办法。 以上就是C++近程开发的次要内容。欢送关注小糖的B站账号“不想吃糖liao”,更多C++相干内容等你来发现。 欢送下载体验 OneFlow v0.7.0 最新版本:https://github.com/Oneflow-In...

May 31, 2022 · 1 min · jiezi

关于c:CC-单元自动化测试解决方案实践

vivo 互联网服务器团队 - Li QingxinC/C++ 开发效率始终被业内开发人员诟病,单元测试开发效率也是如此,以至于开发人员不愿花工夫来写单元测试。那么咱们是不是能够通过改善编写单元测试的效率来晋升我的项目的测试用例覆盖率? 本文次要介绍如何利用GCC插件来实现晋升C/C++开发者的单元效率工具解决方案,心愿对大家在晋升单元测试效率上有所启发。 一、动机 上图展现了C/C++单元测试的根本流程,在日常开发过程中写单元测试是一项比拟大工程量的事件,C/C++ 目前单元测试代码都须要本人手动写,而且对于一些公有办法打桩就更加麻烦。 目前业内无开源的自动化测试框架或者工具,倒是有一些商业的主动测试工具,下图展现了咱们自动化测试工具及单元测试库: 即便开源界有gtest等测试库的反对,咱们依然须要编写大量的单元测试用例代码。对于一些private、protected的类办法,编写单元测试用例的效率就更低,须要手动打桩(mock)。同时咱们剖析测试用例发现,存在很多边界的用例,它们基本上都是很固定或者有肯定模式,比方int 最大最小值等。 如何改善编写单元测试的效率,晋升C/C++同学开发效率以及程序品质?咱们能够通过提取源文件中的函数、类等信息,而后生成对应的单元测试用例。主动生成用例时须要依赖函数的申明、类的申明等信息,那么咱们应该如何获取这些信息呢? 例如:如下的函数定义: void test(int arg) {}咱们心愿可能从下面的函数定义中失去函数的返回值类型、函数名称、函数参数类型、函数作用域。通常咱们能够通过以下几种形式失去: 1.1 办法1:应用正则表达式无奈C/C++ 格局比较复杂可能尽管可能应用多种组合来获取对应的函数申明等信息: void test(int arg){}void test1(template<template<string>> arg,...){}void test2(int(*func)(int ,float,...),template<template<string>> arg2){}那么就须要写一系列的正则表达式: 提取函数名称、参数名:[z-aA-Z_][0-9]+提取函数返回值:^[a-zA-Z_]关键词提取进去了,然而他有一个很大的问题:怎么判断文件中书写的代码是合乎C/C++语法形容呢? 1.2 办法2:应用flex/bison 剖析c/c++源码文件这当然是一种很好的形式,然而工作量微小,相当于实现一个具备词法、语法分析器繁难版本的编译器,而且要适配不同的语法格局,尽管bison能够解决上述的如何判断语法是否正确问题,然而依然很简单。 1.3 办法3:利用编译曾经生成的AST 来生成代码通常咱们理解到的GCC编译的过程是以下四个阶段: 源文件->预处理->编译->汇编→链接但实际上GCC为了反对更多的编程语言、不同的CPU架构做了很多的优化,如下图所示: 上图展现了GCC解决源码及其他优化过程,在前端局部生成的Generic 语言是gcc编译过程中为源码生成的一种与源码语言无关的形象语法表现形式(AST)。既然GCC编译过程中生成了AST树,那么咱们能够通过GCC插件来提取GCC 前端生成的形象语法树要害信息比方函数返回值、函数名称、参数类型等。总体难度也很高,一方面业内可参考资料很少,只能通过剖析GCC的源码来剖析AST语法树上的各个节点形容。 本文所形容的自动化生成单元测试用例的解决方案(咱们称之为TU:Translate Unit,后文统称为TU)就是基于办法3来实现的,上面咱们先来看看咱们的自动化测试用例解决方案的成果展现。 二、成果展现2.1 业务代码零批改, 间接应用TU生成边界用例 在该用例中咱们不须要批改任何业务代码就可能为业务代码生成边界测试用例,而且函数参数可边界值实现全排列,大大降低用例脱漏危险。大家可能发现这种没有做任何批改生成的用例是没有断言的,尽管没有断言,它依然可能帮忙发现单元是否会存在边界值引起coredump。 那么如果想要给他加上断言、mock函数,是否没有方法呢?通过C++11 [[]] 新的属性语法,只须要在办法申明或者定义时增加下依据TU的格局增加断言即可,对业务逻辑无侵入。 2.2 应用注解tu::case生成用户自定义用例很多状况下默认生成的边界测试用例还不能笼罩到外围逻辑,所以咱们也提供tu::case 来给用户自定义本人的测试用例及断言。比方有一个int foo (int x,long y) 办法,当初想新增一个测试用例返回值123,函数实参1,1000,那么只有在函数申明前退出,以下代码即可: [[tu::case("NE","123","1","1000")]] 2.3 应用注解tu::mock 主动生成mock办法开发过程中咱们也常须要对某个办法进行mock(即对原有办法设置一个长期代替办法并且调用形式保持一致),比方某个函数拜访Redis、DB这种状况下进行单元测试往往须要对这些办法进行mock,不便其余函数调用进行单元测试,为了不便进行单元测试咱们往往会对其进行mock,所以为了不便开发人员进行疾速的mock,所以咱们提供了tu::mock 的注解帮忙开发同学疾速的定义注解,而后TU会主动生成对应的mock函数。例如:当初给foo_read 办法mock一个函数,让mock的函数返回10: 三、TU实现计划3.1 AST 是什么?GENERIC、GIMPLE和RTL三者形成了gcc两头语言的全副,它们以GIMPLE为外围,由GENERIC承上,由RTL启下,在源文件和指标指令之间的鸿沟之上构建了一个三层的过渡。 ...

May 31, 2022 · 1 min · jiezi

关于c++:浅谈c中的Pimpl

浅谈c++中的Pimpl什么是Pimpl?Pimpl 意思为“具体实现的指针”(Pointer to Implementation), 它通过一个公有的成员指针,将类的实现细节进行暗藏,从而达到缩小依赖、暗藏实现的目标。 利用实例1、如果有如下场景: Project A援用了多个第三方库OSG来实现具体的性能。Project B援用了 A,这时候如果A减少了osg的依赖,B在应用A时就很难防止不应用到OSG,这样对于B又须要从新编译等等,十分麻烦。2、解决办法: 利用类的前置申明 + 公有成员指针3、具体实现: ClassA.h 头文件 #pragma once class ClassAPrivate; //公有类前置申明 class ClassA { public: ClassA(); ~ClassA(); //测试 void testFun(); private: //公有指针 ClassAPrivate* d_ptr; };ClassA.cpp 源文件 #include "ClassA.h" #include "ClassAPrivate.h" ClassA::ClassA() :d_ptr(new ClassAPrivate(this)) { } ClassA::~ClassA() { } void ClassA::testFun() { d_ptr->testFun(); //函数用公有类实现 }ClassAPrivate.h 公有类头文件 #pragma once #include "osg/Node" class ClassA; //私有类前置申明 class ClassAPrivate : public osg::Node { public: ClassAPrivate(ClassA *qPtr); ~ClassAPrivate(); void testFun(); ClassA* q_ptr; //保留共有类指针,可能须要调用私有类函数 };公有类源文件依据具体需要实现即可。 ...

May 30, 2022 · 1 min · jiezi

关于c++:DeepRoute-Lab-C大杀器超实用在线工具推荐

C++作为语法最简单、写代码时最须要思前顾后的语言,咱们不在身边顺手备用几个“大杀器”在线工具,可能真的不是很利于工作的发展呐。 置信大家对上面这两个网页曾经十分相熟了,它们是编写代码过程中必不可少的工具宝典。 1. cppreference2. cplusplus** 上述两个网页次要是提供十分详尽的语法层面的材料。 除此之外,我将从其余各个方面给大家举荐几个绝对小众然而十分实用的在线工具。 置信我,接触了这几个工具后,你肯定会爱上它们的。 实用在线工具 ✦首先,这几个工具具备如下的通用性能 01 设置运行平台、编译器及版本 x86、x64、arm gcc、clang 7.5.0、9.4.0,etc 02 设置C++语言版本 c++11、c++14,etc 03 设置编译优化选项 Og、O1、O2,etc 上面,我将联合本人的应用教训,顺次介绍这几个工具的典型利用场景和应用成果。 从编译器的角度看源码这就是C++ Insight 咱们在写代码的时候,如果不是对C++规范和编译器一目了然,可能很难晓得编译器在底下到底做了什么。应用C++ Insights,能够帮咱们一探到底。 应用花括号初始化,编译器保障了所有的成员函数都会被(递归地)初始化。 帮忙咱们一览C++ 14的generic lambda expression 是怎么被编译器开展的。 展现了编译器在用户不自定义构造函数时,会主动生成对应的构造函数(到这里一切正常)。 这里仅仅是在原有代码中新增了一个默认析构函数,如果没有看到编译器生成的代码,可能很难设想挪动构造函数基本不会生成吧?起因是什么呢?能够自行搜寻一下 rule of five 和 rule of zero。 具体到这个例子,因为如果你的类外面只申明了自定义的/默认的 copy (ctor & assignment operator) 或者 destructor,那么他们会 suppress 编译器生成默认的 move (ctor & assignment operator) 。 联合C++ Insights,咱们能够很不便地领会模板参数匹配和援用折叠。 实时汇编剖析这就是赫赫有名的Compiler Explorer 它次要用来做实时汇编的生成,帮忙咱们疾速剖析代码片段在不同设置下的汇编代码生成,疾速提供代码优化方向,并阻止咱们自作聪明地去优化代码,感触编译器的弱小。 下面两张图通知咱们不要在古代编译器背后班门弄斧…… clang 真是威力无穷啊,间接返回了编译器的后果。 ...

May 30, 2022 · 1 min · jiezi

关于c:Redis源码解读跳跃表

Redis 中的跳跃表构造 每个节点都有各自的分层,后退节点,后退节点,键以及分值。 后退节点即用来从跳跃表尾部从后向前遍历。后退节点有两局部:后退指针,以及后退的步长。这个步长能够用来计算排位,比方在查找某个节点过程中,将两头的跨度加起来,就能够失去它在跳跃表中的排位。跳跃表节点定义: typedef struct zskiplistNode { sds ele; double score; struct zskiplistNode *backward; // 后退节点 struct zskiplistLevel { struct zskiplistNode *forward; // 后退节点 unsigned long span; } level[];} zskiplistNode;跳跃表节点外部有一个对于层数的柔性数组,代替了传统的 up、down 指针。 跳跃表定义: typedef struct zskiplist { struct zskiplistNode *header, *tail; // 首尾节点 unsigned long length; // 元素个数 int level; // 层高} zskiplist;咱们再察看下面的 head 节点,head 节点不存放数据,并且层高固定为 32 层,32 层曾经满足对于 2 ^ 64 个元素查找的效率了,所以跳跃表最高也就是 32 层。 创立、开释跳跃表创立跳跃表节点创立一个指定层数的跳跃表节点,sds 字符串 ele 将会被该节点援用。sds 字符串即是跳跃表节点的键 ...

May 29, 2022 · 6 min · jiezi

关于c:error-conflicting-types-for-xxx-in-c

一、问题形容#include <stdio.h>#define MAXLINE 1000/* maximum input line length */int getline(char lines[], int maxline);void copy(char to[], char from[]);int main(void){ int len; // current line length int max; // maximum lenght seen so far char line[MAXLINE]; // current input line char longest[MAXLINE]; // longest line max = 0; while ((len = getline(line, MAXLINE)) > 0) if ( len > max) { max = len; copy(longest, line); } if (max > 0) printf("%s", longest); return 0}int getline(char s[], int lim){ int c, i; for(i = 0; i < lim -1 && (c = getchar()) != EOF && C != '\n'; ++i) s[i] += c; if (c == '\n') { s[i] = c; ++i; } return i;}void copy(char to[], char from[]){ int i; i = 0; while ((to[i] = from[i]) != '\0') ++i;}运行以上代码的时候呈现谬误提醒:error: conflicting types for 'getline'; have 'int(char *, int)'。代码来源于《C Programming Language》。 ...

May 28, 2022 · 2 min · jiezi

关于c++:翻译Traits一种新的而且有用的Template技巧

文章来自Traits: a new and useful template technique 应该是很老(1995)的文章了,不过很适宜作为Template入门的资料。 ANSI/ISO C++规范库一开始就想反对国际化(internationalization),尽管一开始还没相好具体细节,然而最近5年逐步有点头绪了。当初失去的论断是,该当用template来对须要进行字符操作的工具进行参数化。 给现有的iostream和string类型进行参数化其实挺难的,须要创造一种新的技术才行。侥幸的是,这种技术能够很好的服用在其余中央。 问题在iostream中,streambuf须要一个EOF来实现本身的性能。在个别的库中,EOF就是一个int而已;一些须要读取字符的函数也只返回int数值。 class streambuf { ... int sgetc(); // return the next character, or EOF. int sgetn(char*, int N); // get N characters. };但如果用一种字符类型来参数化streambuf,会产生什么?一般来说,程序并不需要这个类型,而是须要这个类型的EOF的值。先试试看: template <class charT, class intT> class basic_streambuf { ... intT sgetc(); int sgetn(charT*, int N); };这个多进去的intT就有点烦人了。库的应用刚才不关怀所谓的EOF是啥。问题还不只这个,sgetc在遇到EOF时应该返回什么?莫非要再来一个模板参数?看来这种形式行不通。 Traits技法这时候就须要引入Traits了。有了traits,就不须要从原来的模板里间接取参数,而是定义一个新的模板。用户个别不会间接应用这个新的模板,所以这个模板名字能够起的人性化一点。 template <class charT> struct ios_char_traits { };默认的traits是个空类。对于实在的字符类型,能够特化这个模板以提供有意义的语义。 struct ios_char_traits<char> { typedef char char_type; typedef int int_type; static inline int_type eof() { return EOF; } };ios_char_traits<char>并没有数据成员,只有一些定义。再看看streambuf该怎么定义。 ...

May 27, 2022 · 2 min · jiezi

关于c++:翻译c类中空成员的优化

文章来自于The "Empty Member" C++ Optimization。是我在看c++ std::string代码时遇到的一个链接,其中解释了为什么_Alloc_hider会采纳inhert from Alloc的起因。文章应该是97年的,所以外面的指针长度还是4 byte。c++类中“空成员”的优化C++规范库中有很多有用的模板,包含享誉盛名的SGI STL。这些模板的实现很高效,也不失灵便。在日常的编程中,能够把这些模板当作范例来进行学习,也可启发咱们如何进行兼顾灵活性与效率的程序设计。 “空成员”的优化,就是这样的一个榜样:一个没有类成员的class,就不应该占用内存空间。什么状况下须要一个没有类成员的class呢?这样的class个别会领有一系列的typedef或者成员函数,而程序的调用方能够用本人定义的相似的class来实现一些非凡的性能(自定义的class可不肯定没有类成员)。这个默认提供的class应该能够满足绝大多数的需要。这种状况下,优化这个空成员的class是个很有性价比的事件。 因为语言的限度(之后会解释),空成员的class通常会占据肯定的内存空间。如果是个别状况也就算了,然而在stl里,不进行优化的话,还是会劝退很多潜在的使用者的。 空成员“收缩”以STL举例。每个STL的容器都有一个allocator的参数,当容器须要内存的时候,它会向allocator去申请。如果用户想要本人定制化内存申请过程,那么就能够在结构容器时提供本人的allocator。大多数状况下,容器用的是STL默认的allocator,这个默认的allocator间接调用new来实现调配。这是个空类,相似于上面这个定义 template <class T> class allocator { // an empty class . . . static T* allocate(size_t n) { return (T*) ::operator new(n * sizeof T); } . . . };举个list的例子,class list保留了一个公有的allocator成员,这个成员在构造函数里进行赋值 template <class T, class Alloc = allocator<T> > class list { . . . Alloc alloc_; struct Node { . . . }; Node* head_; public: explicit list(Alloc const& a = Alloc()) : alloc_(a) { . . . } . . . };成员list<>::alloc_通常占据4 byte,只管这个Alloc是个空类。这通常来说不太会是个问题。但万一list本身是一个微小的数据结构的一个节点(比方vector<list>),当vector很大的时候,这种额定的空间耗费是不可漠视的。微小的内存占用意味着更慢的执行速度。就算在当下,绝对于cpu本身的频率来说,内存拜访曾经十分慢了。 ...

May 26, 2022 · 2 min · jiezi

关于c++:Effective-c条款2尽量以constenuminline替换define

条款2(Clause 2):Prefer consts, enums, inlines to #defines 1应用const替换#define比方:将上面的替换 #define ASPECT_R 1.00为 const double AspectR=1.00;起因:可能记号名称ASPECT_R未进入记号表内,当你使用这个常量的时候,显示的报错信息外面可能不会提到ASPECT_R,只提到了1.00,所以找不到谬误在哪里。而应用const就不会呈现这种状况。 两种非凡状况1,定义常量指针(constant pointer)写两次constconst char* const name="Yap Miracle";//上面这样更好const std::string name("Yap Miracle");2,class专用常量不必宏定义来实现函数别用这种函数 #define CALL_WITH_MAX(a, b) F((a) > (b) ? (a): (b))应用 template <typename T>inline void callWithMax(const T& a,const T& b){ f(a > b ? a : b); //f为简略比拟函数}这种写法有很多益处,它恪守作用域和拜访规定。 最初请记住1、对于单纯常量,最好以const对象替换#define。2、对于形似函数的宏,最好改用inline替换#define。3、#include和#ifdef,#ifndef依然是必需品。

May 16, 2022 · 1 min · jiezi

关于c:C程序设计-07-函数

若程序性能较多,规模较大,将所有的程序写在一个 main 主函数中,会使得主函数庞杂,浏览和保护艰难大。于是提出模块化程序设计: 在设计一个较大的程序时,往往将它分为若干个程序模块,每个模块包含一个或多个函数(function),每个函数实现一个特定的性能。一个 C 程序可由一个 main 函数和若干个其余函数形成,程序的执行是从 main 函数开始的。函数间能够互相调用,但其余函数不能调用 mian 函数,一个函数能够被一个或多个函数调用屡次。所有函数都是平行的、互相独立的,函数不能嵌套定义。从用户应用的角度看,函数分为:库函数和用户自定义的函数。 从函数模式上看,函数分为:无参函数和有参函数。 一、定义函数C 语言要求程序中所有用到的函数,必须先定义后应用。定义函数应包含以下几个内容: 函数的名字。函数的类型,即函数返回值的类型。函数的参数名和参数类型(无参数函数不须要)。函数的性能。对于 C 编译系统提供的库函数,是由编译系统当时定义好的,只需应用 #include 指令引入到程序文件中即可应用。 1. 定义无参函数定义无参函数的个别模式有两种: // 模式1类型名 函数名(){ 函数体}// 模式2类型名 函数名(void){ 函数体}模式 2 中括号内 void 示意“空”,即函数没有参数。 定义函数时,如果函数无类型,即无函数值,能够应用 void 代替类型名。这时,执行函数后,不会把任何值带回 main 函数中。 2. 定义有参函数定义有参函数的办法为: 类型名 函数名(形式参数表列){ 函数体}例如,定义一个求两个数中最大值的函数: int max(int x, int y){ int z; z = x > y ? x : y; return(z);}数组元素的作用与变量相当,因而,数组元素也能够作为函数实参,其用法与变量雷同。此外,数组名也能够作为实参和形参。形参数组能够不指定数组大小(高维数组只能疏忽第一维)。 float average(float array[], int n){ float aver, sum = array[0]; int i; for(i = 1; i < n; i++) sum = sum + array[i]; aver = sum / n; return aver;}须要留神,应用数组名作为函数实参时,不是吧数组元素的值传递给形参,传递的是数组的第一个元素的地址,这样两个数组就占用同一段内存单元,当形参数组中各元素值发生变化,实参数组元素值也会发生变化。这与变量作函数参数的状况不同。 ...

May 16, 2022 · 3 min · jiezi

关于c:Redis源码解读字典

[toc] 四个数据结构dictEntrydictEntry 的构造如下(Redis 7.0): typedef struct dictEntry { void *key; // 键 union { void *val; uint64_t u64; int64_t s64; double d; } v; // 值 struct dictEntry *next; /* Next entry in the same hash bucket.即下一个节点 */ void *metadata[]; /* An arbitrary number of bytes (starting at a * pointer-aligned address) of size as returned * by dictType's dictEntryMetadataBytes(). */} dictEntry;能够比照 《Redis 设计与实现》中的 dictEntry 构造,发现联合结构 v 中多了一个 double 的浮点数示意,metadata 是一块任意长度的数据,具体的长度由 dictType 中的 dictEntryMetadataBytes() 返回,作用相当于 privdata ...

May 16, 2022 · 11 min · jiezi

关于c++:ECECS-472572-C求解

Final ProjectECE/CS 472/572 Final Exam ProjectLate submissions will be penalized 15 points per day.Remember to check the errata section (at the very bottom of the page) for updates.Your submission should be comprised of two items: a .pdf file containing your written report and a.tar file containing a directory structure with your C or C++ source code. Your grade will be reduced ifyou do not follow the submission instructions.All written reports (for both 472 and 572 students) must be composed in MS Word, LaTeX, or some otherword processor and submitted as a PDF file.Please take the time to read this entire document. If you have questions there is a high likelihood thatanother section of the document provides answers.IntroductionIn this final project you will implement a cache simulator. Your simulator will be configurable and will beable to handle caches with varying capacities, block sizes, levels of associativity, replacement policies,and write policies. The simulator will operate on trace files that indicate memory access properties. Allinput files to your simulator will follow a specific structure so that you can parse the contents and use theinformation to set the properties of your simulator.After execution is finished, your simulator will generate an output file containing information on thenumber of cache misses, hits, and miss evictions (i.e. the number of block replacements). In addition,the file will also record the total number of (simulated) clock cycles used during the situation. Lastly, thefile will indicate how many read and write operations were requested by the CPU.It is important to note that your simulator is required to make several significant assumptions for the sakeof simplicity. ...

May 15, 2022 · 22 min · jiezi

关于c:基于QT5的文件读取程序的实现

目录一、文件读写操作QFile1.1 头文件1.2 外部函数二、UI设计三、代码3.1 mainwindow.h3.2 mainwindow.c四、成果 一、文件读写操作QFileQT自带了一个文件操作的类->QFile ,试验中也是着重 QFile 的操作 1.1 头文件#include<QFile>1.2 外部函数这些函数没必要都去记住,咱们只须要记住简略的例如open()、readLine()、atEnd()、close() 等罕用的函数即可 首先咱们new 一个 QFile 对象的时候有四种构造方法,通常来说咱们传入 文件的路径名 就好了而后咱们要调用open()函数,这个函数是通知操作系统咱们通过什么样的形式关上,例如只读关上、只写关上、可读可写关上……,这个和咱们在C语言中的文件关上函数是相似的,咱们在QIODevice看到一个枚举类型的 OpenModeFlag打开方式 enum OpenModeFlag { NotOpen = 0x0000, ReadOnly = 0x0001, WriteOnly = 0x0002, ReadWrite = ReadOnly | WriteOnly, Append = 0x0004, Truncate = 0x0008, Text = 0x0010, Unbuffered = 0x0020, NewOnly = 0x0040, ExistingOnly = 0x0080 };这些就是文件关上的一些模式了,能够依据本人的需要选用,咱们这里既然是文件的读取显示操作,那么只须要读取,于是咱们的打开方式就是:QIODevice::ReadOnly 而后就是对这个文件从头到尾读取,在以前咱们学的C语言中有一个文件完结标记EOF,个别这个EOF是 − 1 -1 −1 然而这里的QFile 提供了一个函数atEnd()如果当咱们读到了文件开端,那么就会返回一个true 例如: QFile file("in.txt");if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return; while (!file.atEnd()) { QByteArray line = file.readLine(); process_line(line);}最初咱们通过file.close()敞开数据流就好了 ...

May 15, 2022 · 2 min · jiezi

关于c#:C跨PC远程调用程序并显示UI界面

在我的项目中有一个需要是须要在局域网内跨PC近程调用一个程序,并且要求有界面显示,考察了一些材料,能实现近程调用的.Net技术大略有PsExec、WMI、Schedule Task。 这三种形式都做了一个尝试,后果发现PsExec、WMI都只能在过程列表中看到程序执行,却无奈显示界面,无奈执行程序中的管理员权限操作,就连简略的在C盘创立一个txt文本都做不到。 兴许是我应用办法不对,无奈达到我的需要。直到起初应用了Schedule Task的形式之后,才胜利实现了我的需要。 第三种技术的次要思路是先通过CMD窗口调用schtasks命令在近程PC上创立一个单次执行的打算工作,在打算工作中调用内部程序,而后立刻执行,能够显示界面,并且能够执行管理员权限的操作。 用到的schtasks命令: string queryTaskArg = string.Format(@" /query /s {0} -u domainname\{1} -p {2} /tn install", ip, username, password);string creatTaskArg = string.Format(@" /create /s {0} -u domainname\{1} -p {2} /sc ONCE /st 10:00 /tn installSelector /tr {3} /rl HIGHEST /ru Local /IT", ip, username, password, installPath);string runTaskArg = string.Format(@" /run /s {0} -u domainname\{1} -p {2} /tn install", ip, username, password); ;string deleteTaskArg = string.Format(@" /delete /s {0} -u domainname\{1} -p {2} /tn install /F", ip, username, password);schtasks /create 创立打算工作 ...

May 15, 2022 · 2 min · jiezi

关于c++:一文详解C中运算符的使用

目录一、算术运算符二、关系运算符三、逻辑运算符四、位运算符五、赋值运算符六、杂项运算符 一、算术运算符运算符 形容 把两个操作数相加从第一个操作数中减去第二个操作数把两个操作数相乘/ 分子除以分母% 取模运算符,整除后的余数++ 自增运算符,整数值减少 1– 自减运算符,整数值缩小 1通过上面的例子能够让咱们更好的了解C++中的运算符的意义与应用办法。#include <iostream>using namespace std; int main(){ int a = 66; int b = 33; int c; c = a + b; cout << "a + b 的值是 " << c << endl ; c = a - b; cout << "a - b 的值是 " << c << endl ; c = a * b; cout << "a * b 的值是 " << c << endl ; c = a / b; cout << "a / b 的值是 " << c << endl ; c = a % b; cout << "a % b 的值是 " << c << endl ; return 0;}输入: ...

May 14, 2022 · 3 min · jiezi

关于c:C程序设计-06-数组

为了无效解决大批量数据,引入数组(array): 数组是一组有序数据的汇合。数组中各数据的排列是有法则的,下标(subscript)代表数据在数组中的序号。用一个数组名和下标来惟一确定数组中的元素。数组中的每一个元素都属于同一数据类型。不同数据类型的数据不能放入同一个数组。一、一维数组一维数组是数组中最简略的,只需用一个下标就能惟一确定其中的元素。 1. 定义一维数组定义一维数组的个别模式为: 类型说明符 数组名[常量表达式];阐明: 数组定义时须要指定数组中元素的个数,方括号中的常量表达式用来示意元素的个数,即数组的长度。常量表达式能够蕴含常量和符号常量,但不能时变量,C 语言不容许对数组的长度作动静定义。2. 一维数组的初始化在定义数组的同时能够给数组中的元素赋值,称为数组的初始化。 定义数组时对全副元素初始化:int a[5] = {1, 2, 3, 4, 5};只给一部分元素初始化:int a[5] = {1, 2, 3};花括号内只提供了 3 个初始值,示意给前三个元素赋值,零碎主动为前面两个元素赋值为 0。 若对数组初始化时提供的数据个数与数组长度雷同,能够不指定数组长度:int a[] = {1, 2, 3, 4, 5};定义数组时未被初始化的数组,如果是整数型数组,零碎主动将其初始化为 0;如果是字符型数组,初始化为\0;如果是指针型数组,初始化为NULL,即空指针。 3. 援用一维数组应用数组名和下标援用数组中的元素: 数组名[下标];留神:下标是从 0 开始的,只能援用数组元素而不能一次整体调用整个数组全副元素的值。 #include <stdio.h>int main(){ int a[5], i, j, t; for (i = 0; i < 5; i++) scanf("%d", &a[i]); for (i = 0; i < 5; i++) { for (j = 0; j < 5 - i; j++) { if (a[j] > a[j + 1]) { t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; } } } for (i = 0; i < 5; i++) printf("%d\t", a[i]); return 0;}二、二维数组二维数组常称为矩阵(matrix),能够将其直观写成行(row)和列(column)的排列模式。 ...

May 13, 2022 · 2 min · jiezi

关于c:C程序设计-05-循环语句

一、while语句while语句个别模式为: while (表达式) 语句其中表达式为循环条件,语句为循环体。while的特点为:先判断循环条件,后执行循环体。 #include <stdio.h>int main(){ int n, result = 1; scanf("%d", &n); while (n > 1) { result = result * n; n--; } printf("%d", result); return 0;}二、do...while语句do...while语句的个别模式为: do 语句while (表达式)该语句的特点是:先执行循环体,后判断循环条件。 #include <stdio.h>int main(){ int n, result = 1; scanf("%d", &n); do { result = result * n; n--; } while (n > 0); printf("%d", result); return 0;}三、for语句相比while语句和do...while...语句,for语句更加灵便,不仅能够用于循环次数曾经确定的状况,也能够用于循环次数不确定而只给出了循环完结条件的状况。其个别模式为: for (表达式1; 表达式2; 表达式3) 语句其中三个表达式的作用顺次为: 表达式1:设置初始条件,只执行一次,能够为多个变量设置初始值,可省略。表达式2:循环条件,可省略。表达式3:循环的调整,执行完循环体后才执行,可省略。#include <stdio.h>int main(){ int n, result = 1; scanf("%d", &n); for (; n > 0; n--) result = result * n; printf("%d", result); return 0;}C99 规范容许在表达式1中定义变量并初赋值,但定义变量的作用域仅限于for循环内,在循环外不可调用该变量。 ...

May 13, 2022 · 1 min · jiezi

关于c:C程序设计-04-选择语句

C 语言有两种抉择语句: if语句:实现两个分支的抉择构造。switch语句:实现多分支的抉择构造。一、if抉择语句if语句的个别模式: if (表达式) 语句1 [else 语句2]表达式能够是关系表达式、逻辑表达式、数值表达式。if语句能够嵌套: if (表达式) 语句1else if (表达式2) 语句2else if (表达式3) 语句3...else 语句nif语句无论写成几行都是一个整体,属于一个语句。else局部是另一个语句。else语句是可选的,但不能独自应用,必须和if语句配套应用。 二、关系运算符和关系表达式C 语言中用来比拟两个数据的符号称为关系运算符,共 6 个: 优先级较高:< <= > >=优先级较低:== !=关系运算符的优先级低于算数运算符、高于赋值运算符。关系表达式是用关系运算符将两个数值或数值表达式连接起来的式子,如a+b>c。关系表达式的值是一个逻辑值,即“真”或“假”。C 语言中,用“1”示意“真”,用“2”示意“假”。 三、逻辑运算符与逻辑表达式C 语言中有三种逻辑运算符: &&:逻辑与 AND,双目运算符(要求有两个运算对象)\:逻辑或 OR,双目运算符!:逻辑非 NOT,单目运算符(只有一个运算对象)逻辑运算符的优先秩序为: !最高,&&次之,||最小。&&和||低于关系运算符,!高于算术运算符。用逻辑运算符将关系表达式或其余逻辑量连接起来的式子就是逻辑表达式。 四、条件运算符和条件表达式条件运算符由两个符号?和:形成,须要三个操作对象,是 C 语言中惟一的三目运算符。条件表达式的个别模式为: 表达式1 ? 表达式2 : 表达式3其执行过程为:若表达式1为真,则取表达式2的值;否则取表达式3的值。表达式2和表达式3能够是数值表达式、赋值表达式、函数表达式。条件运算符的优先级大于赋值运算符。 五、switch抉择语句if语句只有两个分支可选,多分支抉择应用if语句的嵌套时,程序简短、可读性低。C 语言提供switch语句实现多分支抉择。 switch(表达式){ case 常量1: 语句1 case 常量2: 语句2 ...... case 常量n: 语句n default: 语句n+1}阐明: 其中的表达式值必须是整数类型(包含字符型)。如果表达式的值与case标签中的常量相等,则执行对应的语句;若没有与表达式绝对应的case值,则执行default语句。default语句为可选语句。case语句的程序不影响执行后果,每一个case常量必须互不雷同。若表达式的值与每一个case匹配,则执行完该case前面的语句后,不再进行判断,从此case标签开始执行上面的所有语句。因而通常在case前面加break语句跳出switch。#include <stdio.h>int main(){ char c = getchar(); switch (c) { case 'a': case 'A': printf("A\n"); break; case 'b': case 'B': printf("B\n"); break; } return 0;}Reference: ...

May 13, 2022 · 1 min · jiezi

关于c:C程序设计-03-输入输出

一、C 语句1. C 语句分类C 语句分为以下 5 类: 管制语句 条件语句:if()...else...循环语句:for()...循环语句:while()...循环语句:do...while()完结本次循环语句:continue终止执行 switch 或循环语句:break多分支抉择语句:switch从函数返回语句:return转向语句(结构化程序中根本不必):goto函数调用语句表达式语句:如赋值表达式。空语句:只有一个分号,作为流程的转折点或循环语句的循环体。复合语句:用 {} 把一些语句括起来。2. 赋值语句复合赋值运算a += 3; // a = a+3;x *= y+8; // x = x*(y+8);应用复合赋值运算符,一是能够简化精炼程序,二是能够进步编译效率,生成品质较高的指标代码。 赋值过程中的类型转换浮点型赋值给整型:舍弃小数局部。整型赋值给单、双精度浮点型:数值不变。双精度浮点型赋值给单精度浮点型:只取 6~7 位有效数字,当双精度数值大小超过单精度数值范畴时会出错。占字节多的整型赋值给占字节少的整型或字符型:只会将其低字节局部赋值给新变量,产生失真。失真不属于语法错误,编译系统不会提醒,要留神防止!!!赋值语句与赋值表达式$$赋值语句 = 赋值表达式 + 分号\ ;$$ 赋值表达式时 C 语言的特点之一,区别于其余语言。一个表达式能够蕴含在其余表达式中,赋值表达式也不例外: if((b=a)>0) c=b;// 相当于先把 a 赋值给 b,再判断 b 是否大于 0二、数据的输入输出1. 输入输出基本概念所谓输入输出是以计算机的主机为主体而言的。C 语言自身不提供输入输出函数,这样做能够使编译系统简化、通用性强、可移植性好。C 语言函数库提供一批规范的输入输出函数,以规范的输入输出设施(个别为终端设备)为输入输出对象: putchar输入字符getchar输出字符printf格局输入scanf格局输出puts输入字符串gets输出字符串要在程序文件结尾用预处理指令# include引入无关头文件。# include指令还有一种模式: #include "studio.h"这两种预处理指令的区别是: 应用尖括号时,编译系统从寄存 C 编译系统的子目录中去找要蕴含的文件,称为规范形式。应用双引号时,编译系统当初用户的当前目录中寻找要蕴含的文件,若找不到,再按规范形式找。双引号内能够是文件的具体门路。为提高效率,应用零碎库函数时尽量应用规范形式。2. printf输出函数printf是格式化输入函数,用来向终端(或零碎隐含指定的输出设备)输入若干个任意类型的数据。其个别格局为: printf(格局管制, 输出表列);输出表列是须要输入的数据,能够是常量、变量或表达式。格局管制是用双引号括起来的字符串,称为格局管制字符串或格局字符串,包含两局部信息: 格局申明:由%和格局字符组成,作用是将输入的数据转换为指定格局。一般字符:须要在输入时原样输入的字符。格局字符包含: 格局字符含意d输入有符号的十进制数ld输入长整型lld输入双长整型c输入一个字符s输入字符串f输入实数(单精度、双精度、长双精度)e或E以指数模式输入实数u输入无符号(unsigned)型十进制数g或G以f或e格局中较短的一个格局输入浮点数o按八进制模式输入整数x或X按十六进制模式输入整数局部格局字符应用时能够在格局申明中指定输入数据的域宽,即所占的列数。原输入内容长度小于域宽时,默认在左侧加空格。如: %5d输入数据占 5 列。%m.nf输入数据占 m 列,其中小数为 n 列。原输入数据过长时采取四舍五入的办法解决。党 n 为 0 时,不输入小数和小数点。%-m.nf与%m.nf作用类似,但数据长度小于 m 时,数据向左靠,右端补空格。尽管输入数据的域宽能够管制,但要留神数据的有效性。float型数据只能保障 6 位有效数字,double为 15 位。并不是能输入的数据都是准确的。 ...

May 13, 2022 · 1 min · jiezi

关于c:C程序设计-02-数据类型

一、常量与变量1. 常量整形常量实型常量 十进制小数模式指数模式:\(12.34e3\)(代表\(12.34\times 10^3\))字符常量 一般字符:用单引号示意,单引号里只能有一个字符。字符变量以 ASCII 代码的模式贮存转义字符 转义字符字符值输入后果\\a正告 alert产生视觉或声音信号\\b退格 backspace将光标以后地位后退一个字符\\f换页 form feed将光标地位移到下一页结尾\\n换行将光标地位移到下一行结尾\\r回车 carriage return将光标地位移到本行结尾\\t程度制表符将光标地位移到下一个 Tab 地位\\v垂直制表符将光标地位移到下一个垂直制表符对齐点\\o或 \\oo或 \\ooo(其中o代表一个八进制数字)与该八进制码对应的 ASCII 字符 \\xh[h...](其中 h代表一个十六进制数字)与该十六进制码对应的 ASCII 字符 字符串:用双引号示意符号变量:用 #define 指令,指定用一个符号代表一个常量 #define PI 3.1416符号常量不是变量!符号常量不占用内存,只是作为一个长期符号,代表一个值,在预编译后这个符号就不存在了,一次不能对符号变量从新赋值。为与变量名区别,习惯上符号常量用大写字母示意。 2. 变量变量必须先定义后应用。变量名理论是以一个名字代表的存储地址。编译时,零碎给每一个变量名调配对应的内存地址。从表变量中取值,实际上是通过变量名找到对应的内存地址,从该存储单元中读取数据。 3. 常变量C99 规范容许应用常变量,办法是定义变量时在后面加一个 const,该变量存在期间其值不能扭转。 常变量与常量: 常变量具备变量的根本属性:有类型,占存储单元,只是不容许扭转值。常变量是有名字的不变量,常量是无名字的不变量。常变量与符号变量: 符号变量是预编译指令,它只是用符号常量代表一个字符串,在预编译时仅进行字符替换,编译后符号常量就不存在了(被值代替),符号常量的名字不调配存储单元。串并联占用存储单元,有变量值,只是不能扭转。从应用上看,常变量具备符号变量的长处,而且应用更不便,有常变量时能够不应用符号常量。但有些编译系统还未实现 C99 的性能,不能应用常变量。4. 标识符用来对常量名、函数、数组、类型等命名的无效字符序列统称为标识符(identifier)。标识符就是一个对象的名字。 C 语言规定标识符只能由字母、下划线、数字组成,且第一个字符必须为字母。大小写字母是两个不同的字符。习惯上变量名应用小写字母。 二、数据类型类型是指对数据调配存储单元的安顿,包含存储单元的长度(占多少字节)一级数据的存储形式。不同的类型调配不同的长度和贮存模式。计算机进行的计算不是形象的理论值的计算,而是用工程的办法实现的计算,在许多状况下只能失去近似的后果。C99 容许应用的类型包含:根本类型和枚举类型的变量都是数值,统称为算术类型(arithmetic type)。算术类型和指针类型的变量都是用数字来示意的,统称为纯量类型(scalar type)。枚举类型是程序中用户自定义的整数类型。数组类型和构造体类型统称为组合类型(aggregate type)。共用体类型不属于组合类型,因为在同一时间内只有一个成员具备值。 1. 整形C 规范没有规定各种类型数据占用的存储单元长度,这是由编译系统自行决定的。如 Turbo C 2.0 为每个 int 调配 2 个字节(16 个二进位),而 Visual C++ 调配 4 个字节(32 个二进位)。C 规范只要求 long 型数据长度不短于 int 型,short 型不长于 int 型,long long 型最长。能够应用 sizeof(int) 来查看类型或变量的长度。将一个程序移植到另一个零碎时,要留神因为编译系统的不同引起的数据溢出。存储单元存储整数的办法是:应用整数的补码(complement)。 ...

May 13, 2022 · 2 min · jiezi

关于c:Linux网络开发必学教程18网络通讯框架的完善

问题:如何扩大之前的通信框架,使其反对 UDP 通信,进而成为一个欠缺的网络通讯框架?UDP 通信扩大 UDP 通信实体概要设计每个 UDP Point 位置对等(因为不用被动发动连贯),可通过 ip 地址和 port 号进行通信UDP Point 数据收发单位为: Message 或 Byte在承受口设计上,与 TcpClient 保持一致(框架接口一致性)指标:封装原生 socket 细节,关注 UDP 通信逻辑 UDP 通信实体接口设计typedef void UdpPoint;UdpPoint *UdpPoint_New(int port);UdpPoint *UdpPoint_From(int fd);void UdpPoint_Del(UdpPoint *point);int UdpPoint_SendMsg(UdpPoint *point, Message *msg, const char *remote, int port);int UdpPoint_SendRaw(UdpPoint *point, const char *buf, int length, const char *remote, int port);Message *UdpPoint_RecvMsg(UdpPoint *point, char *remote, int *port);int UdpPoint_RecvRaw((UdpPoint *point, const char *buf, int length, char *remote, int *port);int UdpPoint_Available(UdpPoint *point);void UdpPoint_SetData(UdpPoint *point, void *data);void *UdpPoint_GetData(UdpPoint *point);int UdpPoint_SetOpt(UdpPoint *point, int levle, int optname, const void *optval, unsigned int optlen);int UdpPoint_GetOpt(UdpPoint *point, int levle, int optname, void *optval, unsigned int *optlen);要害代码实现因为 UDP 是以数据报形式进行通信(非数据流形式,报文间有显著边界)因而,不能间接通过 MParser_ReadFd(...) 解析出音讯必须先将报文残缺接管到内存中,再进行从内存中解析出音讯即通过 MParser_ReadMeme(...) 间接实现音讯解析对于上述的补充UDP 套接字的收发报文要用 sendto 和 recvfrom(能够类比 TCP 套接字的 connect 和 accept),参数外面会标识要发往的对端,或者要接管的对端的 IP 地址和端口; ...

May 12, 2022 · 5 min · jiezi

关于c++:Electron-插件开发实践

前言晚期跨平台桌面利用开发大多采纳 Qt 和 C++,受语言学习老本开发效率影响,越来越多的人将眼光转向了 Electron。Electron 是以 Nodejs 和 Chromium 为内核的跨平台开发框架。 Electron 基于 Web 技术开发桌面利用,Web 技术在软件开发畛域利用十分宽泛,生态较为成熟,学习老本较低、开发效率高。然而 Web 在解决多线程、并发场景时显得顾此失彼,Electron 底层有 Nodejs 反对,Nodejs 的插件模块具备调用 C++ 的能力,C++ 非常适合解决高并发、音视频等简单业务,补救了 Web 的性能问题。本文就 js 和 C++ 混合编程在 Electron 桌面程序中的利用进行介绍。 Nodejs 中应用 C++,有以下几种形式: 将 C++ 程序作为独立子过程应用。通过 node-ffi 形式调用。Nodejs 扩大,将 C++ 代码编译为 Nodejs 模块,本文次要针对这种形式进行介绍。C++ 扩大C++ 扩大简介Nodejs 自身采纳 C++ 编写,所以咱们能够应用 C++ 编写的本人的 Nodejs 模块,能够像 Nodejs 原生模块一样应用。C++ 扩大格局为 .node,其本质为动态链接库,相当于 Windows 下 .dll。C++ 扩大作为动态链接库,通过 dlopen 在 Nodejs 中加载。 C++ 扩大架构图: ...

May 12, 2022 · 3 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第12章-文件-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.以下语句的输入后果是( )。 printf("%d,%d,%d", NULL, '\0', EOF);A.0,0,1 B.0,0,-1 C. NULL, ,EOF D. 1,0, EOF 答:B 解析: NULL等于0'\0'也是等于0EOF等于-1 2.缓冲文件系统的文件缓冲区位于( )。 A.磁盘缓冲区中 B.磁盘文件中 C.内存数据区中 D.程序文件中 答:C 解析: 文件缓冲区是用以临时寄存读写期间的文件数据而在内存区预留的肯定空间 3.定义 FILE *fp; 则文件指针 fp 指向的是( )。 A.文件在磁盘上的读写地位 B.文件在缓冲区上的读写地位 C.整个磁盘文件 D.文件类型构造 答:D 解析: 语句 FILE *fp; ,定义了一个 FILE 构造指针, FILE 是 C 语言为了具体实现对文件的操作而定义的一个蕴含文件操作相干信息的构造类型。 4.若以 “a+” 形式关上一个已存在的文件, 则以下叙述正确的是( )。 A.文件关上时,原有文件内容不被删除,地位指针移到文件开端,可执行增加和读操作 B. 文件关上时,原有文件内容不被删除,地位指针移到文件结尾,可执行重写和读操作 C.文件关上时,原有文件内容被删除,只可执行写操作 D.以上各种说法都不正确 答:A 解析: "a+" 的关上模式,关上文本文件进行读/写/追加。 5.以下可作为函数 fopen() 中第一个参数的正确格局是( )。 ...

May 12, 2022 · 6 min · jiezi

关于c++:记录平时遇到的一些注意点

WM_COPYDATA留神点typedef struct tagCOPYDATASTRUCT { ULONG_PTR dwData; DWORD cbData; PVOID lpData;} COPYDATASTRUCT, *PCOPYDATASTRUCT;/********正文:1、dwData.为自定义数据;2、cbData.即lpData指向的数据的长度,要是这个变量的值设置谬误,就会导致WM_COPYDATA传输/*数据失败;3、lpData.传输的数据.最好应用根底数据类型;********/应用WM_COPYDATA时要用SendMessage而不能应用PostMessage,因为SendMessage是阻塞的,会期待音讯响应窗体解决音讯结束后再返回;而PostMessage是异步的,这样就可能会导致当音讯响应窗体接管到WM_COPYDATA的时候,COPYDATASTRUCT对象曾经被析构了,导致拜访数据产生异样; 因为应用SendMessage,所以不应该在WM_COPYDATA中解决数据,能够在音讯响应窗体的WM_COPYDATA中先把COPYDATASTRUCT对象中的数据复制进去,通过自定义音讯发送到音讯响应窗体,而后立刻返回,来缩小父过程的阻塞工夫。这样就把解决数据的代 case WM_COPYDATA: { COPYDATASTRUCT* data = (COPYDATASTRUCT*)lParam; // TODO: 解决pCopyData->lpData指向的数据 } break;

May 12, 2022 · 1 min · jiezi

关于c:Redis-源码解读sds

“实在”的 sdshdr 构造在 《Redis 设计与实现》中,提到 sds 的实现构造 sdshdr 是这样的: struct sdshdr { // 记录buf数组已应用字节的数量 // 等于SDS所保留字符串的长度 int len; // 记录buf数组中未应用的字节数 int free; // 字节数组,用于保留字符串 char buf[];};这可能是 Redis 以前的版本是这样的,笔者查看的源码是 7.0 在 Redis 7.0 中,sdshdr (在 sds.h 中)构造是这样的: /* Note: sdshdr5 is never used, we just access the flags byte directly. * However is here to document the layout of type 5 SDS strings. */struct __attribute__ ((__packed__)) sdshdr5 { unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ char buf[];};struct __attribute__ ((__packed__)) sdshdr8 { uint8_t len; /* used */ uint8_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ char buf[];};struct __attribute__ ((__packed__)) sdshdr16 { uint16_t len; /* used */ uint16_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ char buf[];};struct __attribute__ ((__packed__)) sdshdr32 { uint32_t len; /* used */ uint32_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ char buf[];};struct __attribute__ ((__packed__)) sdshdr64 { uint64_t len; /* used */ uint64_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ char buf[];};依据字符串长度的不同,用来寄存它的 sdshdr 类型也是不同的 ...

May 12, 2022 · 12 min · jiezi

关于c++:c-volatile的一些理解

含意在这里,咱们将理解 C++ 中 volatile 限定符的含意。volatile 限定符在咱们申明变量时利用到它。它用于通知编译器,该值可能随时更改。这些是 volatile 的一些属性。 volatile 关键字不能删除内存调配。 它不能缓存寄存器中的变量。该值不能按调配程序更改。让咱们看看如何应用 volatile 关键字。volatile int a;int volatile a;这里这两个申明是正确的。像其余数据类型一样,咱们能够应用 volatile 指针、构造体、联合体等。 volatile 构造体和联合体自身能够是 volatile,它们的成员变量也能够是 volatile 类型。 volatile 用在不同的中央。对于内存映射的外设寄存器,一些全局变量,由一些其余函数或中断服务程序拜访,或者在一些多线程应用程序中,能够应用 volatile。例子 int main (){ int value; value++;}int main (){ volatile int value; value++;}有两个代码块。在第一个块中,不存在 volatile 关键字。因而对于第一种状况,变量将从内存复制到 CPU 寄存器,而后执行操作。在第二种状况下,存在volatile,所以在这种状况下,变量不会从内存复制到寄存器。 思考上面的代码int some_int = 100;while(some_int == 100){ //your code}当这个程序被编译时,编译器可能会优化这个代码,如果它发现程序素来没有尝试扭转some_int的值,所以它可能会试图通过将循环从更改为等价的货色来优化while循环执行可能很快(因为循环中的条件仿佛总是一样的)。(如果编译器不对其进行优化,那么它必须在每次迭代中获取 100 的值并将其与 100 进行比拟,这显然有点慢。)while(some_int == 100) while(true) while true some_int 然而,有时,(程序的某些局部的)优化可能是不可取的,因为可能是其他人正在some_int从程序内部更改编译器不晓得的值,因为它看不到它;但这就是你设计它的形式。在这种状况下,编译器的优化不会产生预期的后果! 因而,为了确保取得所需的后果,您须要以某种形式阻止编译器优化while循环。这就是volatile关键字发挥作用的中央。你须要做的就是这个, volatile int some_int = 100; //note the 'volatile' qualifier now!换句话说,我将解释如下: ...

May 11, 2022 · 1 min · jiezi

关于c++:对于单例模式双重检查的一些理解

一、首先从形而上角度看,我认为很多文章都在把两个指标(我称为单例指标和平安指标)混在一起谈。留神这是两个指标,1是是否单例;2是在多线程下是否牢靠。双重锁只是保障了指标1,与指标2无关。其实你想一下,1个if解决不了指标2,2个if就行了?那3个if岂不成果更好? 二、具体来看。有人说1if为效率(防止都申请锁)【我认为不精确】;2if为防止反复new。(1)首先,双重查看锁不肯定非用到单例问题上。用到别处(2中也未必是做new工作),可能1,2都为效率。(2)就单例问题而言,1if原本就是单例模式要求的,谈不上什么效率,2if才是减少的,能防止反复new,从而在多线程环境下没毁坏“指标1”。(3)至于指标2,问题出在p==null为假时。p不空,不代表你马上应用就没问题(因为编译重排、硬件等各种起因,对象还没有初始化好就被你看到了) 。这一点对1if,2if都实用,所以你就是加3个if,或者加volatile,也还是未必能保障你看到的、不空的p能用(前提是p是刚new的,只有是new的问题,那影响因素太多了:单例外部还有其余数据成员是否筹备好、编译优化、OS、多CPU调度、CPU外部。。。)(4)所以我感觉双重锁,只有是用在单例问题上,从根本上看是有平安问题的,只是在你某个具体平台上好使而已。![3Y(LCJ2]T`SQN76BC29K8}U.png](/img/bVcZFTm)

May 11, 2022 · 1 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第11章-指针进阶-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.上面程序段的运行后果是( )。 int x[5] = {2, 4, 6, 8, 10}, *p, **pp;p = x;pp = &p;printf("%d", *(p++));printf("%d\n", **pp);A.4 4 B.2 4 C.2 2 D.4 6 答:B 解析: 题目中先定义了 int 类型的数组 x,又定义两个指针。 而后 p = x,示意将 x 的基地址赋值给 p,所以 p 指向数组中第一个元素。 第一次打印 *(p++),获取 p 指向的元素,打印 2, 而后指针地位向后挪动一个地位。 因为 pp = &p,示意将 p 的地址赋值给 pp,所以 pp 指向 p,p 通过上次打印时的 ++,曾经向后肯定一个,所以第二个打印 **pp,打印的就是 4。 2.对于以下变量定义,正确的赋值是( )。 int *p[3], a[3];A. p=a B. *p=a[0] C. p=&a[0] ...

May 11, 2022 · 10 min · jiezi

关于c#:微软是如何解决-PC-端程序多开问题的

不久前,在尝试应用 C# 解决 PC 端程序多开问题时,发现 VB.NET 的 WinForm 程序提供了一个非常简单的实现形式: 无需任何代码,只需打个勾。 我对它的实现原理很感兴趣,因而对其进行了探索。明天就通过这篇文章为大家介绍微软是如何解决 PC 端程序多开问题的,以及如何在 C# 中实现雷同性能。   原理1——WindowsFormsApplicationBase基类编译一个 VB.NET 的 WinForm 程序,反编译源代码,找到入口Main办法: 该入口类MyApplication继承自WindowsFormsApplicationBase基类,理论执行的基类的Run办法。Run办法外部应用IsSingleInstance属性判断是否启用单个实例应用程序: 而IsSingleInstance属性在入口类的构造函数中被赋值: 实现1通过援用 NuGet 包 Microsoft.VisualBasic,咱们在 C# 中同样能够继承WindowsFormsApplicationBase基类,为IsSingleInstance属性赋值,实现单个实例应用程序: class Program : WindowsFormsApplicationBase{ public Program() { IsSingleInstance = true; } protected override void OnCreateMainForm() { MainForm = new Form1(); } [STAThread] static void Main(string[] args) { new Program().Run(args); }}尽管上述实现非常简单,然而仅实用于 WinForm 应用程序,而且还须要援用Microsoft.VisualBasic类库。 因而,咱们决定深挖一下,看看具体是如何实现的。 原理2-命名管道通过查看WindowsFormsApplicationBase的Run办法实现(代码有删减): Public Sub Run(commandLine As String()) If Not IsSingleInstance Then DoApplicationModel() Else ' This is a Single-Instance application Dim pipeServer As NamedPipeServerStream = Nothing If TryCreatePipeServer(ApplicationInstanceID, pipeServer) Then ' --- This is the first instance of a single-instance application to run. Using pipeServer WaitForClientConnectionsAsync(pipeServer, AddressOf OnStartupNextInstanceMarshallingAdaptor, cancellationToken:=tokenSource.Token) DoApplicationModel() End Using Else Dim awaitable = SendSecondInstanceArgsAsync(ApplicationInstanceID, commandLine, cancellationToken:=tokenSource.Token).ConfigureAwait(False) awaitable.GetAwaiter().GetResult() End If End If 'Single-Instance applicationEnd Sub能够剖析出,微软解决 PC 端程序多开问题的外部实现原理如下: ...

May 11, 2022 · 2 min · jiezi

关于c:Linux网络开发必学教程17深入-UDP-数据收发-下

问题: UDP 是否还有其余一对多的数据发送形式?UDP 通信中的多播多播是向特定组中的所有主机传输数据的办法,多播也称之为组播多播数据传输的特点:多播发送者针对特定的多播组,只发送 1 次数据,组内主机均可接管到数据主机退出特定组,即可接管该组中的多播数据多播组可在 IP 地址范畴内任意增加关键问题:如何收发多播数据多播组是一个 D 类地址 (224.0.0.0 - 239.255.255.255)"退出多播组"可了解为 UDP 网络程序进行的申请如:申请接管发往 239.234.111.222 的多播数据即:设置属性 (IPPROTO_IP, IP_ADD_MEMBERSHP)发送多播数据的形式,与发送一般 UDP 数据的形式雷同准备操作:设置属性,如:(IPPROTO_IP, IP_MULTICAST_TTL)注意事项退出同一个多播组的主机不肯定在同一个网络中因而,必须设置多播数据的最多转发次数(TTL)TTL(即:Time To Live) 是决定数据传输间隔的次要因素TTL 用整数示意,并且每通过 1 个路由就缩小 1当 TTL 变为 0 时,数据无奈持续传递,只能销毁多播程序设计:发送端IP_MULTCAST_TTL: 用于设置多播数据的”最远传输间隔“,默认 1IP_MULTICAST_IF: 用于设置多播数据从哪一个网络接口(网卡)发送进来,默认:0.0.0.0默认 0.0.0.0 状况下操作系统会自主抉择应用哪个网络接口,但在[多网卡主机]的[理论工程利用]中,最好手工指定!!IP_MULTCAST_LOOP: 用于设置多播数据是否发送回本机,默认1 (1,发送回本机)remote.sin_family = AF_INET;remote.sin_addr.s_addr = inet_addr("224.1.1.168");remote.sin_port = htons(8888);setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));do { len = sizeof(remote); r = sendto(sock, buf, strlen(buf), 0, (struct sockaddr*)&remote, len); sleep(1);}while(r > 0);多播程序设计:接收端IP_ADD_MEMBRESHIP: 用于申请加入多播组,参数为:多播组和本机地址struct ip_mreq { // group address struct in_addr inmr_multiaddr; // local host address struct in_addr imr_interface} ...

May 10, 2022 · 3 min · jiezi

关于c:哥德巴赫猜想的验证

首先得申明一句,自己文学业余出身,数学的确不好,能够说齐全零根底,因而这篇博客的代码花了靠近一下午的工夫(并不是代码有多难,而是本人数学太差,所以得查半天材料钻研) 什么是哥德巴赫猜想 (以下内容来自百度百科) 哥德巴赫1742年在给欧拉的信中提出了以下猜测:任一大于2的整数都可写成三个质数之和 [1] 。然而哥德巴赫本人无奈证实它,于是就写信求教赫赫有名的大数学家欧拉帮忙证实,然而始终到死,欧拉也无奈证实。 [2] 因现今数学界曾经不应用“1也是素数”这个约定,原初猜测的古代陈说为:任一大于5的整数都可写成三个质数之和。(n>5:当n为偶数,n=2+(n-2),n-2也是偶数,能够合成为两个质数的和;当n为奇数,n=3+(n-3),n-3也是偶数,能够合成为两个质数的和)欧拉在回信中也提出另一等价版本,即任一大于2的偶数都可写成两个质数之和。今日常见的猜测陈说为欧拉的版本。把命题"任一充沛大的偶数都能够示意成为一个素因子个数不超过a个的数与另一个素因子不超过b个的数之和"记作"a+b"。1966年陈景润证实了"1+2"成立,即"任一充沛大的偶数都能够示意成二个素数的和,或是一个素数和一个半素数的和"。今日常见的猜测陈说为欧拉的版本,即任一大于2的偶数都可写成两个素数之和,亦称为“强哥德巴赫猜想”或“对于偶数的哥德巴赫猜想”。从对于偶数的哥德巴赫猜想,可推出:任何一个大于7的奇数都能被示意成三个奇质数的和。后者称为“弱哥德巴赫猜想”或“对于奇数的哥德巴赫猜想”。若对于偶数的哥德巴赫猜想是对的,则对于奇数的哥德巴赫猜想也会是对的。2013年5月,巴黎低等师范学院研究员哈洛德·贺欧夫各特发表了两篇论文,发表彻底证实了该猜测。 **说了这么多,咱们总结一句话,那就是:咱们要在2000以内的不小于4的正偶数都可能合成为两个素数之和(即验证歌德巴赫猜想对2000以内的正偶数成立)** 思路既然晓得题目要求,咱们接下来就要设计算法了首先,咱们本人定义一个函数,咱们假如函数名字叫fun,将素数过滤出来 int fun(int n){ int i; if(n==2) return 1; /*n是2,返回1*/ if(n%2==0) return 0; /*n是偶数,不是素数,返回0*/ for(i=3; i<=sqrt(n); i+=2) if(n%i==0) return 0; /*n是奇数,不是素数,返回0*/ return 1; /*n是除2以外的素数返回1*/}有了素数的判断,接下来,咱们就能够设计主函数了。因为是用户输出,所以为了避免“淘气的用户乱输出”导致报错,所以咱们思考下空值的状况,以及非偶数的状况,另外,通过退出ok来管制输入。残缺代码如下; #include<math.h>#include<stdio.h>int fun(int n){ int i; if(n==2) return 1; /*n是2,返回1*/ if(n%2==0) return 0; /*n是偶数,不是素数,返回0*/ for(i=3; i<=sqrt(n); i+=2) if(n%i==0) return 0; /*n是奇数,不是素数,返回0*/ return 1; /*n是除2以外的素数返回1*/}int main(){ int n, i, ok; while(scanf("%d",&n)!=EOF) { ok=0; /*进入循环前先置标记位*/ for(i=2; i<=n/2; i++) { if( fun(i) ) if( fun(n-i) ) { printf("%d %d\n", i, n-i); /*i和n-i都是素数,则打印*/ ok=1; } if(i!=2) i++; if(ok) break; /*已打印出所须要的输入后果,跳出循环*/ } } return 0;

May 10, 2022 · 1 min · jiezi

关于c++:祖师级技术人的哲理认知热爱恒心

在“技术名人堂”专辑中,C++之父Bjarne Stroustrup首先带来了他和C++的往事。在他看来,本人长期对历史、哲学抱持的宽泛趣味,对推动这一语言的倒退具备重要意义。 C#和TypeScript之父Anders Hejlsberg也带来他对开发者的坦诚倡议。对于他来说,没有什么比“酷爱”更能诠释取得极大胜利的起因。“只有当创立出一门编程语言并实现编译器和工具,你能力成为本人世界的客人。”  在MySQL之父Michael “Monty” Widenius看来,“一个十分杰出的程序员能够抵五个个别的程序员。对于所有中国开发者,我只想说,请保持你的工作,你曾经做得十分好了,肯定不要进行写代码。” 细品祖师级技术专家给到开发者的倡议,他们想要表白的别离在于:思考力、精神力,以及持久力。 1.要关上认知,不能只把本人当成“码农”,而应以迷信思维自立,融汇事实世界中各类问题的思考; 2.灵感和能源的根源是“酷爱,要为“代码”赋予爱的灵魂,能力成为它的客人; 3.相较于极少数的少年成才,绝大部分人终会大器晚成,只有不忘初心,坚持不懈。

May 10, 2022 · 1 min · jiezi

关于c++:CC气象数据中心实战手把手教你做工业级项目源码齐全

C/C++气象数据中心实战,手把手教你做工业级我的项目(源码齐全)超清原画 残缺无密 资料齐全 获取ZY:百度网盘一个Java注解@Recover搞定俊俏的循环重试代码 使用背景在实际我的项目中其中一部分逻辑可能会因为调用了内部服务或者等待锁等情况下出现不可预料的异样,在这个时候咱们可能需要对调用这部分逻辑进行重试,代码外面次要就是使用for循环写一大坨重试的逻辑,各种硬编码,各种辣眼睛的补丁。 特地是针对重试的逻辑,到处都有。所以我决定用一个重试组件spring-retry优化一波。它的出现,解决掉这部分俊俏的代码! 2开始上代码首先引入依赖: org.springframework.retryspring-retry1.3.2复制代码因为该组件是依赖于 AOP 给你的,所以还需要引入这个依赖(如果你其余 jar 包中引用过了,当然也就不需要再次引用了): org.springframework.bootspring-boot-starter-aop2.6.1复制代码开启重试:@SpringBootApplication@EnableRetrypublic class ApplicationStarter { public static void main(String[] args) { SpringApplication.run(ApplicationStarter.class); }}复制代码Controller层@RestControllerpublic class TestController {@Autowiredprivate IRecursiveCallService recursiveCallService; @GetMapping("test2")public Object test2() { return recursiveCallService.testService();}}复制代码Service层public interface IRecursiveCallService { /** * 测试service * * @return */List testService();}复制代码Service层具体实现@Servicepublic class RecursiveCallServiceImpl implements IRecursiveCallService { @Override@Retryable(recover = "testService3")public List testService() { System.out.println("到此一游!"); System.out.println(1 / 0); return null;}@Recoverpublic List testService1() { System.out.println("谬误的返回"); return Collections.singletonList("S");}@Recoverpublic List testService2(String i) { System.out.println("正确的返回"); return Collections.singletonList(1);}@Recoverpublic List testService3() { System.out.println("正确的返回2"); return Collections.singletonList(2);}} ...

May 10, 2022 · 1 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第10章-函数与程序结构-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.对于以下递归函数,调用f(4),其返回值为( )。 int f(int n){ if (n) return f(n - 1) + n; else return n;}A.10 B.4 C.0 D.以上均不是 答:A 解析: 递归函数的调用。 第一次调用函数 f,参数为 4,执行 if 语句,返回 f(3)+4, 第二次调用函数 f,参数为 3,执行 if 语句,返回 f(2)+3, 第三次调用函数 f,参数为 2,执行 if 语句,返回 f(1)+2, 第四次调用函数 f,参数为 1,执行 if 语句,返回 f(0)+1, 第五次调用函数 f,参数为 0,执行 else 语句,返回 0。 而后再一层一层将return 的后果返回。最终失去的就是 0 +1+2+3+4 = 10。 2.执行下列程序段后,变量 i 的值为( )。 #define MA(x, y) (x*y)i=5;i=MA(i, i+1)-7;A.30 ...

May 10, 2022 · 10 min · jiezi

关于c:Linux网络开发必学教程16深入-UDP-数据收发-上

问题:如何进行一对多的 UDP 数据发送?UDP 通信中的播送播送是向同一网络中的所有主机传输数据的办法播送类型 间接播送:IP 地址中除网络地址外,其余主机地址均设置为 1本地播送:无需晓得网络,应用 255.255.255.255 作为 IP 地址应用区别 本地播送数据不通过路由器寻址,间接发送到本地主机本地播送利用案例:DHCPDHCP (动静主机配置协定)是一个局域网的网络协议(基于 UDP 协定)本地主机可主动取得服务器调配的 IP 地址和子网掩码DHCP 采纳 客户端 / 服务器 模型,地址的动态分配由网络主机驱动工作形式:DHCP 服务器接管到来自网络主机的地址申请时,会向网络主机发送相干的地址配置信息,以实现网络主机地址信息的动静配置 准备筹备 socket 属性设置(option)socket 的实质是对本机网络资源的一种标识socket 自身有各种属性(不同的连贯,属性可能不同)通过 setsockopt() / getsockopt() 可存取指定 socket 的属性值socket 属性的扭转可造成 socket 数据收发行为的扭转TCP 编程中设计的用法 setsockopt() / getsockopt() 属性存取函数#include <sys/types.h>#include <sys/socket.h>int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);若无谬误产生返回 0; 否则返回 SOCKET_ERROR 谬误。 ...

May 9, 2022 · 2 min · jiezi

关于c:Linux网络开发必学教程15UDP-数据收发实战

问题:如何应用 UDP 进行数据收发?再论 UDP 协定UDP 是无连贯的(不牢靠的,无应答音讯,数据包无序号标识)UDP 是面向数据包的,对应用层数据既不合并也不拆分(保留数据包边界)UDP 没有拥塞管制,网络呈现的拥塞不会使源主机的发送速率升高UDP 反对一对一,一对多,多对一和多对多的交互通信UDP 音讯头开销小,只有 8 个字节(TCP 音讯头共 20 个字节) UDP 和 IP 的区别UDP 是建设于 IP 之上的数据传输协定IP 负责将 UDP 数据包从源主机传输到指标主机UDP 则将应用层数据投递到指标 socket (端口号)UDP 简直残缺 “继承” 了 IP 传输的个性通信两端无交互,无流控,无超时重发,不具备可靠性UDP 收发数据#include "sys/socket.h"ssize_t send(int sock, // socket 文件描述符 void *buf, // 须要发送的数据 size_t nbytes, // 须要发送的数据量 int flags, // 发送选项 struct sockaddr *to, // 接管地址信息 socklen_t addrlen); // to 参数长度ssize_t recvfrom(int sock, // socket 文件描述符 void *buf, // 保留接收数据的地址 size_t nbytes, // 可接管的最大数据量 int flags, // 接管选项 struct sockaddr *from, // 接管地址信息 socklen_t *addrlen); // 指向保留 from 参数长度的变量地址UDP 编程模式 ...

May 9, 2022 · 2 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第9章-结构-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.以下定义构造变量的语句中,谬误的是( )。 A. struct student { int num; char name[ 20];} s; B. struct { int num; char name[ 20] ;} s; C. struct student { int num; char name[ 20] ;} ; student s; D. struct student { int num; char name [ 20] ; } ; struct student s; 答:C 解析: 构造变量名能够在定义构造后独自定义。也能够跟在构造后间接定义,间接写构造变量名即可。 2.如果构造变量 s 中的生日是 “1984 年11月11日”,下列对其生日的正确赋值是( )。 struct student{ int no; char name[20]; char sex; struct { int year; int month; int day; }birth;}s;A. year= 1984; month=11; day=11; ...

May 9, 2022 · 7 min · jiezi

关于c:Linux网络开发必学教程14数据收发的扩展用法-下

MSG_PEEK (数据窥探)应用 MSG_PEEK 选项可能获取接收缓冲区数据的拷贝recv() 专用选项,可用于数据预接管指定 MSG_PEEK 选项时,不会清空缓冲区可用于获取接收缓冲区种的数据量(字节数)当接收缓冲区中没有数据时,MSG_PEEK 也会导致线程阻塞 上面的代码输入什么?为什么?static char c_temp[1024 * 2] = {0};char buf[32] = {0];sleep(1);r = recv(client, c_temp, sizeof(c_temp), MSG_PEEK);c_temp[r] = 0;printf("r = %d\n", r);printf("c_temp = %s\n", c_temp);r = recv(client, buf, sizeof(buf), 0);buf[r] = 0;printf("r = %d\n", r);printf("buf = %s\n", buf);client.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(){ int sock = {0}; struct sockaddr_in addr = {0}; int len = 0; char *test = "Delpin-Tang"; sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("socket error\n"); return -1; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(8888); if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { printf("connect error\n"); return -1; } printf("connect success\n"); len = send(sock, test, strlen(test), 0); getchar(); close(sock); return 0;}server.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(){ int server = 0; struct sockaddr_in saddr = {0}; int client = 0; struct sockaddr_in caddr = {0}; socklen_t asize = 0; int len = 0; char buf[32] = {0}; int r = 0; server = socket(PF_INET, SOCK_STREAM, 0); if (server == -1) { printf("server socket error\n"); return -1; } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(8888); if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { printf("server bind error\n"); return -1; } if (listen(server, 1) == -1) { printf("server listen error\n"); return -1; } printf("server start success\n"); while (1) { asize = sizeof(caddr); client = accept(server, (struct sockaddr*)&caddr, &asize); if (client == -1) { printf("client accept error"); return -1; } printf("client: %d\n", client); do { r = recv(client, buf, sizeof(buf), MSG_PEEK); if (r > 0) { buf[r] = 0; printf("r = %d\n", r); printf("data: %s\n", buf); r = recv(client, buf, sizeof(buf), 0); buf[r] = 0; printf("r = %d\n", r); printf("data: %s\n", buf); } else { printf("no data in receive buf\n"); // 留神这里!(如果未打印示意阻塞) } }while (r > 0); close(client); } close(server); return 0;}输入:server start successclient: 4r = 11data: Delpin-Tangr = 11data: Delpin-TangMSG_DONTWAIT (立刻收发模式)数据收发时不阻塞,立刻返回sned() : 如果无奈将数据送入发送缓冲区,那么间接返回谬误 (比方:发送缓冲器 1024 字节大小,欲想发送 2048 字节时)recv() : 如果接收缓冲区中没有数据,那么间接返回谬误send() / recv() 返回值:-1, 谬误产生0, 对端调用 close 敞开n, 发送 / 接管 的数据量上面的代码输入什么?为什么?printf("connect success\n");sleep(1);test = "D.T.software";send(sock, test, strlen(test), 0);sleep(2);test = "quit";send(sock, test, strlen(test), 0); ...

May 8, 2022 · 7 min · jiezi

关于c:数据与C

变量与常量为了可能更加不便的应用数据,程序员会将在程序运行期间会扭转或赋值的数据应用变量进行保留。常量则是事后定义好,在程序运行期间不会扭转的固定值 变量和常量就如同是一个盒子,能够用来装货色(数据)。在计算机中,数据是寄存在内存中的,存放数据的内存空间程序员为了不便当前的应用,都会起一个好记的名字。这个名称也由字母、数字和下划线组成,必须要以字母和下划线结尾。因为C语言是对大小写敏感的,所以大写字母和小写字母是不同的,也就是变量名abc和Abc是两个不同的变量。 数据类型不同的数据类型有不同的含意,有的数据类型示意整数,有的示意字符,有的示意浮点数。常量能够是任何的数据类型,通过常量的值辨认(100是整数,123.45是浮点数)。而变量则须要指定数据类型。在C语言中有很多种数据类型,从最后的K&R给出的7个数据类型关键字,再到C90增加的2个新的关键字,到最初的C99增加的3个关键字 最后K&R给出的关键字C90规范增加的关键字C99规范增加的关键字intsigned_Boollongvoid_Complexshort _Imaginaryunsigned char float double int、long、short、unsigned和C90新增加的signed关键字用于示意整数类型,unsigned示意无符号数,signed则示意有符号数,整数类型的例子:unsigned short int 和 long long int char关键字用于寄存字母和其余字符(如:$、%等),char也能够用来示意较小的整数 float、double和long double示意浮点数 _Bool示意布尔类型(true或false) _Complex和_Imaginary别离示意复数和虚数 存储大小不同的数据类型能够寄存的数据大小是不同的,可能寄存的数据越多,值越大。 数据类型存储大小char1字节int2或4字节()short2字节long4字节float4字节double8字节long double16字节在C语言中,能够通过sizeof运算符查看数据类型存储字节的大小 #include<stdio.h>int main(){ printf("char 的存储大小: %d\n", sizeof(char)); printf("short 的存储大小: %d\n", sizeof(short)); printf("int 的存储大小: %d\n", sizeof(int)); printf("long 的存储大小: %d\n", sizeof(long)); printf("float 的存储大小: %d\n", sizeof(float)); printf("double 的存储大小: %d\n", sizeof(double)); printf("long double 的存储大小: %d\n", sizeof(long double)); return 0;}运行后果: 这里应用到的printf()函数,前面会进行解说,目前只须要晓得printf()是用来打印内容到屏幕上的就能够了。 变量的定义C语言提供了很多种数据类型,在定义变量时须要指定变量的数据类型,如整数能够应用int类型,小数能够应用float类型等,上面将开始介绍如何定义变量。 定义变量定义变量的语法:数据类型 变量名; 举个例子,上面的程序用于计算两个整数的和 #include<stdio.h>int main(){ int num1; //定义一个变量num1,用于寄存第一个数 int num2; //定义一个变量num2,用于寄存第二个数 int sum; //定义一个变量sum,用于寄存两个数的和 num1 = 100; //将整数100赋值给变量num1 num2 = 200; sum = num1 + num2; //计算num1与num2相加,并将值赋值给sum变量 printf("num1 + num2 = %d\n", sum); // 将sum的值打印到屏幕 return 0;}运行后果: ...

May 8, 2022 · 3 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第8章-指针-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.下列语句定义 px 为指向 int 类型变量的指针,正确的是( )。 A. int x, *px=x; B.int x, *px=&x;C. int *px=&x, x;D.int x, px=x; 答:B 解析:先定义变量,再定义指针,定义指针应用 *。为指针赋值为某个变量的地址时应用 & 符。 2.以下选项中,对根本类型雷同的指针变量不能进行运算的运算符是( )。 A. =B. ==C. +D. - 答:C 解析: 选项 A :“=(赋值)”是对于类型雷同的两个指针变量之间惯例运算。 选项 B: “==(比拟相等)”比拟两个指针变量是否雷同。 选项 C:“+” 运算是不能够的,因为指针变量是一种非凡的变量,指针变量的值寄存的是所指向变量的地址,两个地址相加并不能保障后果为一个无效的地址值,因此在 C 语言中指针变量相加是非法的。 选项 D:“-(减法)”运算两个雷同指针变量相减能够取得在之间相隔的同类型元素个数(在某个类型的数组中的利用)。 3.下列程序的输入后果是( )。 void f(int *p){ *p = 5;}int main(void){ int x = 10, *px = &x; f(px); printf("%d#", (*px)++); printf("%d\n", x); return 0;}A.5#6B.6#6C.10#11D.11#11 ...

May 7, 2022 · 9 min · jiezi

关于c:Linux网络开发必学教程13数据收发的扩展用法-上

write() 和 send() 都能够收发数据,有什么区别?send 能够应用 flags 指定可选项信息,其中 0 示意默认发送行为send 当 flags 为 0 时,会期待发送缓冲区数据清空之后才将数据放入发送缓冲器而后返回write 不能指定可选项信息,同时不会阻塞read() 和 recv() 都能够接收数据,有什么区别?recv 能够应用 flags 指定可选项信息,其中 0 示意默认接管行为recv 当 flags 为 0 时,会期待接收缓冲区有数据之后才将数据从接收缓冲区中取出而后返回read 不能指定可选项信息,同时不会阻塞数据收发选项#include <sys/socket.h>ssize_t send(int socketfd, const void *buf, size_t nbytes, int flags);ssize_t recv(int socketfd, void *buf, size_t nbytes, int flags);flags - 收发数据时指定可选项信息,其中 0 为默认收发行为 flags 选项信息 (局部)可选项含意sendrecvMSG_OOB用于传输带外数据(Out Of Band Data),即:紧急数据(优先发送)√√MSG_PEEK验证接收缓冲区是否存在数据(有什么数据) √MSG_DONTROUTE数据传输过程不通过路由表,在本地局域网中寻找目的地√ MSG_DONTWAIT非阻塞模式,数据收发时立刻返回√√MSG_WAITALL在接管到申请的全副数据之前,不提前返回 √MSG_MORE有更多数据须要发送,批示内核期待数据√ ...... 留神: 不同的操作系统对上述可选项的反对不同,理论工程开发时,须要当时对指标零碎中反对的可选项进行调研MSG_OOB (带外数据,紧急数据)原生定义应用与一般数据不同的的通道独立传输的数据带外数据优先级比一般数据高(优先传输,对端优先接管)TCP 中的带外数据因为原生设计的限度,TCP无奈提供真正意义上的带外数据TCP 中仅能通过传输协定音讯头中的标记,传输紧急数据,且长度仅1字节TCP 带外数据实现原理 URG 指针指向紧急音讯的下一个地位,即:URG 指针指向地位的前一个字节存储了紧急音讯接收端优先接管紧急数据,并将其存储到非凡缓冲区,之后再接管一般数据紧急数据:0x03一般数据:0x01,0x02TCP 带外数据处理策略因为 TCP 设计为流式数据,因而,无奈做到真正的带外数据被标记的紧急数据可被提前接管,进入非凡缓冲区(仅一字节) ...

May 7, 2022 · 4 min · jiezi

关于c++:c-stdthread-joindetach用法

detach拆散线程,将对象示意的线程与调用线程拆散,容许它们彼此独立执行。两个线程在没有阻塞或同步的状况下持续运行。留神,当任何一个完结执行时,它的资源都会被开释。让被创立的线程为后盾线程,否则主线程退出时,如果子线程没有退出则异样。 #include <iostream>#include <thread>using namespace std;void func1() { cout << "func1" << endl;}void func2() { cout << "func2" << endl;}int main() { thread t1(func1); thread t2(func2); return 0;}如果间接执行下面的程序,会报错: void func1() {    std::cout << "func1" << std::endl;}void func2() {    std::cout << "func2" << std::endl;}拆散后,则失常: std::thread t1(func1);t1.detach();std::thread t2(func2);t2.detach();join在下面的状况中,个别应用join来解决: #include <iostream>#include <thread>using namespace std;void func1() { cout << "func1" << endl;}void func2() { cout << "func2" << endl;}int main() { thread t1(func1); t1.join(); thread t2(func2); t2.join(); return 0;}然而还是有可能还是会呈现问题,异常情况下可能会存在资源泄露的问题,利用c++的rall机制,能够在析构函数中join,自定义线程类: ...

May 6, 2022 · 1 min · jiezi

关于c:简单谈谈C语言数据类型转换的安全问题

在c语言的赋值类型转换中,有两种转换形式,分为隐形转换和显性转换。 什么是隐性转换,举个简略的demo(当然了,理论遇到的必定比这简单太多) int a = 3; int b = 0;a = b;printf("%d", a);在这里,a的值应该为几,没错,曾经不再是之前的数字,而是变成了b赋予的值,也就是说,咱们这两行代码曾经将a赋予的3变成了b赋予的0,咱们将这种零碎“偷偷摸摸”批改的称之为隐性转换。 这种隐性转换,能够对b的值作出批改,看起来是不是很不便,然而,咱们上面再举一个例子,咱们假如a的值为100000,b的值为1, int a = 1000000; short int b = 0; b = a; printf("%d", b);这种状况下,我这边运行的后果如下: 所以不难看出数据呈现了失落,这是因为,a,b的值过大。因而成为了某些程序员代码中bug的一部分。说完隐性转换,再说说显性转换,举一个简略的例子: int a = 100; double b = 0; b = a; printf("%d", (int)b);这里实际上就是显性转换,显性转换,顾名思义,就是我明晓得会这样,成心这么去设定操作,这里有几个容易失误的中央,那就是输入时肯定须要用%d和(int),对它进行强制。否则输入后果就是浮点型。 好啦,这篇博客就写到这里,如果有其余疑难,欢送评论区评论。

May 6, 2022 · 1 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第7章-数组-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题1.假设 int 类型变量占用两个字节,则以下定义的数组 a 在内存中所占字节数是( )。 int a[10]={10,2,4};A. 20B.10C.6D.3 答:A 解析:题目中,依据 int a[10] ,示意定义了数组的长度是 10 ,每个变量占用两个字节,一共就是 20 个字节。 2.若有定义:int a[2][3] ;以下选项中对数组元素正确援用的是( )。A. a[2][0]B. a[2][3]C. a[0][3]D. a[1>2][1] 答:D 解析: 题目中定义了二维数组 a[2][3] ,那么该数组示意一个 2 行 3 列的矩阵,行的下标(第一个下标)的取值范畴就是 0,1,列的下标(第二个下标)的取值范畴就是 0,1,2。这里是有选项 D,a[1>2][1],实际上是 a[0][1],下标的数值没有越界。 3.以下程序段的输入后果是( )。 int aa[4][4]={{1,2,3,4},{5,6,7,8},{3,9,10,2},{4,2,9,6}};int i, s=0;for(i=0; i<4; i++) s+=aa[i][3];printf("%d\n", s);A.11B.19C.13D.20 答:D 解析: 题目中定义的是二维数组,4X4 的矩阵。 1 2 3 45 6 7 83 9 10 24 2 9 6循环中 i 的值示意行,从 0 取到 3,而列的下标固定是 3,所以示意累加最初一列的值。4+8+2+6 = 20。 ...

May 6, 2022 · 9 min · jiezi

关于c:Linux网络开发必学教程12TCP通讯框架服务端设计

问题:如何设计与客户端对应的服务端?TCP 通信框架设计 服务端负责监听连贯状态 Connect : 产生通信客户端(TcpClient), 并给出事件告诉Close : 给出事件告诉,并销毁客户端负责监听数据通信状态,并给出事件告诉服务端事件设计EVT_CONN: 客户端连贯服务端时触发,并创立 TcpClient 用于通信EVT_DATA: 客户端数据达到服务端时触发,应用 TcpClient 读取数据EVT_CLOSE: 客户端断开服务时触发,相干 TcpClient 将销毁 问题:服务端如何晓得什么时候进行事件回调告诉?服务端通过 select 机制触发事件回调! 服务端接口设计typedef void TcpServer;typedef void (*Listener)(TcpClient*, int);enum { EVT_CONN, EVT_DATA, EVT_CLOSE};TcpServer *TcpServer_New();int TcpServer_Start(TcpServer *server, int port, int max);void TcpServer_Stop(TcpServer *server);void TcpServer_SetListener(TcpServer *server, Listener listener);int TcpServer_IsValid(TcpServer *server);void TcpServer_DoWork(TcpServer *server);void TcpServer_Del(TcpServer *server);服务端要害代码实现 - 初始化typedef struct tcp_server { int fd; int valid; Listener cb; TcpClient *client[FD_SIZE];}Server;TcpServer *TcpServer_New(){ Server *ret = malloc(sizeof(Server)); if (ret) { int i = 0; ret->fd = -1; ret->valid = 0; ret->cb = NULL; } return ret;}服务端要害代码实现 - 事件监听FD_ZERO(&reads);FD_SET(s->fd, &reads);max = s->fd;while (s->valid) { rset = reads; timeout.tv_sec = 0; timeout.tv_usec = 5000; num = select(max+1, &rset, 0, 0, &timeout); if (num > 0) { max = SelectHandler(s, &rset, &reads, num, mac); }}服务器要害代码实现 - 连贯事件 & 数据事件if (index == s->fd) { // 连贯事件 struct sockaddr_in caddr = {0}; socklen_t asize = sizeof(caddr); index = accept(s->fd, (struct sockaddr*)&addr, &asize); if (index > -1) { FD_SET(index, reads); ret = (index > max) ? index : max; s->client[index] = TcpClient_From(index); event = EVT_CONN; }} else { // 数据事件 event = EVT_DATA;}服务器要害代码实现 - 断开事件 & 事件告诉if (s->cb) { if (TcpClient_IsValid(s->client[index])) { s->cb(s->client[index], event); // EVT_CONN & EVT_DATA 事件告诉 } else { if (s->client[index]) { s->cb(s->client[index], EVT_CLOSE); // 断连事件告诉 TcpClient_Del(s->client[index]); s->client[index] = NULL; FD_CLR(index, reads); } }}编程试验tcp_server.h#ifndef TCP_SERVER_H#define TCP_SERVER_H#include "tcp_client.h"typedef void TcpServer;typedef void (*Listener)(TcpClient*, int);enum { EVT_CONN, EVT_DATA, EVT_CLOSE};TcpServer *TcpServer_New();int TcpServer_Start(TcpServer *server, int port, int max);void TcpServer_Stop(TcpServer *server);void TcpServer_SetListener(TcpServer *server, Listener listener);int TcpServer_IsValid(TcpServer *server);void TcpServer_DoWork(TcpServer *server);void TcpServer_Del(TcpServer *server);#endiftcp_server.c#include "tcp_server.h"#include "tcp_client.h"#include <sys/types.h>#include <sys/socket.h>#include <sys/select.h>#include <netinet/in.h>#include <netinet/tcp.h> #include <arpa/inet.h>#include <unistd.h>#include <malloc.h>#define FD_SIZE 1024typedef struct tcp_server { int fd; int valid; Listener cb; TcpClient *client[FD_SIZE];}Server;TcpServer *TcpServer_New(){ Server *ret = malloc(sizeof(Server)); if (ret) { int i = 0; ret->fd = -1; ret->valid = 0; ret->cb = NULL; for (i=0; i<FD_SIZE; ++i) { ret->client[i] = NULL; } } return ret;}int TcpServer_Start(TcpServer *server, int port, int max){ Server *s = (Server*)server; if (s && !s->valid) { struct sockaddr_in saddr = {0}; s->fd = socket(PF_INET, SOCK_STREAM, 0); s->valid = (s->fd != -1); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(port); s->valid = s->valid && (bind(s->fd, (struct sockaddr*)&saddr, sizeof(saddr)) != -1); s->valid = s->valid && (listen(s->fd, max) != -1); } return s->valid;}void TcpServer_Stop(TcpServer *server){ Server *s = (Server*)server; if (s) { int i =0; s->valid = 0; close(s->fd); for (i=0; i<FD_SIZE; ++i) { TcpClient_Del(s->client[i]); s->client[i] = NULL; } }}void TcpServer_SetListener(TcpServer *server, Listener listener){ Server *s = (Server*)server; if (s) { s->cb = listener; }}int TcpServer_IsValid(TcpServer *server){ return server ? ((Server*)server)->valid : 0;}static int SelectHandler(Server *s, fd_set *rset, fd_set *reads, int num, int max){ int ret = max; int i =0; for (i=0; i<=max; ++i) { if (FD_ISSET(i, rset)) { int index = i; int event = -1; if (index == s->fd) { struct sockaddr_in caddr = {0}; socklen_t asize = sizeof(struct sockaddr_in); index = accept(s->fd, (struct sockaddr*)&caddr, &asize); if (index > -1) { FD_SET(index, reads); ret = (index > max) ? index : max; s->client[index] = TcpClient_From(index); event = EVT_CONN; } } else { event = EVT_DATA; } if (s->cb) { if (TcpClient_IsValid(s->client[index])) { s->cb(s->client[index], event); } else { if (s->client[index]) { s->cb(s->client[index], EVT_CLOSE); } TcpClient_Del(s->client[index]); s->client[index] = NULL; FD_CLR(index, reads); } } } } return ret;}void TcpServer_DoWork(TcpServer *server){ Server *s = (Server*)server; if (s && s->valid) { int max = 0; int num = 0; fd_set reads = {0}; fd_set rset = {0}; struct timeval timeout = {0}; FD_ZERO(&reads); FD_SET(s->fd, &reads); max = s->fd; while (s->valid) { rset = reads; timeout.tv_sec = 0; timeout.tv_usec = 10000; num = select(max + 1, &rset, 0, 0, &timeout); if (num > 0) { max = SelectHandler(s, &rset, &reads, num, max); } } }}void TcpServer_Del(TcpServer *server){ TcpServer_Stop(server); free(server);}测试:server.c#include <stdio.h>#include <string.h>#include <malloc.h>#include "tcp_server.h"void EventListener(TcpClient *client, int evt) { if (evt == EVT_CONN) { printf("Connect: %p\n", client); } else if (evt == EVT_DATA) { Message *m = TcpClient_RecvMsg(client); if (m) { char *s = TcpClient_GetDate(client); if (m->index == 0) { s = malloc(m->total + 1); TcpClient_SetData(client, s); } strcpy(s+m->index, m->payload); if ((m->index + 1) == m->total) { printf("Data: %s\n", s); free(s); } free(m); } } else if (evt == EVT_CLOSE) { printf("close: %p\n", client); }}int main(){ TcpServer *server = TcpServer_New(); if (server) { int r = TcpServer_Start(server, 8888, 20); if (r) { TcpServer_SetListener(server, EventListener); TcpServer_DoWork(server); } } return 0;}输入:Connect: 0x5602eb035690Data: D.T.Softwareclose: 0x5602eb035690

May 5, 2022 · 4 min · jiezi

关于c++:Blackjack-游戏开发

BlackjackIntro:Blackjack is a comparing card game between one or more players and a dealer, where each player in turncompetes against the dealer. Players do not compete against each other. It is played with one or more decksof 52 cards, and is the most widely played casino banking game in the world.[1] <Blackjack>Now, in this project, you are required to implement 1 Human vs 1 Computer blackjack.Game Description:In the game, the winner with the highest the number of points must have 21 points or less. Blackjack meansget Ace and ten-value at same time in the licensing phase. Each player wants to win the game as much aspossible, and the criteria are as follows:If the player is dealt an blackjack, and the dealer does not, the player wins, vice versa.If the player exceeds a sum of 21 ("busts"), the player loses, vice versa.If the player attains a final sum higher than the dealer and does not bust, the player wins, vice versa.If both dealer and player receive a blackjack or any other hands with the same sum called a "push", noone wins.Main rules and flow path:rules:There are 52 cards in each deck, except two jokers.Two decks of playing cards are used at a game. The deck will continue to be played in each subsequentround until the number of cards left is less than half or renewing the game. At this point, the cards arereshuffled.The value of cards two through ten is their pip value. Jack, Queen, and King are all worth ten. Aces can beworth one or eleven.In the game, the computer is the dealer, and the person is the player.No one can have more than five cards in his hand.The order of the draw is the sequential draw.All cards drawn in Hit are exposed.flow path: ...

May 5, 2022 · 6 min · jiezi

关于c:Linux网络开发必学教程11TCP通讯框架客户端设计

问题:有了协定和协定解析器之后,能够干嘛?TCP 通信框架设计 客户端 以协定音讯为根本单位收发数据同时反对字节为根本单位收发数据服务端 负责监听链接,并产生通信客户端负责监听数据通讯状态,并给出告诉 职责意义客户端用于进行理论的双向数据通信 数据发送 & 数据接管 (协定音讯)服务端仅用于监听和回调告诉 事件类型:连贯,数据,断开事件回调:void (*Listener)(TcpClient *client, int event);客户端接口设计typedef void TcpClient;TcpClient *TcpClient_New();TcpClient *TcpClient_From(int fd);int TcpClient_SendMsg(TcpClient *client, Message *msg);int TcpClient_SendRaw(TcpClient *client, char *buf, int length);Message *TcpClient_RecvMsg(TcpClient *client);int TcpClient_RecvRaw(TcpClient *client, char *buf, int length);int TcpClient_Connect(TcpClient *client, char *ip, int port);int TcpClient_IsValid(TcpClient *client);void TcpClient_Close(TcpClient *client);void TcpClient_Del(TcpClient *client);void TcpClient_SetData(TcpClient *client, void *data);void *TcpClient_GetDate(TcpClient *client);编程试验:客户端设计与实现message.h#ifndef MESSAGE_H#define MESSAGE_Htypedef struct message { unsigned short type; unsigned short cmd; unsigned short index; unsigned short total; unsigned int length; unsigned char payload[];}Message;Message *Message_New(unsigned short type, unsigned short cmd, unsigned short index, unsigned short total, unsigned char *payload, unsigned int length);int Message_Size(Message *m);Message *Message_N2H(Message *m);Message *Message_H2N(Message *m);#endifmessage.c#include "message.h"#include <malloc.h>#include <string.h>#include <arpa/inet.h>Message *Message_New(unsigned short type, unsigned short cmd, unsigned short index, unsigned short total, unsigned char *payload, unsigned int length){ Message *ret = malloc(sizeof(Message) + length); if (ret) { ret->type = type; ret->cmd = cmd; ret->index = index; ret->total = total; ret->length = length; if (payload) { memcpy(ret + 1, payload, length); } } return ret;}int Message_Size(Message *m){ int ret = 0; if (m) { ret = sizeof(Message) + m->length; } return ret;}Message *Message_N2H(Message *m){ if (m) { m->type = ntohs(m->type); m->cmd = ntohs(m->cmd); m->index = ntohs(m->index); m->total = ntohs(m->total); m->length = ntohl(m->length); } return m;}Message *Message_H2N(Message *m){ if (m) { m->type = htons(m->type); m->cmd = htons(m->cmd); m->index = htons(m->index); m->total = htons(m->total); m->length = htonl(m->length); } return m; }msg_parser.h#ifndef MSG_PARSER_H#define MSG_PARSER_H#include "message.h"typedef void MParser;MParser *MParser_New();Message *MParser_ReadMem(MParser *parser, unsigned char *mem, unsigned int length);Message *MParser_ReadFd(MParser *parser, int fd);void MParser_Reset(MParser *parse);void MParser_Del(MParser *parse);#endifmsg_parser.c#include <malloc.h>#include <string.h>#include <arpa/inet.h>#include <unistd.h>#include "msg_parser.h"typedef struct msg_parser { Message cache; int header; int need; Message *msg;}MsgParser;static void InitState(MsgParser *p){ p->header = 0; p->need = sizeof(p->cache); free(p->msg); p->msg = NULL;}static int ToMidState(MsgParser *p){ p->header = 1; p->need = p->cache.length; p->msg = malloc(sizeof(p->cache) + p->need); if (p->msg) { *p->msg = p->cache; } return !!p->msg;}static Message *ToLastState(MsgParser *p){ Message *ret = NULL; if (p->header && !p->need) { ret = p->msg; p->msg = NULL; } return ret;}static int ToRecv(int fd, char *buf, int size){ int retry = 0; int i = 0; while (i < size) { int len = read(fd, buf + i, size - i); if (len > 0) { i += len; } else if (len < 0) { break; } else { if (retry++ > 5) { break; } usleep(200 * 1000); } } return i;}MParser *MParser_New(){ MsgParser *ret = calloc(1, sizeof(MsgParser)); InitState(ret); return ret;}Message *MParser_ReadMem(MParser *parser, unsigned char *mem, unsigned int length){ Message *ret = NULL; MsgParser *p = (MsgParser*)parser; if (!p || !mem || !length) { return ret; } if (!p->header) { int len = (p->need < length) ? p->need : length; int offset = sizeof(p->cache) - p->need; memcpy((char*)&p->cache + offset, mem, len); if (p->need == len) { Message_N2H(&p->cache); mem += p->need; length -= p->need; if (ToMidState(p)) { ret = MParser_ReadMem(p, mem, length); } else { InitState(p); } } else { p->need -= len; } } else { if (p->msg) { int len = (p->need < length) ? p->need : length; int offset = p->msg->length - p->need; memcpy(p->msg->payload + offset, mem, len); p->need -= len; if (ret = ToLastState(p)) { InitState(p); } } } return ret;}Message *MParser_ReadFd(MParser *parser, int fd){ Message *ret = NULL; MsgParser *p = (MsgParser*)parser; if (fd == -1 || !p) { return ret; } if (!p->header) { int offset = sizeof(p->cache) - p->need; int len = ToRecv(fd, (char*)&p->cache + offset, p->need); if (len == p->need) { Message_N2H(&p->cache); if (ToMidState(p)) { ret = MParser_ReadFd(p, fd); } else { InitState(p); } } else { p->need -= len; } } else { if (p->msg) { int offset = p->msg->length - p->need; int len = ToRecv(fd, p->msg->payload + offset, p->need); p->need -= len; } if (ret = ToLastState(p)) { InitState(p); } } return ret;}void MParser_Reset(MParser *parse){ MsgParser *p = (MsgParser*)parse; if (p) { InitState(p); }}void MParser_Del(MParser *parse){ MsgParser *p = (MsgParser*)parse; if (p) { free(p->msg); free(p); }}tcp_client.h#ifndef TCP_CLIENT_H#define TCP_CLIENT_H#include "message.h"typedef void TcpClient;TcpClient *TcpClient_New();TcpClient *TcpClient_From(int fd);int TcpClient_SendMsg(TcpClient *client, Message *msg);int TcpClient_SendRaw(TcpClient *client, char *buf, int length);Message *TcpClient_RecvMsg(TcpClient *client);int TcpClient_RecvRaw(TcpClient *client, char *buf, int length);int TcpClient_Connect(TcpClient *client, char *ip, int port);int TcpClient_IsValid(TcpClient *client);void TcpClient_Close(TcpClient *client);void TcpClient_Del(TcpClient *client);void TcpClient_SetData(TcpClient *client, void *data);void *TcpClient_GetDate(TcpClient *client);#endiftcp_client.c#include "tcp_client.h"#include "msg_parser.h"#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h> #include <arpa/inet.h>#include <unistd.h>#include <malloc.h>typedef struct tcp_client { int fd; MParser *parser; void *data;}Client;TcpClient *TcpClient_New(){ return TcpClient_From(-1);}TcpClient *TcpClient_From(int fd){ Client *ret = malloc(sizeof(Client)); if (ret) { ret->fd = fd; ret->parser = MParser_New(); ret->data = NULL; } return (ret && ret->parser) ? ret : (free(ret), NULL);}int TcpClient_SendMsg(TcpClient *client, Message *msg){ int ret = 0; Client *c = (Client*)client; if (c && msg) { int len = Message_Size(msg); char *data = (char*)Message_H2N(msg); ret = (send(c->fd, data, len, 0) != -1); Message_N2H(msg); } return ret;}int TcpClient_SendRaw(TcpClient *client, char *buf, int length){ int ret = 0; Client *c = (Client*)client; if (c && buf) { ret = send(c->fd, buf, length, 0); } return ret;}Message *TcpClient_RecvMsg(TcpClient *client){ Message *ret = NULL; Client *c = (Client*)client; if (c) { ret = MParser_ReadFd(c->parser, c->fd); } return ret;}int TcpClient_RecvRaw(TcpClient *client, char *buf, int length){ int ret = 0; Client *c = (Client*)client; if (c && buf) { ret = recv(c->fd, buf, length, 0); } return ret;}int TcpClient_Connect(TcpClient *client, char *ip, int port){ int ret = TcpClient_IsValid(client); Client *c = (Client*)client; if (!ret && ip && ((c->fd = socket(PF_INET, SOCK_STREAM, 0)) != -1)) { struct sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ip); addr.sin_port = htons(port); ret = (connect(c->fd, (struct sockaddr*)&addr, sizeof(addr)) != -1); } return ret;}int TcpClient_IsValid(TcpClient *client){ int ret = 0; Client *c = (Client*)client; if (c) { struct tcp_info info = {0}; int l = sizeof(info); getsockopt(c->fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t*)&l); ret = (info.tcpi_state == TCP_ESTABLISHED); } return ret;}void TcpClient_Close(TcpClient *client){ Client *c = (Client*)client; if (c) { close(c->fd); c->fd = -1; MParser_Reset(c->parser); }}void TcpClient_Del(TcpClient *client){ Client *c = (Client*)client; if (c) { TcpClient_Close(c); MParser_Del(c->parser); free(c); } }void TcpClient_SetData(TcpClient *client, void *data){ Client *c = (Client*)client; if (c) { c->data = data; }}void *TcpClient_GetDate(TcpClient *client){ void *ret = NULL; Client *c = (Client*)client; if (c) { ret = c->data; } return ret;}测试文件:client.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <malloc.h>#include "message.h"#include "tcp_client.h"int main(){ int i = 0; char *test = "D.T.Software"; Message *pm = NULL; TcpClient *client = TcpClient_New(); if (client && TcpClient_Connect(client, "127.0.0.1", 8888)) { printf("connect success\n"); for (i=0; i<strlen(test); ++i) { char buf[2] = {0}; buf[0] = test[i]; pm = Message_New(128, 129, i, strlen(test), buf, 2); TcpClient_SendMsg(client, pm); free(pm); } } getchar(); TcpClient_Del(client); return 0;}测试文件:server.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/tcp.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <malloc.h>#include "msg_parser.h"#include "tcp_client.h"int main(){ int server = 0; struct sockaddr_in saddr = {0}; struct sockaddr_in caddr = {0}; socklen_t asize = 0; int client = 0; server = socket(PF_INET, SOCK_STREAM, 0); if (server == -1) { printf("server socket error\n"); return -1; } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(8888); if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { printf("server bind error\n"); return -1; } if (listen(server, 1) == -1) { printf("server listen error\n"); return -1; } printf("server start success\n"); while (1) { TcpClient *c = NULL; struct tcp_info info = {0}; int l = sizeof(info); asize = sizeof(caddr); client = accept(server, (struct sockaddr*)&caddr, &asize); if (client == -1) { printf("client accept error\n"); return -1; } c = TcpClient_From(client); printf("client: %d\n", client); printf("addr: %p\n", c); do { Message *m = TcpClient_RecvMsg(c); if (m) { printf("payload = %s\n", m->payload); free(m); } } while (TcpClient_IsValid(c)); printf("client socket is closed\n"); TcpClient_Del(c); } close(server); return 0;}输入: ...

May 4, 2022 · 6 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第6章-回顾数据类型和表达式-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.已知字符 'A' 的 ASCII 码是 65,别离对应八进制数 101 和十六进制数 41,以下( )不能正确示意字符'A'。 A. 'A' B. '\101' C. '\x41' D. '\0x41' 答:D 解析: 十六进制示意字符用 \x 结尾。 2.设 a 为整型变量,不能正确表白数学关系: 10<a<15 的 C 语言表达式是( )。 A.10<a<15 B. !(a<= 10lla>= 15) C. a>10 && a<15 D. !(a<= 10)&&!(a>= 15) 答:A 解析: 在 C 语言中,不能像选项 A 中 10<a<15,这样写。 3.执行以下程序段后,变量 c 的值是( )。 int a=10, b=20, c;c=(a%2==0)? a:bA.0 B.5 C.10 D.20 答:C 解析: ...

May 4, 2022 · 7 min · jiezi

关于c:Linux网络开发必学教程10应用协议解析模块下

问题:如何通过 socket 文件描述符实时解析协定数据?深度思考从文件描述符是否可能获取足够的数据?(是否肯定等到数量足够(如:音讯头12字节),能力开始解析)数据量足够 读取 12 字节解析音讯头读取数据填充 payload (length)数据量有余 无奈获取音讯头所需数据(如何解决?解析状态如何切换?)无奈获取 payload 残缺数据(如何解决?是否可追加?)解决方案策略:尽力获取数据,实时解析即使以后获取 1 字节,也可依据状态进行解析反对不同数据源屡次接力解析(从内存或文件描述符交替获取数据)充分利用解析器状态信息是实现解决方案的要害解析器状态切换 状态切换函数static void InitState(MsgParser *p) { p->header = 0; p->need = sizeof(p->cache); free(p->msg); p->msg = NULL;}static int ToMidState(MsgParser *p){ p->header = 1; p->need = p->cache.length; p->msg = malloc(sizeof(p->cache) + p->need); if (p->msg) { *p->msg = p->cache; } return !!p->msg;}static Message *ToLastState(MsgParser *p){ Message *ret = NULL; if (p->header && !p->need) { ret = p->msg; p->msg = NULL; } return ret;}从文件描述符中获取数据static int ToRecv(int fd, char *buf, int size){ int retry = 0; int i = 0; while (i < size) { int len = read(fd, buf + i, size - i); if (len > 0) { i += len; } else { if (retry++ > 5) { break; } usleep(200 * 10000); } } return i;}从文件描述符中实时解析音讯头if (!p->header) { int offset = sizeof(p->cache) - p->need; int len = ToRecv(fd, (char*)&p->cache + offset/* 计算寄存地位并读取音讯头数据 */, p->need); if (len == p->need) { ntoh(&p->cache); if (ToMidState(p)) { ret = MParser_ReadFd(p, fd); } } else { p->need -= len; }}从文件描述符中获取 payload 数据if (p->msg) { int len = ToRecv(fd, p->msg->payload, p->need); p->need -= len;}/* 尝试切换到最终状态,如果胜利,则可取得协定音讯;之后切换到初始状态 */if (ret = ToLastState(p)) { InitState(p);}编程试验:从文件描述符解析协定音讯message.h#ifndef MESSAGE_H#define MESSAGE_Htypedef struct message { unsigned short type; unsigned short cmd; unsigned short index; unsigned short total; unsigned int length; unsigned char payload[];}Message;Message *Message_New(unsigned short type, unsigned short cmd, unsigned short index, unsigned short total, unsigned char *payload, unsigned int length);#endifmessage.c#include "message.h"#include <malloc.h>#include <string.h>Message *Message_New(unsigned short type, unsigned short cmd, unsigned short index, unsigned short total, unsigned char *payload, unsigned int length){ Message *ret = malloc(sizeof(Message) + length); if (ret) { ret->type = type; ret->cmd = cmd; ret->index = index; ret->total = total; ret->length = length; if (payload) { memcpy(ret + 1, payload, length); } } return ret;}msg_parser.h#ifndef MSG_PARSER_H#define MSG_PARSER_H#include "message.h"typedef void MParser;MParser *MParser_New();Message *MParser_ReadMem(MParser *parser, unsigned char *mem, unsigned int length);Message *MParser_ReadFd(MParser *parser, int fd);void MParser_Reset(MParser *parse);void MParser_Del(MParser *parse);#endifmsg_parser.c#include <malloc.h>#include <string.h>#include <arpa/inet.h>#include <unistd.h>#include "msg_parser.h"typedef struct msg_parser { Message cache; int header; int need; Message *msg;}MsgParser;static void InitState(MsgParser *p){ p->header = 0; p->need = sizeof(p->cache); free(p->msg); p->msg = NULL;}static int ToMidState(MsgParser *p){ p->header = 1; p->need = p->cache.length; p->msg = malloc(sizeof(p->cache) + p->need); if (p->msg) { *p->msg = p->cache; } return !!p->msg;}static Message *ToLastState(MsgParser *p){ Message *ret = NULL; if (p->header && !p->need) { ret = p->msg; p->msg = NULL; } return ret;}static void ntoh(Message *m){ m->type = ntohs(m->type); m->cmd = ntohs(m->cmd); m->index = ntohs(m->index); m->total = ntohs(m->total); m->length = ntohl(m->length); }static int ToRecv(int fd, char *buf, int size){ int retry = 0; int i = 0; while (i < size) { int len = read(fd, buf + i, size - i); if (len > 0) { i += len; } else if (len < 0) { break; } else { if (retry++ > 5) { break; } usleep(200 * 1000); } } return i;}MParser *MParser_New(){ MsgParser *ret = calloc(1, sizeof(MsgParser)); InitState(ret); return ret;}Message *MParser_ReadMem(MParser *parser, unsigned char *mem, unsigned int length){ Message *ret = NULL; MsgParser *p = (MsgParser*)parser; if (!p || !mem || !length) { return ret; } if (!p->header) { int len = (p->need < length) ? p->need : length; int offset = sizeof(p->cache) - p->need; memcpy((char*)&p->cache + offset, mem, len); if (p->need == len) { ntoh(&p->cache); mem += p->need; length -= p->need; if (ToMidState(p)) { ret = MParser_ReadMem(p, mem, length); } else { InitState(p); } } else { p->need -= len; } } else { if (p->msg) { int len = (p->need < length) ? p->need : length; int offset = p->msg->length - p->need; memcpy(p->msg->payload + offset, mem, len); p->need -= len; if (ret = ToLastState(p)) { InitState(p); } } } return ret;}Message *MParser_ReadFd(MParser *parser, int fd){ Message *ret = NULL; MsgParser *p = (MsgParser*)parser; if (fd == -1 || !p) { return ret; } if (!p->header) { int offset = sizeof(p->cache) - p->need; int len = ToRecv(fd, (char*)&p->cache + offset, p->need); if (len == p->need) { ntoh(&p->cache); if (ToMidState(p)) { ret = MParser_ReadFd(p, fd); } else { InitState(p); } } else { p->need -= len; } } else { if (p->msg) { int offset = p->msg->length - p->need; int len = ToRecv(fd, p->msg->payload + offset, p->need); p->need -= len; } if (ret = ToLastState(p)) { InitState(p); } } return ret;}void MParser_Reset(MParser *parse){ MsgParser *p = (MsgParser*)parse; if (p) { InitState(p); }}void MParser_Del(MParser *parse){ MsgParser *p = (MsgParser*)parse; if (p) { free(p->msg); free(p); }}测试一:test.c#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include "msg_parser.h"int main(){ MParser *p = MParser_New(); char buf[] = {0x00, 0x01, 0x00, 0x02, 0x00}; char another[] = {0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04}; char data[] = {0x11, 0x12, 0x13, 0x14}; Message *m = MParser_ReadMem(p, buf, sizeof(buf)); int i = 0; if (!m) { printf("parse again...\n"); m = MParser_ReadMem(p, another, sizeof(another)); } if (!m) { printf("parse again again...\n"); m = MParser_ReadMem(p, data, sizeof(data)); } printf("m = %p\n", m); if (m) { printf("type = %d\n", m->type); printf("cmd = %d\n", m->cmd); printf("index = %d\n", m->index); printf("total = %d\n", m->total); printf("length = %d\n", m->length); for (i=0; i<m->length; ++i) { printf("0x%02x ", m->payload[i]); } printf("\n"); free(m); } MParser_Del(p); return 0; }输入:parse again...parse again again...m = 0x555e21dd56a0type = 1cmd = 2index = 3total = 4length = 40x11 0x12 0x13 0x14测试2:client.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <malloc.h>#include "message.h"static void hton(Message *m){ m->type = htons(m->type); m->cmd = htons(m->cmd); m->index = htons(m->index); m->total = htons(m->total); m->length = htonl(m->length); }int main(){ int sock = 0; struct sockaddr_in addr = {0}; int i = 0; char *test = "D.T.Software"; Message *pm = NULL; sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("socket error\n"); return -1; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(8888); if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { printf("connect error\n"); return -1; } printf("connect success\n"); for (i=0; i<strlen(test); ++i) { char buf[2] = {0}; buf[0] = test[i]; pm = Message_New(128, 129, i, strlen(test), buf, 2); hton(pm); send(sock, pm, sizeof(Message) + 2, 0); free(pm); } close(sock); return 0;}server.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/tcp.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <malloc.h>#include "msg_parser.h"int main(){ int server = 0; struct sockaddr_in saddr = {0}; int client = 0; struct sockaddr_in caddr = {0}; socklen_t asize = 0; int len = 0; char buf[32] = {0}; int r = 0; MParser *parser = MParser_New(); server = socket(PF_INET, SOCK_STREAM, 0); if (server == -1) { printf("server socket error\n"); return -1; } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(8888); if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { printf("server bind error\n"); return -1; } if (listen(server, 1) == -1) { printf("server listen error\n"); return -1; } printf("server start success\n"); while (1) { struct tcp_info info = {0}; int l = sizeof(info); asize = sizeof(caddr); client = accept(server, (struct sockaddr*)&caddr, &asize); if (client == -1) { printf("client accept error\n"); return -1; } printf("client: %d\n", client); do { getsockopt(client, IPPROTO_TCP, TCP_INFO, &info, (socklen_t*)&l); Message *m = MParser_ReadFd(parser, client); if (m) { printf("type = %d\n", m->type); printf("cmd = %d\n", m->cmd); printf("index = %d\n", m->index); printf("total = %d\n", m->total); printf("length = %d\n", m->length); printf("payload = %s\n", m->payload); printf("\n"); free(m); } } while (info.tcpi_state == TCP_ESTABLISHED); printf("client socket is closed\n"); close(client); } close(server); MParser_Del(parser); return 0;}输入:server start successclient: 4type = 128cmd = 129index = 0total = 12length = 2payload = Dtype = 128cmd = 129index = 1total = 12length = 2payload = .type = 128cmd = 129index = 2total = 12length = 2payload = Tclient socket is closed有了协定和协定解析器之后,能够干嘛?

May 4, 2022 · 6 min · jiezi

关于c++:C单例模式双重锁漏洞内存读写的乱序执行编译器问题

阐明首先解释为什么会呈现这个问题:在懒汉模式下存在多线程不平安的问题(饿汉模式是线程平安的),为了解决这个问题,首先采纳的是利用C++中lock_guard类,这个类实现原理采纳RAII,不必手动治理unlock。 class singleton {private: singleton() {} static singleton *p; static mutex lock_;public: static singleton *instance();};singleton *singleton::p = nullptr;singleton* singleton::instance() { lock_guard<mutex> guard(lock_); if (p == nullptr) p = new singleton(); return p;}解决了懒汉模式的这个问题,又呈现了性能问题:每次执行都会有加锁开释锁, 而这个步骤只有在第一次new Singleton()才是有必要的. 因而引出DCL 双重查看锁模式class singleton {private: singleton() {} static singleton *p; static mutex lock_;public: singleton *instance(); // 实现一个内嵌垃圾回收类 class CGarbo { public: ~CGarbo() { if(singleton::p) delete singleton::p; } }; // 2022-4-21 // 所谓的垃圾回收,就是定义一个动态的类,类外面只有一个办法,这个办法查看singleton::p是否是空,不是空,执行delete // 因为是动态的办法,程序会主动的开释该对象,从而达到主动回收的机制。 static CGarbo Garbo; // 定义一个动态成员变量,程序完结时,零碎会主动调用它的析构函数从而开释单例对象};singleton *singleton::p = nullptr;singleton::CGarbo Garbo;singleton* singleton::instance() { if (p == nullptr) { lock_guard<mutex> guard(lock_); if (p == nullptr) p = new singleton(); } return p;}留神咱们的题目是单例模式双重锁破绽。 ...

May 3, 2022 · 1 min · jiezi

关于c:Linux网络开发必学教程9应用协议解析模块上

问题:如何在代码层面封装协定细节?如何将接收缓冲区中的数据解析为 Message ?深度思考数据是否可能解析成为 Message ?数据量足够 如果数据量足够,是否可能解析不止一个 Message?如何解决残余数据 (属于下一个 Message)数据量有余 是否达到协定最小长度(12 字节)?如何解决数据量超过最小长度,但不足以创立一个 Message 的状况?初步的解决方案定义一个模块用于从字节流解析 Message可 从指定内存 或 从指定文件描述符 读取并解析当至多存在 12 个字节时开始解析 首先解析协定中的头信息和数据区长度(length)依据数据区长度持续从字节流读取数据(payload)当协定数据解析实现时,创立 Message 并返回,否则,返回 NULL协定解析模块的初步设计解析器接口定义typedef void MParser;MParser *MParser_New();Message *MParser_ReadMem(MParser *parser, unsigned char *mem, unsigned int length);Message *MParser_ReadFd(MParser *parser, int fd);void MParser_Reset(MParser *parser);void MParser_Del(MParser *parser);解析器数据结构typedef struct msg_parser { Message cache; // 缓存已解析的音讯头 int header; // 标识音讯头是否解析胜利 int need; // 标识还剩多少字节能力实现解析 Message *msg; // 解析中的协定音讯(半成品)}MsgParser;条件:内存长度至多间断 12 个字节memcpy(&p->cache, mem, p->need);p->cache.type = ntohs(p->cache.type); // 从网络字节序转换为本机字节序p->cache.cmd = ntohs(p->cache.cmd);p->cache.index = ntohs(p->cache.index);p->cache.total = ntohs(p->cache.total);p->cache.length = ntohs(p->cache.length);mem += p->need;length -= p->need;p->header = 1;p->need = p->cache.length;从内存中读取 payload 中的数据(可读取屡次)if (!p->msg) { // 胜利创立音讯头之后, 创立 Message p->msg = malloc(sizeof(p->cache) + p->need); if (p->msg) { *p->msg = p->cache; }}if (p->msg) { unsigned int len = (p->need < length) > p->need : length; unsigned int offset = p->msg->length - p->need; memcpy(p->msg->payload + offset, mem, len); p->need -= len;}编程试验:协定解析模块初步设计msg_parser.h#ifndef MSG_PARSER_H#define MSG_PARSER_H#include "message.h"typedef void MParser;MParser *MParser_New();Message *MParser_ReadMem(MParser *parser, unsigned char *mem, unsigned int length);Message *MParser_ReadFd(MParser *parser, int fd);void MParser_Reset(MParser *parse);void MParser_Del(MParser *parse);#endifmsg_parser.c#include <malloc.h>#include <string.h>#include <arpa/inet.h>#include <unistd.h>#include "msg_parser.h"typedef struct msg_parser { Message cache; int header; int need; Message *msg;}MsgParser;MParser *MParser_New(){ MsgParser *ret = calloc(1, sizeof(MsgParser)); MParser_Reset(ret); return ret;}Message *MParser_ReadMem(MParser *parser, unsigned char *mem, unsigned int length){ Message *ret = NULL; MsgParser *p = (MsgParser*)parser; if (!p || !mem || !length) { return ret; } if (!p->header) { if (p->need <= length) { memcpy(&p->cache, mem, p->need); p->cache.type = ntohs(p->cache.type); p->cache.cmd = ntohs(p->cache.cmd); p->cache.index = ntohs(p->cache.index); p->cache.total = ntohs(p->cache.total); p->cache.length = ntohl(p->cache.length); mem += p->need; length -= p->need; p->header = 1; p->need = p->cache.length; ret = MParser_ReadMem(parser, mem, length); } } else { if (!p->msg) { p->msg = malloc(sizeof(p->cache) + p->need); if (p->msg) { *p->msg = p->cache; } } if (p->msg) { unsigned int len = (p->need < length) ? p->need : length; unsigned int offset = p->msg->length - p->need; memcpy(p->msg->payload, mem, len); p->need -= len; } if (!p->need) { ret = p->msg; p->msg = NULL; MParser_Reset(p); } } return ret;}Message *MParser_ReadFd(MParser *parser, int fd){ Message *ret = NULL; return ret;}void MParser_Reset(MParser *parse){ MsgParser *p = (MsgParser*)parse; if (p) { p->header = 0; p->need = sizeof(p->cache); free(p->msg); p->msg = NULL; }}void MParser_Del(MParser *parse){ MsgParser *p = (MsgParser*)parse; if (p) { free(p->msg); free(p); }}test.c#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include "msg_parser.h"int main(){ MParser *p = MParser_New(); char buf[] = {0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04}; char data[] = {0x11, 0x12, 0x13, 0x14}; Message *m = MParser_ReadMem(p, buf, sizeof(buf)); int i = 0; if (!m) { printf("parse again...\n"); m = MParser_ReadMem(p, data, sizeof(data)); } printf("m = %p\n", m); if (m) { printf("type = %d\n", m->type); printf("cmd = %d\n", m->cmd); printf("index = %d\n", m->index); printf("total = %d\n", m->total); printf("length = %d\n", m->length); for (i=0; i<m->length; ++i) { printf("0x%02x ", m->payload[i]); } printf("\n"); free(m); } MParser_Del(p); return 0; }思考:如何通过 socket 文件描述符实时解析协定数据?

May 3, 2022 · 3 min · jiezi

关于c++:浅谈重写操作符CSE111

CSE-111 • Spring 2021 • Program 1 • Overloading and operators Using C++11/14/17 (20?)All programming in this course will be done C++ style, not C style, as shown in thefollowing table.Do not use : Instead, use :char* strings <string>C arrays <vector><stdio.h>, <cstdio> <iostream>, <iomanip>pointers <shared_ptr>union inheritance<header.h> <cheader>Include only C++11/14/17 header files where feasible : using namespace std;Include <cheader> files only when C++-style files are unavailable. Include <header.h> files from C only when an appropriate <cheader> files is unavailable. Use thescript cpplint.py.perl (a wrapper for cpplint.py) to check style.OverviewThis assignment will involve overloading basic integer operators to perform arbitraryprecision integer arithmetic in the style of dc(1). Your class bigint will intermixarbitrarily with simple integer arithmetic.To begin read the man(1) page for the command dc(1) :man -s 1 dcA copy of that page is also in this directory. Your program will use the standard dcas a reference implemention and must produce exactly the same output for thecommands you have to implement :+-*/%^cdfpqIf you have any questions as to the exact format of your output, just run dc(1) andmake sure that, for the operators specified above, your program produces exactlythe same output. A useful program to compare output from your program with thatof dc(1) is diff(1), which compares the contents of two files and prints only the differences.Also look in the subdirectory misc/ for some examples.See also :• dc (computer program)https://en.wikipedia.org/wiki...(computer_program)• dc, an arbitrary precision calculatorhttps://www.gnu.org/software/...Implementation strategyAs before, you have been given starter code.(a) Makefile, debug, and util If you find you need a function which does not properlybelong to a given module, you may add it to util.CSE-111 • Spring 2021 • Program 1 • Overloading and operators 2 of 5(b) The module scanner reads in tokens, namely a NUMBER, an OPERATOR, or SCANEOF.Each token returns a token_t, which indicates what kind of token it is (theterminal_symbol symbol), and the string lexinfo associated with the token.Only in the case of a number is there more than one character. Note that oninput, an underscore (_) indicates a negative number. The minus sign (-) isreserved only as a binary operator. The scanner also has defined a couple ofoperator<< for printing out scanner results in debug mode.(c) The main program main.cpp, has been implemented for you. For the six binaryarithmetic functions, the right operand is popped from the stack, then the leftoperand, then the result is pushed onto the stack.(d) The module iterstack can not just be the STL stack, since we want to iteratefrom top to bottom, and the STL stack does not have an iterator. A stackdepends on the operations back(), push_back(), and pop_back() in the underlyingcontainer. We could use a vector, a deque, or just a list, as long as the requisiteoperations are available.Class bigintThen we come to the most complex part of the assignment, namely the class bigint.Operators in this class are heavily overloaded.(a) Most of the functions take a arguments of type const bigint&, i.e., a constantreference, for the sake of efficiency. But they have to return the result byvalue.(b) The operator<< can’t be a member since its left operand is an ostream, so wemake it a friend, so that it can see the innards of a bigint. Note now dc printsreally big numbers.(c) The relational operators == and < are coded individually as member functions.The others, !=, <=, >, and >= are defined in terms of the essential two.(d) All of the functions of bigint only work with the sign, using ubigint to do theactual computations. So bigint::operator+ and bigint::operator- will checkthe signs of the two operands then call ubigint::operator+ or ubigint::operator-,as appropriate, depending on the relative signs and magnitudes. Themultiplication and division operators just call the corresponding ubigint operators,then adjust the resulting sign according to the rule of signs.Class ubigintClass ubigint implements unsigned large integers and is where the computationalwork takes place. Class bigint takes care of the sign. Now we turn to the representationof a ubigint, which will be represented by vector of bytes.(a) Replace the declarationusing unumber = unsigned long;unumber uvalue {};withusing ubigvalue_t = vector<uint8_t>;ubigvalue_t ubig_value;in the header file <ubigint.h>. The type uint8_t is an unsigned 8-bit integerCSE-111 • Spring 2021 • Program 1 • Overloading and operators 3 of 5defined in <cstdint>.(b) In storing the big integer, each digit is kept as an integer in the range 0 to 9 inan element of the vector. Since the arithmetic operators add and subtractwork from least significant digit to most significant digit, store the elements ofthe vector in the same order. That means, for example, that the number 4629would be stored in a vector v as : v3 = 4, v2 = 6, v1 = 2, v0 = 9. In other words,if a digit’s value is d × 10k, then vk = d.(c) In order for the comparisons to work correctly, always store numbers in acanonical form : After computing a value from any one of the six arithmeticoperators, always trim the vector by removing all high-order zeros :while (size() > 0 and back() == 0) pop_back();Zero should be represented as a vector of zero length and a positive sign.(d) The scanner will produce numbers as strings, so scan each string from the endof the string, using a const_reverse_iterator (or other means) from the end ofthe string (least significant digit) to the beginning of the string (most signifi-cant digit) using push_back to append them to the vector.Implementation of Operators(a) For bigint::operator+, check to see if the signs are the same or different. Ifthe same, call ubigint::operator+ to compute the sum, and set the result signas appopriate. If the signs are different, call ubigint::operator- with thelarger number first and the smaller number second. The sign is the sign of thelarger number.(b) The operator bigint::operator- should perform similarly. If the signs are different,it uses ubigint::operator+ but if the same, it uses ubigint::operator-.(c) To implement ubigint::operator+, create a new ubigint and proceed from thelow order end to the high order end, adding digits pairwise. For any sum >=10, take the remainder and add the carry to the next digit. Use push_back toappend the new digits to the ubigint. When you run out of digits in theshorter number, continue, matching the longer vector with zeros, until it isdone. Make sure the sign of 0 is positive.(d) To implement ubigint::operator-, also create a new empty vector, startingfrom the low order end and continuing until the high end. If the left digit issmaller than the right digit, the subtraction will be less than zero. In thatcase, add 10 to the digit, and set the borrow to the next digit to −1. After thealgorithm is done, pop_back all high order zeros from the vector before returningit. Make sure the sign of 0 is positive.(e) To implement operator==, check to see if the signs are the same and thelengths of the vectors are the same. If not, return false. Otherwise run downboth vectors and return false as soon a difference is found. Otherwise returntrue.(f) To implement operator<, remember that a negative number is less than a positivenumber. If the signs are the same, for positive numbers, the shorter one isless, and for negative nubmers, the longer one is less. If the signs and lengthsare the same, run down the parallel vectors from the high order end to the lowCSE-111 • Spring 2021 • Program 1 • Overloading and operators 4 of 5order end. When a difference is found, return true or false, as appropriate. Ifno difference is found, return false.(g) Implement function bigint::operator*, which uses the rule of signs to determinethe result. The number crunching is delegated to ubigint::operator*,which produces the unsigned result.(h) Multiplication in ubigint::operator* proceeds by allocating a new vectorwhose size is equal to the sum of the sizes of the other two operands. If u is avector of size m and v is a vector of size n, then in O(mn) speed, perform anouter loop over one argument and an inner loop over the other argument,adding the new partial products to the product p as you would by hand. Thealgorithm can be described mathematically as follows :p ← for i ∈ [0, m) :c ← 0for j ∈ [0, n) :d ← pi+ j + uivj + cpi+ j ← d rem 10c ← d ÷ 10pi+n ← cNote that the interval [a, b) refers to the set {x|a ≤ x < b}, i.e., to a half-openinterval including a but excluding b. In the same way,apair of iterators inC++ bound an interval.(i) Long division is complicated if done correctly. See a paper by P. BrinchHansen, ‘‘Multiple-length division revisited : A tour of the minefield’’, Software— Practice and Experience 24, (June 1994), 579–601. Algorithms 1 to 12 areon pages 13–23, Note that in Pascal, array bounds are part of the type, whichis not true for vectors in C++.multiple-length-division.pdfhttp://brinch-hansen.net/pape...http://citeseerx.ist.psu.edu/...(j) The function divide as implemented uses the ancient Egyptian division algorithm,which is slower than Hansen’s Pascal program, but is easier to understand.Replace the long values in it by vector<digit_t>. The logic is shownalso in misc/divisioncpp.cpp. The algorithm is rather slow, but the big-Oanalysis is reasonable.(k) Modify operator<<, first just to print out the number all in one line. You willneed this to debug your program. When you are finished, make it print numbersin the same way as dc(1) does.(l) The pow function uses other operations to raise a number to a power. If theexponent does not fit into a single long print an error message, otherwise dothe computation. The power function is not a member of either bigint or ubigint,and is just considered a library function that is implemented using moreprimitive operations.CSE-111 • Spring 2021 • Program 1 • Overloading and operators 5 of 5Memory leak and other problemsMake sure that you test your program completely so that it does not crash on a SegmentationFault or any other unexpected error. Since you are not using pointers,and all values are inline, there should be no memory leak. Use valgrind(1) to checkfor and eliminate uninitialized variables and memory leak.If your program is producing strange output or segmentation faults, use gdb(1) andthe debug macros in the debug module of the code/ subdirectory.Version of g++The code must compile and run using g++ on unix.ucsc.edu, regardless of whether itruns elsewhere. When this document was formatted that was :bash-$ which g++/opt/rh/devtoolset-8/root/usr/bin/g++bash-$ g++ --version | head -1g++ (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)bash-$ echo $(uname -sp) - $(hostname) - $(date)Linux x86_64 - unix6.lt.ucsc.edu - Fri Mar 26 00:01:02 PDT 2021What to submitSubmit source files and only source files : Makefile, README, and all of the headerand implementation files necessary to build the target executable. If gmake does notbuild ydc your program can not be tested and you lose 1/2 of the points for theassignment. Use checksource on your code to verify basic formatting.Look in the .score/ subdirectory for instructions to graders. Read Syllabus/pairprogramming/and also submit PARTNER if you are doing pair programming. Eitherwa y submit the README described therein.Et cetera ( ‘´).The accuracy of the Unix utility dc(1) can be checked by :echo ’82 43/25 43+65P80P82P73P76P32P70P79P79P76P10P’ | dc

May 1, 2022 · 9 min · jiezi

关于c++:CC气象数据中心实战手把手教你做工业级项目源码齐全

C/C++气象数据中心实战,手把手教你做工业级我的项目(源码齐全)超清原画 残缺无密 获取ZY:网盘链接hashCode() 和 equals()的区别equals()equals() 方法用于比较两个对象是否相等,它与 == 相等比较符有着本质的不同。 在万物皆对象的 Java 体系中,零碎把判断对象是否相等的权力交给程序员。具体的措施是把 equals() 方法写到 Object 类中,并让所有类继承 Object 类。 这样程序员就能在自定义的类中重写 equals() 方法, 从而实现自己的比较逻辑。 hashCode()hashCode() 的意义是哈希值, 哈希值是经哈希函数运算后失去的后果,哈希函数能够保障雷同的输出能够失去雷同的输入(哈希值),然而不能够保障不同的输出总是能得出不同的输入。 当输出的样本量足够大时,是会产生哈希冲突的,也就是说不同的输出产生了雷同的输入。 暂且不谈冲突,就雷同的输出能够产生雷同的输入这点而言,是及其宝贵的。它使得零碎只需要通过简略的运算,在工夫复杂度O(1)的情况下就能得出数据的映射关系,根据这种个性,散列表应运而生。 一种支流的散列表实现是:用数组作为哈希函数的输入域,输出值通过哈希函数计算后失去哈希值。而后根据哈希值,在数组种找到对应的存储单元。当发生冲突时,对应的存储单元以链表的形式保存冲突的数据。 两者关系在大多数编程实践中,归根结底会落实到数据的存取问题上。 在汇编语言期间,你需要老诚恳实地对每个数据操作编写存取语句。 而随着期间发展到明天,咱们都用更便利灵活的高级语言编写代码,比如 Java。 Java 以面向对象为中心思想,封装了一系列操作数据的 api,升高了数据操作的复杂度。 但在咱们对数据进行操作之前,首先要把数据按照肯定的数据结构保存到存储单元中,否则操作数据将无从谈起。 然而不同的数据结构有各自的个性,咱们在存储数据的时候需要抉择合适的数据结构进行存储。 Java 根据不同的数据结构提供了丰富的容器类,便利程序员抉择适合业务的容器类进行开发。 通过继承关系图咱们看到 Java 的容器类被分为 Collection 和 Map 两大类,Collection 又可能进一步分为 List 和 Set。 其中 Map 和 Set 都是不容许元素重复的,严格来说Map存储的是键值对,它不容许重复的键值。 值得注意的是:Map 和 Set 的绝大多数实现类的底层都会用到散列表结构。 讲到这里咱们提取两个关键字不容许重复和散列表结构, 回顾 hashCode() 和 equals() 的个性,你是否想到了些什么货色呢?equals()力不从心下面提到 Set 和 Map 不存放重复的元素(key),这些容器在存储元素的时必须对元素做出判断:在以后的容器中有没有和新元素雷同的元素? 你可能会想:这容易呀,间接调用元素对象的 equals() 方法进行比较不就行了吗? ...

May 1, 2022 · 1 min · jiezi

关于c#:qiao索引器

索引器(Indexer)索引器(Indexer) 容许一个对象能够像数组一样应用下标的形式来拜访。 当您为类定义一个索引器时,该类的行为就会像一个 虚构数组(virtual array) 一样。您能够应用数组拜访运算符 [ ] 来拜访该类的的成员。 语法一维索引器的语法如下: element-type this[int index]{ // get 拜访器 get { // 返回 index 指定的值 } // set 拜访器 set { // 设置 index 指定的值 }}索引器(Indexer)的用处索引器的行为的申明在某种程度上相似于属性(property)。就像属性(property),您可应用 get 和 set 拜访器来定义索引器。然而,属性返回或设置一个特定的数据成员,而索引器返回或设置对象实例的一个特定值。换句话说,它把实例数据分为更小的局部,并索引每个局部,获取或设置每个局部。 定义一个属性(property)包含提供属性名称。索引器定义的时候不带有名称,但带有 this 关键字,它指向对象实例。上面的实例演示了这个概念: 实例 using System;namespace IndexerApplication{ class IndexedNames { private string[] namelist = new string[size]; static public int size = 10; public IndexedNames() { for (int i = 0; i < size; i++) namelist[i] = "N. A."; } public string this[int index] { get { string tmp; if( index >= 0 && index <= size-1 ) { tmp = namelist[index]; } else { tmp = ""; } return ( tmp ); } set { if( index >= 0 && index <= size-1 ) { namelist[index] = value; } } } static void Main(string[] args) { IndexedNames names = new IndexedNames(); names[0] = "Zara"; names[1] = "Riz"; names[2] = "Nuha"; names[3] = "Asif"; names[4] = "Davinder"; names[5] = "Sunil"; names[6] = "Rubic"; for ( int i = 0; i < IndexedNames.size; i++ ) { Console.WriteLine(names[i]); } Console.ReadKey(); } }}当下面的代码被编译和执行时,它会产生下列后果: ...

April 30, 2022 · 1 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第5章-函数-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.在 C 语言程序中,若对函数类型未加显式阐明,则函数的隐含类型为( )。 A. void B. double C. char D. int 答:D 解析:在不返回后果的函数定义中,void 不能省略;否则,函数类型被默认定义为 int 。 2.以下正确的说法是( )。 A.实参加其对应的形参独特占用一个存储单元 B.实参加其对应的形参各占用独立的存储单元 C.只有当实参加其对应的形参同名时才占用一个独特的存储单元 D.形参是虚构的,不占用内存单元 答:B 解析:依照 C 语言的规定,在参数传递过程中,将实参的值复制给形参。所以他们各自占用独立的存储单元。 3.以下不正确的说法是( )。 A.实参能够是常量、变量或表达式 B.实参能够是任何类型 C.形参能够是常量、变量或表达式 D.形参应与对应的实参类型统一 答:B 解析:实参和形参一一对应,数量应雷同,程序应统一。实参能够是常量、变量或表达式。 4.在函数调用 Fume(exp1, exp2+exp3, exp4*exp5) 中,实参的数量是( )。 A.3 B.4 C.5 D.语法错误 答:A 解析:参数应用逗号宰割,所以题目中是3个参数。 5.下列程序的输入后果是( )。 fun(int a, int b, int c){ c = a * b;}int main(void){ int c; fun(2, 3, c); printf("%d\n", c); return 0;}A.0 ...

April 29, 2022 · 7 min · jiezi

关于c:Linux网络开发必学教程8应用协议设计与实现

问题:上面的代码输入什么?为什么?printf("connect success\n");send(sock, "A", 1, 0);send(sock, "B", 1, 0);send(sock, "C", 1, 0);close(sock);do { r = recv(client, buf, sizeof(buf), 0); if (r > 0) { printf("Recv: %s\n", buf); }}while (1);close(client);残缺代码 client.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(){ int sock = 0; struct sockaddr_in addr = {0}; int len = 0; char buf[128] = {0}; char input[32] = {0}; int r = 0; sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("socket error\n"); return -1; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(8888); if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { printf("connect error\n"); return -1; } printf("connect success\n"); send(sock, "A", 1, 0); send(sock, "B", 1, 0); send(sock, "C", 1, 0); close(sock); return 0;}残缺代码:server.c#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(){ int server = 0; struct sockaddr_in saddr = {0}; int client = 0; struct sockaddr_in caddr = {0}; socklen_t asize = 0; int len = 0; char buf[32] = {0}; int r = 0; server = socket(PF_INET, SOCK_STREAM, 0); if (server == -1) { printf("server socket error\n"); return -1; } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(8888); if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { printf("server bind error\n"); return -1; } if (listen(server, 1) == -1) { printf("server listen error\n"); return -1; } printf("server start success\n"); while (1) { asize = sizeof(caddr); client = accept(server, (struct sockaddr*)&caddr, &asize); if (client == -1) { printf("client accept error\n"); return -1; } printf("client: %d\n", client); do { r = recv(client, buf, sizeof(buf), 0); if (r > 0) { printf("Receive: %s\n", buf); } } while (r > 0); close(client); } close(server); return 0;}输入server start successclient: 4Receive: ABC小常识发送缓冲区 ...

April 29, 2022 · 3 min · jiezi

关于c:Linux网络开发必学教程7TCP-与-UDP

TCP/IP 分层构造 应用层:各个应用程序能够定义(应用)各种这样的协定传输层:确保收回的数据可能达到目标主机,实现数据传输网络层:填写数据包地址,抉择数据传输门路数据链路层:交融不同连贯形式的链路,屏蔽网络差别物理层:具体连贯形式,有线,无线,光纤...TCP/IP 工作形式 TCP/IP层次结构的特点下层依赖邻接上层的能力,上层只为间接邻接下层服务下层不晓得上层的工作机制,上层不论下层传输的数据内容不做跨层服务,层次结构中的角色缺一不可 深刻了解网络层(IP层)IP 寻址:IP 地址属于网络层地址,用于标识网络上的主机路由管制:控制数据如何达到主机(如:须要通过哪些路由器转发)无连贯:数据包依据 IP 地址在网络上传递(无需与指标主机建设连贯)Mac 地址:数据链路层所应用的硬件地址Mac 地址与网络无关,出厂时写入到网络设备中当主机从网络上每收到一个数据帧时,首先检查数据中的 MAC 地址。如果是发往本机的数据帧则收下,之后进行其余的解决;否则就将此帧抛弃,不再进行其余的解决。IP 地址和 MAC 地址IP 地址是动静的,不属于某个具体的硬件 (MAC 地址隶属于具体硬件)IP 地址是网络层应用的地址(用于跨网络投递数据包)MAC 地址是数据链路层应用的地址(用于确定指标网络中接收数据的主机)路由器中记录了本网络中主机 IP 地址与 MAC 地址的映射关系(ARP协定实现)IP 路由管制为了将数据发给指标主机,所有主机都保护着一张路由表路由表记录了 IP 数据包下一步应该发给哪个路由器 IP 数据转发IP 包转发用的是 ”尽力服务“ 策略 ”尽力服务“ 指 ”会致力“, 但不保障后果转发时会通过附加信息检查数据合法性,但出现异常不会进行重发以包为单位进行转发,不保障达到(收回之后,石沉网海)TCP/IP 网络层次结构是否能提供牢靠数据传输?传输控制协议 (Transmission Control Protocol)TCP 在协定实现上提供牢靠数据传输 TCP 不存在 ”数据包“ 的概念,实现了流式传输 (数据如流水,无头无尾)TCP 外部有服务状态,可能准确晓得数据是否曾经发送胜利,是否被接管...TCP 在行为上可进行阻塞管制(网络环境变差时,可能调整数据发送速度)TCP 连贯建设 问:三次交互完结后,建设连贯,为什么是三次?答:避免旧的反复连贯引起连贯凌乱问题比方在网络环境比较复杂的状况,客户端可能会间断发送屡次申请。如果只设计成两次握手的状况,服务端只能一接管申请,而后返回申请信息,也不晓得客户端是否申请胜利。这些过期申请的话就会造成网络连接的凌乱。所以设计成三次握手的状况,客户端在接管到服务端SEQ+1的返回音讯之后,就会晓得这个连贯是历史连贯,所以会发送报文给服务端,通知服务端。所以TCP设计成三次握手的目标就是为了防止反复连贯。而后能够设计成四次握手?五次握手?不能够?答案是也是能够的,不过为了节俭资源,三次握手就能够符合实际状况,所以就没必要设计成四次握手、五次握手等等状况 TCP 的天生缺点 (DDoS攻打)客户端收到 SYN,ACK 之后,不再回复最初的 ACK 音讯这将导致服务端耗费资源,但并不会理论进行通信当多个傀儡客户端同时对服务端进行 ”连贯申请“,服务端资源将耗尽 TCP 连贯断开 问:四次交互完结后,连贯断开,为什么是四次?答:因为TCP是全双工通信的第一次挥手:当被动方发送断开连接的申请(即FIN报文)给被动方时,仅仅代表被动方不会再发送数据报文了,但被动方仍能够接收数据报文。第二次挥手:被动方此时有可能还有相应的数据报文须要发送,因而须要先发送ACK报文,告知被动方“我晓得你想断开连接的申请了”。这样被动不便不会因为没有收到应答而持续发送断开连接的申请(即FIN报文)第三次挥手:被动方在解决完数据报文后,便发送给被动方FIN报文;这样能够保障数据通信失常牢靠地实现。发送完FIN报文后,被动方进入LAST_ACK阶段(超时期待)。第四挥手:如果被动方及时发送ACK报文进行连贯中断的确认,这时被动方就间接开释连贯,进入可用状态。 UDP 的特点:齐全继承网络层工作形式无需连贯,间接指定 IP 地址和端口即可发送数据监听固定端口,只有有数据,通通接管不论网络状况,只有有数据通通可发送不关怀数据是否达到UDP 的应用场合对数据不敏感,须要实时性的场合(如:直播,实时游戏)网络环境比拟好的场合(如:物联网家居)须要深度定制协定的场合(如:”不丢包的“UDP协定)TCP 与 UDP 的区别TCP: 瓶口到嘴上了吗?瓶口到嘴上了吗?瓶口到嘴上了吗?好,给你喝水。UDP:给你给你都给你,我懒得管你喝不喝失去。 ...

April 28, 2022 · 1 min · jiezi

关于c:Linux网络开发必学教程6Window-下的网络编程

socket 接口已普遍存在于古代操作系统中Windows 下的 socket 编程接口与 Linux 中简直雷同不同之处 返回类型不同(句柄类型)句柄不是文件描述符,Window 中并不是所有接文件 (因而 windows 下对于 socket 无奈应用 send、recv)Windows 下 socket() 的用法SOCKET s = {0};s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // IPPROTO_TCP 明确指明创立 TCP 协定的套接字if (s == INVALID) { // 创立套接字时出错,返回 INVALID_SOCKET ERROR("..."); return -1;}Windows 网络编程接口#include <winsock2.h> 函数原型性能形容SOCKET socket(int af, int type, int protocal);创立套接字,为网络连接做筹备int connect(SOCKET s, const struct sockaddr *addr, int len);连贯指定地址的近程设施int send(SOCKET s, const char *buf, int len, int flags);发送数据到近程设施int recv(SOCKET s char *buf, int len, int flags);接管近程设施发回的数据int closesocket(SOCKET s);敞开连贯,销毁套接字int bind(SOCKET s, const struct sockaddr *addr, int len);将套接字与指定地址进行关联int listen(SOCKET s, int backlog);将套接字推入监听状态,期待连贯SOCKET accept(SOCKET s, struct sockaddr *addr, int len);接管客户端连贯int shutdown(SOCKET s, int howto);敞开连贯,进行发送和接管closes 与 shutdown(Linux 下也存在) 的区别:shoutdown 不开释 socket 资源几点细微差别通过 WSAStartup() 初始化零碎环境(最先调用)socket(), accept() 谬误返回 INVALID_SOCKET (不可默认为 -1)bind(), listen() 谬误返回 SOCKET_ERROR (不可默认为 -1)connect(), send(),recv() 谬误返回 SOCKET_ERROR (不可默认为 -1)通过 WSACleanup() 革除零碎环境(最初调用)Windows 网络编程的非凡阐明在工程属性中设置链接 ws2_32.lib定义变量 WSADATA wd抉择 socket 版本并初始化 WSAStartup(MAKEWORD(2, 2), &wd) ...

April 28, 2022 · 5 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第4章-循环结构-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.以下程序段( )不能实现求 s = 1+2+...+n-1。 A. int i, n, s=0;scanf("%d", &n);for(i=1; i<n; i++){ s=s+i;}B. int i,n,s=0;scanf("%d",&n);for(i=1; i<=n-1;++i){ s=s+i;}C. int i,n, s≈0;scanf("%d", &n);for(i=n-1;i>0;i--){ s=s+i;}D. int i,n,s=0;scanf("%d",&n);for(i=n-1;i>0;++i){ s=s+i;}答:D 解析: 选项 A、B、C 的代码都能够实现题目要求。然而选项 D 的代码执行起来是个死循环,i 的值从 n-1 开始,而后++i,循环的完结条件是 i>0,i 的值越加越大,始终大于 0,条件永远成立。实现的并不是从 1 累加到 n-1。 2.输出65 14 <Enter>,以下程序段的输入后果为( )。 int m, n;scanf("%d%d", &m,&n);while(m!=n) { while(m>n) m=m-n; while(n>m) n=n-m;}printf( "m=%d\n", m);A. m=3B. m=2C. m=1D. m=0 答:C 解析: m 的初始值为 65,n 的初始值为 14。第一个while 的条件 m!=n,是成立的。执行外面的循环体。 ...

April 28, 2022 · 11 min · jiezi

关于c++:C高性能网络服务保姆级教程-day02-真正的高并发还得看IO多路复用

教程阐明C++高性能网络服务保姆级教程 首发地址day02 真正的高并发还得看IO多路复用 本节目的应用epoll实现一个高并发的服务器 从单过程讲起上节从一个根底的socket服务说起咱们实现了一个根本的socket服务器,并留了个思考题 先启动server,而后启动一个client,不输出数据,这个时候在另外一个终端上再启动一个client,并在第二个client终端中输出数据,会产生什么呢?实际操作后,咱们会发现,在第二个client输出后,服务端并没有响应,直到第一个client也输出数据实现交互后,第二个client才会有数据返回。 这是因为服务端accept获取到第一个client的套接字后,因为第一个client未输出数据,所以服务端过程会阻塞在期待客户端数据那一行。 ...int read_num = read(accept_fd, read_msg, 100);...所以,第二个client实现三次握手后,连贯始终在服务端的全连贯队列中,期待accept获取解决。 多线程,一个线程一个连贯后续的client无奈失去解决是因为服务端只有一个线程,获取client套接字还有连贯通信全在一个线程中。 那咱们间接开多个线程就好了,主线程只负责accept获取客户端套接字。每来一个连贯,咱们就新起一个线程去解决客户端和服务端的通信。这样多个连贯之间就不会相互影响了。服务端程序如下: // per_conn_per_thread_server.cpp#include <sys/socket.h>#include <netinet/in.h>#include <unistd.h>#include <thread>#include <arpa/inet.h>#include <string.h>#include <cstdio>#include <errno.h>void handleConn(int accept_fd) { char read_msg[100]; int read_num = read(accept_fd, read_msg, 100); printf("get msg from client: %s\n", read_msg); int write_num = write(accept_fd, read_msg, read_num); close(accept_fd);}int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(8888); if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { printf("bind err: %s\n", strerror(errno)); close(listen_fd); return -1; } if (listen(listen_fd, 2048) < 0) { printf("listen err: %s\n", strerror(errno)); close(listen_fd); return -1; } struct sockaddr_in client_addr; bzero(&client_addr, sizeof(struct sockaddr_in)); socklen_t client_addr_len = sizeof(client_addr); int accept_fd = 0; while((accept_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_addr_len)) > 0) { printf("get accept_fd: %d from: %s:%d\n", accept_fd, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); std::thread handleThread(handleConn, accept_fd); // 将线程设置为后盾线程,防止阻塞主线程 handleThread.detach(); }}应用thread库时,如果应用g++进行编译须要增加-lpthread,残缺编译命令: ...

April 27, 2022 · 4 min · jiezi

关于c++:C高性能网络服务保姆级教程-day01从一个基础的socket服务说起

首发地址:day01-从一个根底的socket服务说起教程阐明:C++高性能网络服务保姆级教程本节目的实现一个基于socket的echo服务端和客户端 服务端监听流程第一步:应用socket函数创立套接字在linux中,一切都是文件,所有文件都有一个int类型的编号,称为文件描述符。服务端和客户端通信实质是在各自机器上创立一个文件,称为socket(套接字),而后对该socket文件进行读写。 在 Linux 下应用 <sys/socket.h> 头文件中 socket() 函数来创立套接字 int socket(int af, int type, int protocol);af: IP地址类型; IPv4填AF_INET, IPv6填AF_INET6type: 数据传输方式, SOCK_STREAM示意流格局、面向连贯,多用于TCP。SOCK_DGRAM示意数据报格局、无连贯,多用于UDPprotocol: 传输协定, IPPROTO_TCP示意TCP。IPPTOTO_UDP示意UDP。可间接填0,会主动依据后面的两个参数主动推导协定类型#include <sys/socket.h>int sockfd = socket(AF_INET, SOCK_STREAM, 0);第二步:应用bind函数绑定套接字和监听地址socket()函数创立出套接字后,套接字中并没有任何地址信息。须要用bind()函数将套接字和监听的IP和端口绑定起来,这样当有数据到该IP和端口时,零碎才晓得须要交给绑定的套接字解决。 bind函数也在<sys/socket.h>头文件中,原型为: int bind(int sock, struct sockaddr *addr, socklen_t addrlen);sock: socket函数返回的socket描述符addr:一个sockaddr构造体变量的指针,后续会开展说。addrlen:addr的大小,间接通过sizeof失去咱们先看看socket和bind的绑定代码,上面代码中,咱们将创立的socket与ip='127.0.0.1',port=8888进行绑定: #include <sys/socket.h>#include <netinet/in.h>int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr)); //用0填充server_addr.sin_family = AF_INET; //应用IPv4地址server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址;填入INADDR_ANY示意"0.0.0.0"server_addr.sin_port = htons(8888); //端口//将套接字和IP、端口绑定bind(server_addr, (struct sockaddr*)&server_addr, sizeof(server_addr));能够看到,咱们应用sockaddr_in构造体设置要绑定的地址信息,而后再强制转换为sockaddr类型。这是为了让bind函数能适应多种协定。 struct sockaddr_in{ sa_family_t sin_family; //地址族(Address Family),也就是地址类型 uint16_t sin_port; //16位的端口号 struct in_addr sin_addr; //32位IP地址 char sin_zero[8]; //不应用,个别用0填充};struct sockaddr_in6 { sa_family_t sin6_family; //(2)地址类型,取值为AF_INET6 in_port_t sin6_port; //(2)16位端口号 uint32_t sin6_flowinfo; //(4)IPv6流信息 struct in6_addr sin6_addr; //(4)具体的IPv6地址 uint32_t sin6_scope_id; //(4)接口范畴ID};struct sockaddr{ sa_family_t sin_family; //地址族(Address Family),也就是地址类型 char sa_data[14]; //IP地址和端口号};其中,sockaddr_in是保留IPv4的构造体;sockadd_in6是保留IPv6的构造体;sockaddr是通用的构造体,通过将特定协定的构造体转换成sockaddr,以达到bind可绑定多种协定的目标。 ...

April 27, 2022 · 2 min · jiezi

关于c#:C-float浮点数与二进制相互转换IEEE754

Float32转二进制C#中浮点数的二进制格局遵循IEEE754规范(IEEE二进制浮点数算术规范)。 以小数11.25为例,float32的二进制值为:01000001001101000000000000000000 这个值是怎么来的呢?IEEE754是一个对于浮点数的规范,它把浮点数分成3个局部:Sign(符号)|Exponent(指数)|Mantissa(尾数) Sign(符号) 示意浮点数的正负(大于等于0为0,小于0为1)Exponent(指数) 示意浮点数的指数(相似迷信计数法的指数局部)Mantissa(尾数) 示意有效数字(相似迷信计数法的有效数字)以下内容简称这3局部别离为S、E、M Float32占32位,8位一字节共4字节: S(1位)|E(8位 偏移127)|M(23位) 即:0 | 1000 0010 | 01101000000000000000000S、E、M 这3局部是怎么确定的呢? 比方11.25 示意成十进制的迷信计数法: 1.125x101符号是+,指数是1,有效数字是1.125 IEEE754是先把小数转成二进制,用二进制的迷信计数法示意该小数。还是以11.25为例:S为0 (这个数字大于等于0 符号S=0,如果小于0,符号S=1)把浮点数的整数局部和小数局部别离转成二进制,再拼到一起。 整数局部转二进制: 转换方法:整数除以2取余 倒序排列(除到整数局部为0)整数局部I为11,转成二进制为:1011 $$2\sqrt{11}=5···1 \qquad\enspace \\=2···1\\=1···0\\=0···1$$ 小数局部转二进制: 转换方法:小数乘以2取整 正序排列(乘到小数局部为0,即余数为0)小数局部F为0.25,转成二进制为:01 $$0.25\times2=0···0.5 \qquad\enspace\enspace \\=1···0$$ 整数和小数拼到一起: IF = 1011.01 以二进制迷信计数法表白: IF = 1.01101x23 指数局部E: E = 3, IEEE754规定这个值要加127E = 130 转成二进制为:1000 0010整数除以2取余 倒序排列(除到整数局部为0) $$2\sqrt{130}=65···0 \qquad\enspace\enspace \\=32···1\\=16···0\\=\enspace 8···0\\=\enspace 4···0\\=\enspace 2···0\\=\enspace 1···0\\=\enspace 0···1$$ 尾数局部M: M = 101101因为二进制的迷信计数法首位肯定为1, 1能够省略不写,尾数局部就变成了01101M = 01101 S、E、M三局部拼到一起: ...

April 27, 2022 · 3 min · jiezi

关于c#:C-sizeof-计算规则

1.sizeof的作用我集体的了解:sizeof是用来获取非托管类型所占内存大小的操作符。 微软官网对sizeof的定义: sizeof 运算符返回给定类型的变量所占用的字节数。 sizeof 运算符的参数必须是一个sizeof的名称,或是一个限定为非托管类型的类型参数。 《微软官网文档》https://docs.microsoft.com/zh... 2.sizeof和Mashal.sizeof首先要说的是sizeof和Marshal.SizeOf是有差别的。 C# 中的sizeof和Marshal.SizeOf都能够用来获取非托管类型的大小,然而性能上有差异,后果也略有差别。 sizeof在失常环境下只能用于预约义的非托管类型,如int、long等等。在unsafe环境下,sizeof能够被用于值类型,然而值类型中不能够有援用类型,否则C#编译器会报错。 Marshal.SizeOf则是取得该类型被Marshal(转换,通常翻译为列集,指数据从一种类型转换到另外一种类型)到对应的非托管类型的大小。和sizeof不同,Marshal.SizeOf容许用在含有援用类型的值类型上。 参考资料:《Marshal.SizeOf和sizeof的区别》 先看输入后果: public struct Struct1 { public int Id;}public struct Struct2 { public int Id; public string Name;}// sizeof()测试 零碎内置的根本类型sizeof是固定常量值,编译器主动替换,不是通过计算失去的 不须要用unsafe 自定义的须要unsafe下计算private void SizeofTest() { Console.WriteLine(sizeof(bool)); // 1 Console.WriteLine(sizeof(byte)); // 1 Console.WriteLine(sizeof(sbyte)); // 1 Console.WriteLine(sizeof(short)); // 2 Console.WriteLine(sizeof(ushort)); // 2 Console.WriteLine(sizeof(int)); // 4 Console.WriteLine(sizeof(uint)); // 4 Console.WriteLine(sizeof(long)); // 8 Console.WriteLine(sizeof(ulong)); // 8 Console.WriteLine(sizeof(char)); // 2 Console.WriteLine(sizeof(float)); // 4 Console.WriteLine(sizeof(double)); // 8 //自定义struct unsafe { Console.WriteLine(sizeof(Struct1));// 4 //Console.WriteLine(sizeof(Struct2));// 编译器报错 无奈获取托管类型("Struct2")的地址和大小,或者申明指向他的指针 }}// Mashal.SizeOf()测试private void MarshalSizeofTest() { // using System.Runtime.InteropServices; Console.WriteLine(Marshal.SizeOf(typeof(bool))); // 4 (sizeof是1) Console.WriteLine(Marshal.SizeOf(typeof(byte))); // 1 Console.WriteLine(Marshal.SizeOf(typeof(sbyte))); // 1 Console.WriteLine(Marshal.SizeOf(typeof(short))); // 2 Console.WriteLine(Marshal.SizeOf(typeof(ushort))); // 2 Console.WriteLine(Marshal.SizeOf(typeof(int))); // 4 Console.WriteLine(Marshal.SizeOf(typeof(uint))); // 4 Console.WriteLine(Marshal.SizeOf(typeof(long))); // 8 Console.WriteLine(Marshal.SizeOf(typeof(ulong))); // 8 Console.WriteLine(Marshal.SizeOf(typeof(char))); // 1 (sizeof是2) Console.WriteLine(Marshal.SizeOf(typeof(float))); // 4 Console.WriteLine(Marshal.SizeOf(typeof(double))); // 8 // 自定义struct Console.WriteLine(Marshal.SizeOf(typeof(Struct1)));// 4 Console.WriteLine(Marshal.SizeOf(typeof(Struct2)));// 8} 3.sizeof大小的计算在计算之前,请看下面SizeofTest()办法内的输入后果,记住根本数据类型的大小,用来计算。 ...

April 27, 2022 · 5 min · jiezi

关于c:Linux网络开发必学教程5基于多路复用的服务端

问题:应用 select() 函数能够扩大服务端性能吗? 如果能够,具体怎么实现? 目前服务端的瓶颈剖析服务端大多数时候处于期待状态,无奈施展主机(设施)的最大性能 while (1) { // 阻塞,期待客户端连贯 client = accept(server, (struct sockaddr*)&caddr, &asize); printf("client: %d\n", client); do { // 阻塞,期待客户端数据 r = recv(client, buf, sizeof(buf), 0); if (r > 0) { printf("Receive: %s\n", buf); if (strcmp(buf, "quit") != 0) { len = send(client, buf, r, 0); } else { break; } } } while (r > 0); close(client);}解决方案:阻塞变轮询通过 select() 函数首先监听服务端 server_fd, 指标事件为 “连贯”(读)当事件产生(客户端连贯),则调用 accept() 承受连贯将 client_fd 退出监听范畴,指标事件为“数据接管”(读)循环查看各个被监听的文件描述符是否有事件产生实现形式 ...

April 27, 2022 · 3 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第3章-分支结构-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.有一函数 $$y = \begin{cases}1 & (x \gt 0) \\ 0 & (1 = 0) \\-1 & (x \lt 0)\end{cases}$$ 以下程序段中谬误的是( )。 A. if(x>0)y=1;else if(x==0)y≈0;else y=-1;B. y=0;if(x>0)y=1;else if(x<0)y=-1;C. y=0;if(x>=0);if(x>0)y=1;else y=-1;D. if(x>=0) if(x>0)y=1; else y=0;else y=-1;答:C 解析:依据函数, x 大于 0 ,y 的值为 1 。x 等于 0,y 的值为 0,x 小于 0,y 的值为 -1。选项 A,B,D 代码均正确。 2.对于变量定义: inta, b=0; 下列叙述中正确的是( )。A. a 的初始值是 0,b 的初始值不确定B. a 的初始值不确定,b 的初始值是 0C. a 和 b 的初始值都是 0D.a 和 b 的初始值都不确定 ...

April 27, 2022 · 6 min · jiezi

关于c:Linux网络开发必学教程4尝鲜-seclect-多路复用

问题:如何加强服务端能力,同时反对多个客户端?Linux 的设计哲学:所有皆文件 Linux 中的文件是什么?侠义: 文件系统中物理意义上的文件(逻辑上关联的数据汇合)狭义: 设施,通道,内存,。。。Linux 治理的所有对象了解文件描述符文件描述符是一个非负整数,实质是一个句柄所有对用户(程序员)通明的资源标识都能够看作句柄用户应用文件描述符(句柄)与内核交互内核通过文件描述符操作对应资源的数据结构所有皆文件的意义对立各种设施的操作形式(open,read,write,close)如: IO 设施(命令行,显示器)网络设备(网卡)...编程试验:以文件形式操作命令行#include <stdio.h>#include <unistd.h>int main(){ int iofd = 0; char s[] = "D.T.SoftWare\n"; int len = 0; write(iofd, s, sizeof(s)); len = read(0, s, 5); s[len] = 0; printf("%s\n", s); return 0;}输入: book@100ask:~/Desktop$ ./a.out D.T.SoftWare1234512345book@100ask:~/Desktop$ ...book@100ask:~/Desktop$ ./a.out D.T.SoftWare1234567812345 // 留神这里为什么只输入了 12345book@100ask:~/Desktop$ 678 // 留神这里为什么输入 678678: command not found答:在 a.out 应用程序中输出了"12345678",但应用程序只读取了 5 个字符,即"12345"。当应用程序完结,a.out所在终端获得所有权,失去 "678", 并尝试将其当作命令解析事件相干函数的分类阻塞式函数 函数调用后须要期待某个事件产生后才会返回非阻塞式函数 函数调用后可能及时返回(仅标记期待的事件)事件产生后以回调形式传递阻塞 VS 轮询轮询指依序拜访每一个相干设施是否须要服务的形式轮询可用于解决阻塞函数导致程序无奈继续执行的问题 神奇的 select() 函数select() 用于监督指定的文件符是否产生事件可通过轮询的形式检测指标文件(事件产生则标记发生变化)依据事件类型做出具体解决(如:读数据)int select(int maxfd, // maxfd = n(最大的文件描述符 ) + 1,标记监听的描述符范畴 [0 - maxfd-1] fd_set *readset, // 查看可读性 fd_set *writeset, // 查看可写性 fd_set *exceptset, // 查看异样 const struct timeval *timeout); // 期待 IO 的时长select() 函数的应用步骤 ...

April 26, 2022 · 2 min · jiezi

关于c:浙大版C语言程序设计何钦铭颜晖-第2章-用C语言编写程序-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 一、选择题 1.改过下列程序中( )处谬误后,程序的运行后果是在屏幕上显示短句“ Welcome to You!"。 #include <stdio.h>int main(void){ printf(Welcome to You! \n") return 0;}A.1 B.2 C.3 D.4 答案:B 解析: printf() 函数是零碎提供的库函数,在系统文件stdio.h中申明。 printf() 函数的格局为: printf(格局管制字符串,输入参数1,...,输入参数n);所以,printf里的字符串要加双引号。 printf语句开端要以分号完结。 2.C语言表达式( )的值不等于1。 A. 123 / 100 B. 901%10 C.76%3 D.625%5 答案:D 解析: 选项A:123/100 的后果是 1 。123 除以 100,商 1 余 23 ,这里取商。 选项B:901%10 的后果是 1 。901除以10,商 90 余 1 ,这里取余数。 选项C:76%3 的后果是 1 。76 除以 3 ,商 25 余 1,这里取余数。 选项D:625%5 的后果是 0 。625 除以 5 ,商 125 余 0 ,这里取余数。 ...

April 26, 2022 · 5 min · jiezi

关于c:Linux网络开发必学教程3深入浅出-IP-地址

问题:网络编程接口中一些参数的意义是什么?sock = socket(PF_INET, SOCK_STREAM, 0);socket 参数详解int socket(int domain, int type, int protocal);参数意义domain套接字中应用的协定族信息type套接字数据传输类型信息prorocol设施间通信应用的协定信息socket() 中的 domain 参数(协定族)PF_INET → IPv4 互联网协议族PF_INET6 → IPv6 互联网协议族PF_LOCAL → 本地通信的协定族PF_PACKET → 底层数据收发协定PF_IPX → Novell 专用协定(互联网分组替换协定)...留神:不同协定中的地址表现形式可能不同,网络编程时地址类型必须和协定类型匹配socket() 中的 type 和 protocol 参数type : 用于指定协定类型 SOCK_STREAM : 流式数据 (TCP)SOCK_UGRAM : 报文式数据(UDP)protocol :用于指定协定族合乎类型的具体协定 domain 和 type 简直能够惟一确定一种协定,因而,这个参数通常为 0即:0 代表 domain 和 type 指定后的默认协定对于端口号和 IP 地址端口号是一个 2 字节数据(无符号)0 - 1024 作为特定端口被预约义(调配给特定应用程序)IP 地址是一个 4 字节无符号地址族 (可分为 5 类地址) 深刻解析 IP 地址IP 地址分为 网络标识 和 主机标识 两局部网络标识:标识网络主机(设施)所在的网络主机标识:标识网络主机(设施)的具体地址 ...

April 25, 2022 · 2 min · jiezi

关于c++:c面经

语法层面static关键字的作用有哪些(润饰全局变量、润饰局部变量、润饰类的成员函数和数据成员)(扩大:name的两个独立的性质:存储周期storage duration 和 链接性 linkage)const关键字(润饰类型、润饰成员函数、润饰指针)语义层面指针和援用的区别是什么?c++11退出的右值援用、挪动语义、完满转发的含意内存相干2.1 new和malloc的区别,new做了什么new operator、operator new、placement new三者的作用和区别2.2 c++11内存治理,智能指针(shared_ptr、unique_ptr、enable_shared_from_this、weak_ptr)2.3 程序的内存调配(和操作系统联合起来)stl相干2.1 vectorpush_back的工夫复杂度(均摊剖析)push_back的强异样平安保障迭代器生效问题扩容问题2.2 map、set 红黑树2.3 unordered_map 哈希表基于对象初始化列表(必须应用:const成员、援用类型)成员函数(const、virtual、pure vritual)几个特地的成员函数(默认结构、拷贝、挪动、析构)面向对象封装:访问控制关键字继承:虚函数重写、override多态:虚函数机制、类型转换操作符重载、重写、暗藏的区别 多线程锁、条件变量、线程、原子变量友元相干friend

April 25, 2022 · 1 min · jiezi

关于c:Linux网络开发必学教程2服务端编程初体验

客户端/服务端 编程模式服务端长期保留于网络(公开本人的 IP 地址),并期待客户端连贯客户端发动连贯动作,并期待服务端回应特点: 服务端无奈被动连贯客户端客户端只能依照预约义的形式(协定)连贯服务端服务端编程模式1. 筹备网络连接2. 绑定端口3. 进入端口监听状态4. 期待连贯 服务端外围工作:绑定 & 监听 & 接管绑定:int bind(int sock, struct sockaddr *addr, socklen_t addrlen);监听:int listen(int sock, int backlog);接管:int accept(int sock, struct sockaddr *addr, socklen_t addrlen);深度分析服务端服务端 socket 只用于接管连贯,不进行理论通信当接管到连贯时,accept() 函数返回与客户端通信的 socket服务端 socket 产生用于通信的客户端 socket所以,socket 到底是什么玩意?如何了解?深刻了解 socket() 函数socket() 是什么? socket() 是一个多功能函数socket() 返回的又是什么? socket() 的返回值是用于通信的资源标识符socket() 还能做什么? socket() 可提供不同类型的通信性能(本地过程间通信)编程试验:服务端编程初体验#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(){ int server = 0; struct sockaddr_in saddr = {0}; int clinet = 0; struct sockaddr_in caddr = {0}; socklen_t asize = 0; int len = 0; char buf[32] = {0}; int r = 0; server = socket(PF_INET, SOCK_STREAM, 0); if (server == -1) { printf("server socket error\n"); return -1; } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(8899); if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { printf("server bind error\n"); return -1; } if (listen(server, 1) == -1) { printf("server listen error\n"); return -1; } printf("server start success\n"); asize = sizeof(caddr); clinet = accept(server, (struct sockaddr*)&caddr, &asize); if (clinet == -1) { printf("client accept error\n"); return -1; } printf("client: %d\n", clinet); len = 0; do { int i = 0; r = recv(clinet, buf, sizeof(buf), 0); if (r > 0) { len += r; } for (i=0; i<r; ++i) { printf("%c", buf[i]); } } while (len < 64); printf("\n"); send(clinet, "hello word!", 12, 0); sleep(1); close(clinet); close(server); return 0;}INADDR_ANY => "0.0.0.0", 示意本机的连贯全副承受(如,本机有多个网卡进而有多个 IP 时)客户端/服务端 编程的外围模式服务端长时间运行(死循环)接管客户端的申请客户端连贯后向服务端发送申请(协定数据) ...

April 25, 2022 · 3 min · jiezi

关于c++:C-可变变量格式化字符串

一:格式化字符串#include <stdarg.h>...void ownLog(const char *fmt, ...){ va_list arglist; va_start(arglist, fmt); vprintf(fmt,arglist); { char log[1024];//格式化字符后存储的数组 vsprintf(log,fmt,arglist); } va_end(arglist);}main(){ ownLog("init data time(%d)",123);}在va_start到va_end之间能够获取到指定的数据 二、获取数据void ownLog(int count, ...){}

April 25, 2022 · 1 min · jiezi

关于c:浙大版C语言程序设计第四版何钦铭颜晖-第1章-引言-课后习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 题目1:对C语言来说,下列标示符中哪些是非法的,哪些是不非法的? total,_debug, Large&Tall, Counter1, begin_答: 非法的: total、_debug、 Counter1、 begin_ 。不非法的: Large&Tall。解析: 一、什么是标识符?在 C 语言中,用来示意变量,函数,数据类型,语句等等这些,所应用的符号,就被称作标识符。 二、C 语言中对标识符的规定:1、C 语言的标识符,必须由字母,数字,下划线组成,其中第一个字符必须是字母或者下划线。 2、在 C 语言中,是辨别大小写的。 三、在 C 语言中,最次要的标识符是保留字和用户自定义的标识符。 1、保留字,也叫做关键字,是 C 语言规定的,并且有特定含意 和 有专门用处的标识符。 次要与和数据类型和语句无关。 2、用户自定义标识符。 就是用户本人定义的,个别用于变量名,数据类型名,函数名,符号常量名等等。 题目2: 改写 1.4 节中的流程图 1.2, 求 1一100 中能被 6 整除的所有整数的和。 <img src="https://img.chengxuka.com/WX20220401-163018@2x.png" alt="WX20220401-163018@2x" style="zoom:50%;" /> 解析: 对于 1.4 节中的流程图 1.2,是求 1-100 偶数和。流程图如下: <img src="https://img.chengxuka.com/WX20220421-152331@2x.png" style="zoom:50%;" /> 其实两道题的流程思路差不多。 题目3:改写 1.4 节中的程序,求 1-100 中能被 6 整除的所有整数的和,并在编程环境中验证该程序的运行后果。 解: 答案代码: #include <stdio.h>int main(void){ int i, sum = 0; for (i = 1; i <= 100; i++) if (i % 6 == 0) sum = sum + i; printf("sum=%d\n", sum); return 0;}运行后果: ...

April 25, 2022 · 1 min · jiezi

关于c:Linux网络开发必学教程1网络编程核心概念与模式

问题:如何进行网络编程?网络编程的实质应用操作系统提供的接口函数,使得应用程序具备收发网络数据的能力 网络接口在代码层面是操作系统提供的函数 网络编程只是一系列零碎函数的花式玩法应用程序通过网络接口应用操作系统的联网能力 网络编程是特定畛域(网络)的 C 语言程序设计协定:为进行数据通讯而预约义的数据规定地址:网络通讯中的用于标识设施的整数值(“xxx.xxx.xxx.xxx” 4字节整形值可示意,单为了更容易记忆,转换为字符串)端口号 设施为收发数据而指定的数值,用于示意具体连贯可了解为:设施中用于网络通讯的数据通道如:一台电脑往往只领有一个 IP 而又有多个应用程序,此时就应用端口进行辨别角色 服务端:期待连贯设施客户端:发动连贯的是恶被 ps : 一台设施可同时作为客户端和服务端 网络常识充电站网址就是 IP 地址吗? URL 是什么,域名又是什么? 网址不是 IP 地址,是指网络信息资源的地址(如:具体网页的地址),即:URL域名是 IP 地址的名别,多个域名能够指向同一个 IP 地址域名 → DNS → IP 地址协定肯定是看不懂的二进制数据吗? 协定是一种约定,即:事后定义的规定协定能够基于文本定义,也能够基于二进制定义小端系统:采纳小端模式(little-endian)的零碎,即:数据低字节放在内存低地址中0x12345678 int 4字节低地址 |78|56|34|12| 高地址 大端系统:采纳大端模式(big-endian)的零碎,即:数据低字节放在内存高地址中0x12345678 int 4字节低地址 |12|34|56|78| 高地址 网络字节序:网址字节程序采纳大端模式,所以,在小端系统中须要做字节转换网络编程模式1. 筹备连贯2. 连贯近程设施3. 收发数据4. 敞开丽娜姐 初探网络编程接口#include <sts/types.h>#include <sys/socket.h> 函数原型性能形容int socket(int domain, int type, int protocal);创立套接字,为网络连接做筹备int connect(int socket, struct sockaddr *addr, socklen_t len);连贯指定地址的近程设施ssize_t send(int fd, const void *buf, size_t n, int flags);发送数据到近程设施ssize_t recv(int fd, void *buf, size_t n, int flags);接管近程设施发回的数据int close(int fd);敞开连贯,销毁套接字编程试验:网络编程初体验#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(void){ int sock = 0; struct sockaddr_in addr = {0}; char *tosend = "GET /index.html HTTP/1.1\nHOST: www.dt4sw.com\nUser-Agent: TEST\nConnection: close\n\n"; int len = 0; char buf[128] = {0}; int r = 0; sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("socket error\n"); return -1; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("47.99.217.175"); addr.sin_port = htons(80); if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { printf("connected error\n"); return -1; } printf("connect success\n"); len = send(sock, tosend, strlen(tosend), 0); printf("send bytes = %d\n", len); len = 0; do { int i = 0; r = recv(sock, buf, sizeof(buf), 0); if (r > 0) { len += r; } for (i=0; i<r; ++i) { printf("%c", buf[i]); } } while (r > 0); printf("\n"); printf("recv bytes = %d\n", len); return 0;}输入: ...

April 24, 2022 · 2 min · jiezi

关于c++:OneFlow-学习笔记从-Python-到-C-调用过程分析

撰文|月踏 在 OneFlow 中,从 Python 端咱们能够应用各种 Op 进行相干操作,上面是一个最最简略的 relu op 的应用示例: >>> import oneflow as of>>> x=of.tensor([-3,-2,-1,0,1,2,3], dtype=of.float)>>> of.relu(x)tensor([0., 0., 0., 0., 1., 2., 3.], dtype=oneflow.float32)尽管调用在 Python 端,但具体的实现是在 C++端,那么 OneFlow 是怎么样一步步从 Python 端调到 C++中的呢,本文以最最简略的 Relu 这个 Op 作为例子,来追溯一下在 OneFlow 中从 Python 端到 C++中的大抵调用过程,具体过程大略总结为 Python wrapper 和 C++ glue functor 两局部,上面是两局部的具体细节。 1 Python wrapperPython 的代码都在 python/oneflow 文件夹中,在剖析 Python wrapper 的过程中,也会波及很多 C++代码,次要是和 pybind11 绑定相干的,也一并归类到 Python wrapper 这部分了。 先看本文结尾示例中的 relu 接口的间接起源,在 python/oneflow/__init__.py 中能够找到上面这一行:from oneflow._C import relu能够看到 relu 是从_C 这个 module 中导出来的,所以持续看 oneflow/_C/__init__.py 这个文件: ...

April 24, 2022 · 3 min · jiezi

关于c:c-语言-struct的内存对齐原则

如何计算得悉struct内存大小,这就要从内存对齐准则说起: 内存对齐第一准则构造体中元素是依照定义程序一个个放到内存中去的,但并不是严密排列的.每一个元素都认为内存是以它本人的大小来划分的,因而元素搁置地位肯定是元素内存宽度的整数倍上开始(从构造体首地址上向后找,找到第一个闲暇的残缺内存) struct X { char a; //[0] int b;//[4,7] double c;//[8,15]} S1;例如此例,a存入内存首地址第0个字节 存入b时,它先从构造体首地址查找,发现第一个4字节的空间被a占了一个,于是找下一个四字节空间,从第4个字节开始写入,到第7个字节完结. 存入c时,它先从构造体首地址以字节的大小查找,发现第一个8字节的空间被a、b占用,于是找一个8字节空间,于是从8字节写入到15字节完结 内存对齐第二准则构造体占用内存大小,满足内存大小必须为占用最大内存元素的内存大小的整数倍 struct X { char a; //[0] double b; //[8,15] int c;//[16,20]}S2;计算sizeof(S2)得24这是为什么呢,明明是只有20字节,这阐明必须满足最大元素的整数倍,所以留了最初4个字节是空白 留神:如果构造体里是个复合构造,比如说数组,那么会以数组元素内存宽度来做内存排布,如: struct label { int l_flags; union { void *l_ptr; long l_long; } l_perpolicy[N];};l_perpolicy是一个占用8*N内存大小的数组,那么在构造体label的内存排布是这样的,首先排l_flags,写入0~3内存空间,其次写入l_perpolicy的第一个元素,从构造体找第一个8字节空间发现写入了l_flags,于是向后找第二个8字节空间,也就是8~15写入数组的第一个元素,其余元素以此类推

April 24, 2022 · 1 min · jiezi

关于c++:C变量及方法命名

为了防止和C++保留字或者STL抵触,应尽量避免应用以下变量或办法命名,并应用: min -> mnmax -> mxsize -> szlength -> len(Python程序员可能感到不习惯)union -> merge(在并查集算法中)stack -> stkqueue -> que其余倡议应用的的常见命名还包含: ans(answer)res(result)cntsummididxflagst(state)dist(distance)

April 24, 2022 · 1 min · jiezi

关于c:C语言程序设计谭浩强第五版-第10章-对文件的输入输出-习题答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 题目1:什么是文件型指针?通过文件指针拜访文件有什么益处? 答: 缓冲文件系统中,要害的概念是“文件类型指针”,简称“文件指针”。每个被应用的文件都在内存中开拓一个相应的文件信息区,用来寄存文件的无关信息(如文件的名字、文件状态及文件以后地位等)。这些信息是保留在一个构造体变量中的。该构造体类型是由零碎申明的,取名为FILE。所以,在C语言上,文件型指针就是指FILE类型的指针,它指向一个文件类型的构造,构造里蕴含着该文件的各种属性。 通过文件指针拜访文件的益处是:能够随机拜访文件,无效示意数据结构,动静分配内存,方便使用字符串,无效应用数组。 题目2:对文件的关上与敞开的含意是什么?为什么要关上和敞开文件? 答: 关上文件,是建设文件的各种相干信息,并使文件类型指针指向该文件,以便进行其它操作。而敞开文件操作可强制把缓冲区中的数据写入磁盘文件,保障文件的完整性,同时还将开释文件缓冲区单元和FILE构造,使文件类型指针与具体文件脱钩。 要对一个文件进行操作,必须先将其关上,读写结束后还要将其敞开,以避免不失常的操作。 ”关上“是指为文件建设相应的信息区(用来寄存无关文件的信息)和文件缓冲区(用来临时寄存输入的数据)。 ”敞开“是指撤销文件信息区和文件缓冲区,使文件指针变量不再指向该文件,显然就无奈进行对文件的读写了。 题目3:从键盘输入一个字符串,将其中的小写字母全副转换成大写字母,而后输入到一个磁盘文件 test中保留,输出的字符串以"!"完结。 解: 答案代码: #include <stdio.h>#include <string.h>#include <stdlib.h>int main(){ FILE *fp; char str[100]; int i = 0; if ((fp = fopen("test.txt", "w")) == NULL) { printf("can not open file\n"); exit(0); } printf("input a string:\n"); gets(str); while (str[i] != '!') { if (str[i] >= 'a' && str[i] <= 'z') str[i] = str[i] - 32; fputc(str[i], fp); i++; } fclose(fp); fp = fopen("test.txt", "r"); fgets(str, strlen(str) + 1, fp); printf("%s\n", str); fclose(fp); return 0;}运行后果: ...

April 24, 2022 · 9 min · jiezi

关于c:Linux网络开发必学教程0课程定位目标与安排

课前第一问:为什么要学习网络编程?实际必备技能:学完 C 语言之后想做点我的项目练手,能够吗?职业必备技能:招聘的任职技能时代必备技能 简直所有操作系统都反对网络性能简直所有 app 都须要联网能力工作互联网工夫 → 挪动互联网时代 → 物联网时代人工智能典型落地计划:云边协同推理...课程布局 课程学习路线 课程定位Linux 下的 socket 网络编程 问:只是 Linux 下的网络编程吗?答:也会在 Window 下进行试验把握根本的网络编程模式 问:学习网络编程须要先把握网络原理吗?答:不须要,课程中也不会做特地的解说课程目标以 Linux 零碎为次要平台,从 0 把握 socket 网络编程 把握网协定的实质以及 socket 的实质把握网络编程根底模型,如:C/S把握 TCP 和 UDP 网络编程不同平台网络编程实际...课程安顿socket 接口与 TCP 和 UDP 编程(数据收发)通信协定设计与实现案例开发:基于硬件平台的温湿度检测案例开发:HTTP服务器设计与实现Linux 系列课程初步布局Linux 网络编程(根底 & 进阶)Linux 文件编程(C 接口编程 & 零碎接口编程)Linux 多任务编程 (多过程 & 多线程)Linux 过程间通信...新篇章已开启,筹备好了吗?

April 24, 2022 · 1 min · jiezi

关于c#:async-void-导致程序崩溃

起源:https://note.guoqianfan.com/2...前言之前都是在文档里看到:除了winform的事件能够应用async void,其余状况下相对不能应用async void,而是要用async Task。 对于这个标准,尽管不是很明确内里起因,然而始终恪守着。 直到这天看到了这篇博客:在 ASP.NET Core 中誤用 async void 竟引發了 502(Bad Gateway),说async void里出现异常时会导致程序解体。钻研测试了一番,终于明确起因。 摘录重点如下: 根據使用者提供的另一個線索「網站的某個性能壞了」,我們繼續往下追究,從程式碼當中我看到了一個近期新加的办法,它应用了 async void,沒錯,它应用了 async void,而且很可怜地它會發生 Exception,更慘的是這個 Exception 沒有被處理。 對 C# 非同步程式設計有理解的敌人,看到這邊應該大抵上能够晓得是發什麼問題了,async void 是建議應該防止应用的宣告形式,其中一個起因就是當 async void 办法發生 Exception 時無法從呼叫端捕獲,即便加了 try...catch... 也沒用,async void 办法就有點像是我們本人起了另一個 Thread 去執行程式一樣,執行的過程中如果發生 Exception 沒有去處理,Exception 就會一路被往上拋,最終在 AppDomain 層級被捕獲,然後我們的應用程式就掛了。 async-void-办法的异样无奈被捕捉async void办法抛出的异样无奈被捕捉,异样会被始终往上面抛,最终在AppDomain层级被捕捉,而后程序就挂了。 示例代码如下: [HttpGet]public async void Get(){ try { ThrowExceptionAsync(); } catch (Exception ex) { //这里不能捕捉到异样,程序解体! _logger.LogInformation(ex, "ex..."); }}async void ThrowExceptionAsync(){ throw new Exception("async void ex!");}留神后面所说的是 async void办法抛出的无奈预知到的异样。在async void办法外部,咱们依然可能应用try catch,逻辑是失常逻辑。具体见上面的示例: ...

April 23, 2022 · 1 min · jiezi

关于c#:C中的类型转换自定义隐式转换和显式转换

起源:https://note.guoqianfan.com/2...前言有时咱们会遇到这么一种状况:在json数据里,数组里的数据类型不统一,导致咱们不能间接反序列化为指标类型。最终咱们只能反序列化为JObject类型,而后通过字符串取值的形式来取出数据。 上面介绍一种新形式:通过自定义隐式转换,把不一样的数据类型反序列化为一样的数据类型。 基础知识类型转换有2种:隐式转换和显式转换。然而,不论是隐式转换,还是显式转换,都是生成了一个新对象返回的。扭转新对象的属性,不会影响老对象!(dynamic对象除外,详情搜寻dynamic动静类型。) 自定义隐式/显式转换的办法须要用到几个关键字:implicit(隐式转换)、explicit(显式转换)、operator(操作符)。更多的留神点见下: 办法必須是static应用implicit或explicit搭配operator(此也是c#關鍵字,可在類別或結構宣告內多載內建運算子或提供使用者定義的轉換)返回值为要转换为的指标类型,但不要在办法上申明,办法名为指标类型。留神:返回值不肯定是本类类型。本类型和其余类型之间能够相互转换,只有定义转换方法就行。参数为原始类型,办法名为指标类型类A到类B的类型转换定义不能在类C中进行(即2个类的转换不能在第3个类中定义),否则会报错:用户定义的转换必须是转换成关闭类型,或者从关闭类型转换。具体查看前面的用户定义的转换必须是转换成关闭类型,或者从关闭类型转换不能被virtual/override润饰(不能“笼罩”运算符,因为它们是动态的。)Overriding implicit operators in C#示例代码//================定义类型和办法================class Robot{ public int Id { get; set; } public string Name { get; set; } public Robot(int id, string name) { Id = id; Name = name; } #region 其余类型->本类 //隐式转换 public static implicit operator Robot(string name) { return new Robot(101, name); } //显式转换 public static explicit operator Robot(int id) { return new Robot(id, "miku"); } #endregion #region 本类->其余类型 //隐式转换 public static implicit operator string(Robot robot) { return robot.Name; } //显式转换 public static explicit operator int(Robot robot) { return robot.Id; } #endregion}//================测试代码================#region 其余类型->本类string gumiStr = "gumi";Robot gumi001 = gumiStr; //隐式转换Console.WriteLine("隐式转换:gumi001 : {0}", JsonConvert.SerializeObject(gumi001));int lukaId = 1004;Robot luka001 = (Robot)lukaId; //显式转换Console.WriteLine("显式转换:luka001 : {0}", JsonConvert.SerializeObject(luka001));#endregion#region 其余类型->本类Robot miku001 = new Robot(1001, "miku10001");//隐式转换string mikuName = miku001;//显式转换int mikuId = (int)miku001;Console.WriteLine("隐式转换:miku001 Name: {0}", mikuName);Console.WriteLine("显式转换:miku001 Id: {0}", mikuId);#endregion输入后果如下: ...

April 22, 2022 · 2 min · jiezi

关于c:C语言程序设计谭浩强第五版-第9章-用户自己建立数据类型-习题解析与答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 题目1:定义一个构造体变量(包含年、月、日)。计算该日在本年中是第几天,留神平年问题。 解: 解题思路为:失常年份每个月中的天数是已知的,只有给出日期,算出该日在本年中是第几天是不艰难的。如果是平年且月份在 3 月或 3 月当前时,应再减少 1 天。平年的规定是:年份能被 4 或 400 整除但不能被 100 整除,例如,2000 年是平年,2100 年不是平年。 解法一: #include <stdio.h>struct{ int year; int month; int day;} date; //构造体变量 date中的成员对应于年、月、日int main(){ int days; // days 为天数 printf("input year,month,day:"); scanf("%d,%d,%d", &date.year, &date.month, &date.day); switch (date.month) { case 1: days = date.day; break; case 2: days = date.day + 31; break; case 3: days = date.day + 59; break; case 4: days = date.day + 90; break; case 5: days = date.day + 120; break; case 6: days = date.day + 151; break; case 7: days = date.day + 181; break; case 8: days = date.day + 212; break; case 9: days = date.day + 243; break; case 10: days = date.day + 273; break; case 11: days = date.day + 304; break; case 12: days = date.day + 334; break; } if ((date.year % 4 == 0 && date.year % 100 != 0 || date.year % 400 == 0) && date.month >= 3) days += 1; printf("%d/%d is the%dth day in %d.\n", date.month, date.day, days, date.year); return 0;}运行后果: ...

April 22, 2022 · 16 min · jiezi

关于c:C语言程序设计谭浩强第五版-第8章-善于利用指针-习题解析与答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 本章习题均要求用指针办法解决。 题目1:输出3个整数,按由小到大的程序输入。 解: 答案代码: #include <stdio.h>int main(){ void swap(int *p1, int *p2); int n1, n2, n3; int *p1, *p2, *p3; printf("input three integer n1,n2,n3:"); scanf("%d,%d,%d", &n1, &n2, &n3); p1 = &n1; p2 = &n2; p3 = &n3; if (n1 > n2) swap(p1, p2); if (n1 > n3) swap(p1, p3); if (n2 > n3) swap(p2, p3); printf("Now,the order is:%d,%d,%d\n", n1, n2, n3); return 0;}void swap(int *p1, int *p2){ int p; p = *p1; *p1 = *p2; *p2 = p;}运行后果: ...

April 21, 2022 · 20 min · jiezi

关于c#:6-堪比JMeter的Net压测工具-Crank-实战篇-收集诊断跟踪信息与如何分析瓶颈

1. 前言下面咱们曾经做到了接口以及场景压测,通过控制台输入后果,咱们只须要将后果收集整理下来,最初汇总到excel上,此次压测报告就能够实现了,但收集报告也挺麻烦的,交给谁呢…… 找了一圈、没找到违心接手的人,该怎么办呢……思考了会儿还是决定看看是否通过程序解决咱们的难题吧,毕竟整顿表格太累╯﹏╰ 2. 收集后果通过查阅官网文档,咱们发现官网提供了把数据保留成Json、csv、以及数据库三种形式,甚至还有小伙伴踊跃的对接要把数据保留到Es中,那选个最简略的吧! 要不抉择Json吧,不须要依赖内部存储,很简略,我感觉应该可试,试一下看看:输出命令: crank --config load.benchmarks.yml --scenario api --load.framework net5.0 --application.framework net5.0 --json 1.json --profile local --profile crankAgent1 --description "wrk2-获取用户详情" --profile defaultParamLocal最初失去后果: { "returnCode": 0, "jobResults": { "jobs": { "load": { "results": { "http/firstrequest": 85.0, "wrk2/latency/mean": 1.81, "wrk2/latency/max": 1.81, "wrk2/requests": 2.0, "wrk2/errors/badresponses": 0.0, "wrk2/errors/socketerrors": 0.0, "wrk2/latency/50": 1.81, "wrk2/latency/distribution": [ [ { "latency_us": 1.812, "count": 1.0, "percentile": 0.0 }, { "latency_us": 1.812, "count": 1.0, "percentile": 1.0 } ] ] } } } }}残缺的导出后果好吧,数据有点少,如同数据不太够吧,这些信息怎么解决能做成报表呢,再说了数据不对吧,QPS、提早呢?好吧,被看进去了,因为信息太多,我删了一点点(也就1000多行指标信息吧),看来这个不行,用json的话还得配合个程序好难…… ...

April 20, 2022 · 2 min · jiezi

关于c:C语言程序设计谭浩强第五版-第7章-用函数实现模块化程序设计-习题解析与答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 题目1:写两个函数,别离求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输入后果。两个整数由键盘输入。 解:设两个整数为 u 和 v,用辗转相除法求最大公约数的算法如下∶ ifv>u将变量 u与v的值调换 (使大者u为被除数) while(u/v的余数 r≠0){ u=v (使除数v变为被除数 u) v=r (使余数r变为除数 v)}输入最大公约数 r 最小公倍数1= u* v/最大公约数r 能够别离用以下两种办法∶
办法一:用两个函数 hcf 和 lcd 别离求最大公约数和最小公倍数。在主函数中输出两个整数 u 和 v,并传送给函数 hcf,求出的最大公约数返回主函数赋给整型变量 h,而后再把 h 和两个整数 u ,v 一起作为实参传递给函数 lcd,以求出最小公倍数,返回到主函数赋给整型变量 l。输入最大公约数和最小公倍数。
据此写出程序: #include <stdio.h>int main(){ int hef(int, int); //函数申明 int lcd(int, int, int); //函数申明 int u, v, h, l; scanf("%d,%d", &u, &v); h = hef(u, v); printf("H.C.F=%d\n", h); l = lcd(u, v, h); printf("L.C.D=%d\n", l); return 0;}int hef(int u, int v){ int t, r; if (v > u) { t = u; u = v; v = t; } while ((r = u % v) != 0) { u = v; v = r; } return (v);}int lcd(int u, int v, int h){ return (u * v / h);}运行后果: ...

April 20, 2022 · 13 min · jiezi

关于c:C语言程序设计谭浩强第五版-第6章-利用数组处理批量数据-习题解析与答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 题目1:用筛选法求100 之内的素数。 解: 所谓"筛选法"指的是"埃拉托色尼(Eratosthenes)筛法"。埃拉托色尼是古希腊的驰名数学家。他采取的办法是,在一张纸上写上1~1000 的全副整数,而后一一判断它们是否是素数,找出一个非素数,就把它挖掉,最初剩下的就是素数,见图6.1。 具体做法如下∶
(1)先将1挖掉(因为1不是素数)。
(2)用2除它前面的各个数,把能被2整除的数挖掉,即把2的倍数挖掉。 (3)用3除它前面各数,把3 的倍数挖掉。
(4)别离用4,5…各数作为除数除这些数当前的各数。这个过程始终进行到在除数前面的数已全被挖掉为止。例如在图6.1中找1~50 的素数,要始终进行到除数为 47为止。事实上,能够简化,如果须要找1~n 的素数,只须进行到除数为 $ \sqrt{n} $(取其整数)即可,例如对1~50,只须进行到将 $ \sqrt{7} $ 作为除数即可。请读者思考为什么。 下面的算法可示意为∶ (1)挖去1;
(2)用下一个未被挖去的数 p 除 p 前面个数,把 p 的倍数挖掉;
(3)查看p是否小于 $ \sqrt{n} $ 的整数局部(如果 n=1000,则查看 p<31 是否成立),如果是,则返回(2)继续执行,否则就完结; (4)剩下的数就是素数。
用计算机解此题,能够定义一个数组 a。a[1]~a[n] 别离代表1~n这 n 个数。如果查看出数组 a的某一元素的值是非素数,就使它变为 0,最初剩下不为 0 的就是素数。
程序如下: #include <stdio.h>#include <math.h> //程序中用到求平方根函数 sqrtint main(){ int i, j, n, a[101]; //定义a数组蕴含101个元素 for (i = 1; i <= 100; i++) // a[0]不必,只用a[1]~a[100] a[i] = i; //使 a[1]~a[100]的值为1~100 a[1] = 0; //先"挖掉"a[1] for (i = 2; i < sqrt(100); i++) for (j = i + 1; j <= 100; j++) { if (a[i] != 0 && a[j] != 0) if (a[j] % a[i] == 0) a[j] = 0; //把非素数“挖掉" } printf("\n"); for (i = 2, n = 0; i <= 100; i++) { if (a[i] != 0) //选出值不为0的数组元素,即素数 { printf("%5d", a[i]); //输入素数,宽度为5列 n++; //累积本行已输入的数据个数 } if (n == 10) { printf("\n"); n = 0; } } printf("\n"); return 0;}运行后果: ...

April 19, 2022 · 10 min · jiezi

关于c:C语言程序设计谭浩强第五版-第5章-循环结构程序设计-习题解析与答案

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。 题目1:请画出例 5.6 中给出的3个程序段的流程图。 解∶上面别离是教材第5章例5.6给出的程序,据此画出流程图。 (1)程序1: #include <stdio.h>int main(){ int i, j, n = 0; for (i = 1; i <= 4; i++) // n用来累计输入数据的个数 for (j = 1; j <= 5; j++, n++) { if (n % 5 == 0) printf("\n"); //管制在输入5个数据后换行 printf("%d\t", i * j); } printf("\n"); return 0;}运行后果: 其对应的流程图见图5. 1。 (2)程序2: #include <stdio.h>int main(){ int i, j, n = 0; for (i = 1; i <= 4; i++) for (j = 1; j <= 5; j++, n++) { if (n % 5 == 0) printf("\n"); //管制在输入5个数据后换行 if (i == 3 && j == 1) break; //遇到第3行第1列,完结内循环 printf("%d\t", i * j); } printf("\n"); return 0;}运行后果: ...

April 18, 2022 · 11 min · jiezi

关于c:C语言使用指针找出二维数组中最大的值

1、题目现有如下二维数组,请找出其中最大的数。 要求: 1、不在子函数中输入。2、不能批改指定的子函数int GetMax(int* p, int m, int n)示例: 输出:1 2 9           4 9 8输入:max=92、残缺代码2.1 C语言版本#include <stdio.h>#define N 10int GetMax(int* p, int m, int n) { int ret = -0x3f3f3f3f; for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) ret = max(ret, (p + i * N)[j]); return ret;}int max(a, b) { if (a >= b) return a; else return b;}int main() { int a[N][N]; for (int i = 0; i < 2; ++i) for (int j = 0; j < 3; ++j) scanf("%d", &a[i][j]); printf("max=%d", GetMax(a[0], 2, 3)); return 0;}2.2 C++版本#include <iostream>#define N 10using namespace std;int GetMax(int *p, int m, int n){ int ret = -0x3f3f3f3f; for(int i = 0; i < m; ++i) for(int j = 0; j < n; ++j) ret = max(ret, (p + i * N)[j]); return ret;}int max(a, b) { if (a >= b) return a; else return b;}int main(){ int a[N][N]; for(int i = 0; i < 2; ++i) for(int j = 0; j < 3; ++j) cin >> a[i][j]; cout << GetMax(a[0], 2, 3) << endl; return 0; }3、截图 ...

April 17, 2022 · 1 min · jiezi