【C++】POCO学习总结(十七):日志系统(级别、通道、格式化、记录流)

news2024/11/17 3:29:31

【C++】郭老二博文之:C++目录

1、Poco::Message 日志消息

1.1 说明

所有日志消息都在Poco::Message对象中存储和传输。
头文件:#include “Poco/Message.h”
一条消息包含如下内容:优先级、来源、一个文本、一个时间戳、进程和线程标识符、可选参数(名称-值对)

1.2 消息优先级

POCO定义了8个消息优先级:

  • PRIO_FATAL(最高优先级)
  • PRIO_CRITICAL
  • PRIO_ERROR
  • PRIO_WARNING
  • PRIO_NOTICE
  • PRIO_INFORMATION
  • PRIO_DEBUG
  • PRIO_TRACE(最低优先级)

设置、获取优先级

  • void setPriority(Priority prio)
  • Priority getPriority() const

1.3 消息来源

消息来源:一般用生成消息的类的名称,或者产生消息的子系统的名称

  • void setSource(const std::string& source)
  • const std::string& getSource() const

1.4 消息内容

要记录的实际消息。对格式、长度等没有要求。可以在出现在日志目的地之前由格式化程序修改

  • void setText(const std::string& text)
  • const std::string& getText() const

1.5 时间戳

创建消息的日期和时间,精度可达微秒级。
由Poco::Message的构造函数自动初始化为当前日期和时间。

  • void setTime(const Timestamp& time)
  • const Timestamp& getTime() const

1.6 进程和线程标识符

进程标识符(PID)是一个长整型值,用于存储系统的进程ID。
线程标识符(TID)也是一个长整型值,存储当前线程的序列号。
进程标识符、线程标识符和线程名称在Poco::Message的构造函数中初始化。

  • void setThread(const std::string& threadName)
  • const std::string& getThread() const
  • void setTid(long tid)
  • long getTid() const
  • void setPid(long pid)
  • long getPid() const

1.7 消息参数

消息可以存储任意数量的键值对。键和值可以是任意字符串。消息参数可以在格式化程序中引用。使用索引操作符访问消息参数。

2、Poco::Logger 日志记录

2.1 创建

Poco::Logger是日志框架的主要入口点。
头文件 #include “Poco/Logger.h”
应用程序使用Poco::Logger类的实例来生成日志消息。
每个记录器都有一个附加的通道,该通道将消息传递到它们的目的地(可能通过其他通道)。
每个记录器都有一个名称,它成为该记录器生成的所有消息的源。该名称是在创建时设置的,以后不可更改

2.2 优先级

日志记录器根据消息的优先级过滤消息。
只有优先级等于或高于日志记录器日志级别的消息才会被传播。
例如:
日志级别设置为PRIO_ERROR的日志记录器将只传播优先级为PRIO_ERROR、PRIO_CRITICAL或PRIO_FATAL的消息。
PRIO_WARNING或更低的值将被丢弃。

2.3 记录器的层次结构

根据它们的名字,记录器形成了一个树状的层次结构。
日志记录器的名称由一个或多个组件组成,以句点分隔。每个组件对应于前一个组件的名称空间中的一个名称。
一个特殊的记录器,根记录器,是一个以空字符串作为其名称的记录器。它构成了日志记录器层次结构的根。
日志记录器层次结构的最大深度没有限制。

在这里插入图片描述

2.4 继承层次结构

新创建的日志记录器从日志记录器层次结构中的祖先继承其日志级别和附加通道。
例如:在创建时,记录器“HTTPServer.RequestHandler.cgi”将从名为“HTTPServer.RequestHandler”的记录器继承其日志级别和附加通道。
一旦日志程序被完全创建,它就不再与它的祖先相关。换句话说,对日志记录器的日志级别或通道的更改对其已经存在的后代没有影响。

2.5 记录日志

  • void log(const Message& msg):如果消息的优先级大于或等于记录器的日志级别,则将消息传播到附加的通道。信息保持不变。

  • void log(const Exception& exc):创建并记录一条优先级为PRIO_ERROR的消息和异常的显示文本

创建并记录具有各自优先级和给定文本的消息:

  • void fatal(const std::string& text)
  • void critical(const std::string& text)
  • void error(const std::string& text)
  • void warning(const std::string& text)
  • void notice(const std::string& text)
  • void information(const std::string& text)
  • void debug(const std::string& text)
  • void trace(const std::string& text)

void dump(const std::string& text,const void* buffer, int length,Message::Priority prio = Message::PRIO_DEBUG)
用给定的优先级记录给定的消息。文本之后是给定缓冲区的十六进制转储。

2.6 日志级别

  • bool is(int level) const:如果日志记录器的日志级别至少为level,则返回true。- bool fatal() const

如果日志记录器的日志级别至少是相应的级别,则返回true:

  • bool critical() const
  • bool error() const
  • bool warning() const
  • bool notice() const
  • bool information() const
  • bool debug() const
  • bool trace() const

2.7 记录器

POCO管理一个全局的记录器映射。
不要自己创建记录器。要使用POCO提供记录器的引用。POCO会根据需要动态创建新的记录器。

static Logger& get(const std::string& name)

返回对具有给定名称的记录器的引用。如果没有会自动创建日志记录器。这是线程安全的。

2.8 示例

#include "Poco/Logger.h"
using Poco::Logger;
int main(int argc, char** argv)
{
	Logger& logger = Logger::get("TestLogger");
	logger.information("This is an informational message");
	logger.warning("This is a warning message");
	return 0;
}

3、Poco::Channel 通道

3.1 说明

Poco::Channel的子类负责将消息(Poco::Message)传递到它们的目的地(例如,控制台或日志文件)。
每个Poco::Logger(它本身是Poco::Channel的子类)都连接到Poco::Channel。POCO提供了POCO::Channel的各种子类,这些子类将消息传递到控制台、日志文件或系统的日志记录设施。
可以定义你自己的通道类。
通道使用引用计数进行内存管理。

3.2 信道特性

通道可以支持任意数量的属性(键值对),这些属性用于配置通道。
属性是通过setProperty()成员函数设置的:
属性的值可以通过getProperty()获得:
这两个函数是在Poco::Configurable类中定义的,它是Poco::Channel的超类。

  • void setProperty(const std::string& name, const std::string& value)
  • std::string getProperty(const sdt::string& name)

3.3 Poco::ConsoleChannel 控制台通道

Poco::ConsoleChannel 是最基本的通道实现。
头文件:#include “Poco/ConsoleChannel.h”
Poco::ConsoleChannel 只是将接收到的任何消息的文本写入标准输出(std::clog)。
Poco::ConsoleChannel 没有可配置的属性。
Poco::ConsoleChannel 是根记录器的默认通道。

3.4 Poco::WindowsConsoleChannel Windows控制台

Poco::WindowsConsoleChannel类似于ConsoleChannel,但直接写入Windows控制台,而不是std::clog。
头文件:#include “Poco/WindowsConsoleChannel.h”
Poco::WindowsConsoleChannel 只是将接收到的任何消息的文本写入Windows控制台。
Poco::WindowsConsoleChannel 没有可配置的属性。
Poco::WindowsConsoleChannel 支持> UTF-8编码的文本。

3.5 Poco::NullChannel 空通道

Poco::NullChannel丢弃发送给它的所有消息。
头文件:#include “Poco/NullChannel.h”

3.6 Poco::SimpleFileChannel 最简日志文件

3.6.1 说明

Poco::SimpleFileChannel是编写日志文件最简单的方法。
消息的文本被附加到一个文件中,后跟一个换行符。
支持可选的简单日志文件轮换:在主日志文件和备日志文件之间轮流写,当一旦主日志文件超过一定大小,将创建一个备日志文件(如果已经存在,则将其清空)。如果备日志文件超过最大大小,则清空主日志文件,并继续记录主日志文件,依此类推。

3.6.2 属性

1)path:主日志文件路径。
2)secondaryPath:备日志文件路径。默认为path.1
3) rotation:日志文件大小

  • never:默认的,一直记录在主日志文件
  • n:当文件大小超过n字节时轮换
  • n K:当文件大小超过n Kb时轮换
  • n M:当文件大小超过n Mb时轮换

3.6.3 示例

#include "Poco/Logger.h"
#include "Poco/SimpleFileChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::SimpleFileChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
	AutoPtr<SimpleFileChannel> pChannel(new SimpleFileChannel);
	pChannel->setProperty("path", "sample.log");
	pChannel->setProperty("rotation", "2 K");
	Logger::root().setChannel(pChannel);
	Logger& logger = Logger::get("TestLogger"); // 继承根通道
	for (int i = 0; i < 100; ++i)
		logger.information("Testing SimpleFileChannel");
	return 0;
}

3.7 Poco::FileChannel 文件通道

3.7.1 说明

Poco::FileChannel提供了全面的日志文件支持。
头文件:#include “Poco/FileChannel.h”
消息的文本被附加到一个文件中,后跟一个换行符。
Poco::FileChannel 支持根据文件大小或时间间隔轮换日志文件。
Poco::FileChannel 支持归档日志文件的自动归档(不同的文件命名策略)、压缩(gzip)和清除(根据归档文件的时间或归档文件的数量)。

3.7.2 属性

1)path:日志文件路径
2)rotation:日志文件的轮换方式

  • never 不轮换
    • n:当文件大小超过n字节时轮换
  • n K:当文件大小超过n Kb时轮换
  • n M:当文件大小超过n Mb时轮换
  • [day,][hh:][mm]:在指定的星期/时间轮换
  • daily/weekly/monthly:每天/每周/每月
  • n hours/weeks/months:每n个小时/周/月

3)archive:归档日志文件的命名

  • number:一个自动递增的数字,从0开始,附加到日志文件名后。最新存档的文件总是0。
  • timestamp: 以 YYYYMMDDHHMMSS 格式的时间戳附加到日志文件中。

4)times:指定轮换时间是作为本地时间还是UTC时间处理。有效值为local和utc。
5)compress:自动压缩归档文件。指定true或false。
6)purgeAge:指定归档日志文件的最大保存时间。超过这个时间的文件将被清除。
7)purgeCount:指定归档日志文件的最大数目。如果达到这个数字,那么最旧的归档日志文件将被清除。

3.7.3 示例

#include "Poco/Logger.h"
#include "Poco/FileChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::FileChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
	AutoPtr<FileChannel> pChannel(new FileChannel);
	pChannel->setProperty("path", "sample.log");
	pChannel->setProperty("rotation", "2 K");
	pChannel->setProperty("archive", "timestamp");
	Logger::root().setChannel(pChannel);
	Logger& logger = Logger::get("TestLogger"); // 继承根通道
	for (int i = 0; i < 100; ++i)
		logger.information("Testing FileChannel");
	return 0;
}

3.8 Poco::EventLogChannel Windows专用

Poco::EventLogChannel:仅在Windows NT平台上使用,记录Windows事件日志。
Poco::EventLogChannel将PocoFoundation.dll注册为Windows事件日志中的消息定义资源DLL。
当查看Windows事件日志时,事件查看器应用程序必须能够找到PocoFoundation.dll,否则日志消息将不会按预期显示。

3.9 Poco::SyslogChannel Linux专用

仅在Unix平台上可用的Poco::SyslogChannel将日志记录到本地Syslog守护进程。
Net库包含一个RemoteSyslogChannel类,它使用基于udp的Syslog协议与远程Syslog守护进程一起工作。

3.10 Poco::AsyncChannel 异步通道

Poco::AsyncChannel允许在单独的线程中运行通道。
将产生日志消息的线程与传递日志消息的线程解耦。
所有日志消息都存储在FIFO队列中。
一个单独的线程从队列中提取消息并将它们发送到另一个通道。

#include "Poco/Logger.h"
#include "Poco/AsyncChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::AsyncChannel;
using Poco::ConsoleChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
	AutoPtr<ConsoleChannel> pCons(new ConsoleChannel);
	AutoPtr<AsyncChannel> pAsync(new AsyncChannel(pCons));
	Logger::root().setChannel(pAsync);
	Logger& logger = Logger::get("TestLogger");
	for (int i = 0; i < 10; ++i)
		logger.information("This is a test");
	return 0;
}

3.11 Poco::SplitterChannel 分发通道

Poco::SplitterChannel将消息转发到一个或多个其他通道。
void addChannel(Channel* pChannel)为Poco::SplitterChannel添加一个新通道

#include "Poco/Logger.h"
#include "Poco/SplitterChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/SimpleFileChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::SplitterChannel;
using Poco::ConsoleChannel;
using Poco::SimpleFileChannel;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
	AutoPtr<ConsoleChannel> pCons(new ConsoleChannel);
	AutoPtr<SimpleFileChannel> pFile(new SimpleFileChannel("test.log"));
	AutoPtr<SplitterChannel> pSplitter(new SplitterChannel);
	pSplitter->addChannel(pCons);
	pSplitter->addChannel(pFile);
	Logger::root().setChannel(pSplitter);
	Logger::root().information("This is a test");
	return 0;
}

4、Poco::LogStream 日志流

Poco::LogStream为Logger提供了ostream接口。
流的所有特性都可用于格式化日志消息。
日志消息必须以std::endl(或CR或LF字符)结束。

可以设置消息的优先级

  • LogStream& priority(Message::Priority prio)
  • LogStream& fatal()
  • LogStream& critical()
  • LogStream& error()
  • LogStream& warning()
  • LogStream& notice()
  • LogStream& information()
  • LogStream& debug()
  • LogStream& trace
#include "Poco/LogStream.h"
#include "Poco/Logger.h"
using Poco::Logger;
using Poco::LogStream;
int main(int argc, char** argv)
{
	Logger& logger = Logger::get("TestLogger");
	LogStream lstr(logger);
	lstr << "This is a test" << std::endl;
	return 0;
}

5、日志格式化

5.1 说明

Poco::FormattingChannel 和 Poco::Formatter 负责格式化日志消息。
在将消息传播到下一个通道之前,Poco::FormattingChannel 将它接收到的每个消息传递给 Poco::Formatter。
Formatter是所有格式化器类的基类。
与通道一样,格式化器也可以使用属性进行配置。

5.2 PatternFormatter

PatternFormatter根据printstyle打印模式格式化消息

#include "Poco/ConsoleChannel.h"
#include "Poco/FormattingChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/Logger.h"
#include "Poco/AutoPtr.h"
using Poco::ConsoleChannel;
using Poco::FormattingChannel;
using Poco::PatternFormatter;
using Poco::Logger;
using Poco::AutoPtr;
int main(int argc, char** argv)
{
	AutoPtr<ConsoleChannel> pCons(new ConsoleChannel);
	AutoPtr<PatternFormatter> pPF(new PatternFormatter);
	pPF->setProperty("pattern", "%Y-%m-%d %H:%M:%S %s: %t");
	AutoPtr<FormattingChannel> pFC(new FormattingChannel(pPF, pCons));
	Logger::root().setChannel(pFC);
	Logger::get("TestChannel").information("This is a test");
	return 0;
}

6、性能

创建消息需要花费一些时间(必须确定当前时间、当前进程ID和当前线程ID)。
创建一个有意义的消息可能需要更多的时间,因为字符串连接和数字格式等是必要的。
消息通常通过引用在通道链中传递。
特别的:formatingchannel和AsyncChannel创建消息的副本。

对于每个日志记录器,总是分别启用或禁用日志记录(或者更准确地说,设置日志级别),因此,一旦有了对日志记录器的引用,确定为特定日志记录器设置哪个日志级别是一个常数时间操作(简单的内联整数比较)。

获取对记录器的引用是一个具有对数复杂度的操作(基本上是std::map查找)。记录器的名称用作查找中的键,因此记录器名称的长度线性地影响查找时间(字符串比较)。然而,这一点可能可以忽略不计。

通常,对记录器(logger::get())的引用只在应用程序中获得一次。例如,在一个类中,可以在类的构造函数中获得对其日志记录器的引用,然后从此只使用该引用。
应该避免频繁调用Logger::get()。最好是对将要使用的每个记录器调用它一次,然后存储对记录器的引用以供以后使用。
日志性能取决于你要使用的通道。实际信道性能是高度依赖于系统的。

构造日志消息通常是一个耗时的操作,包括字符串创建、字符串连接、数字格式化等。
在这种情况下,使用is()、fatal()、critical()等方法,在构造消息之前检查消息是否会被记录是一个好主意。
还有一些宏在构造消息之前做检查:poco_fatal(msg), poco_critical(msg), poco_error(msg)

if (logger.warning())
{
	std::string msg("This is a warning");
	logger.warning(msg);
}

等同于:poco_warning(logger, “This is a warning”);

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

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

相关文章

每天五分钟计算机视觉:Inception网络是由多个Inception模块构成

本文重点 inception从另一种角度来提升训练结果:能更高效的利用计算资源,在相同的计算量下能提取到更多的特征,从而提升训练结果。可以简单的理解为Inception 网络是由一个一个的Inception模块构建成的,我们来看一下。 Inception模块 如上就是Inception模块的 通过一个1…

【Android逆向】记录一次某某虚拟机的逆向

导语 学了一段时间的XPosed&#xff0c;发现XPosed真的好强&#xff0c;只要技术强&#xff0c;什么操作都能实现... 这次主要记录一下我对这款应用的逆向思路 apk检查 使用MT管理器检查apk的加壳情况 发现是某数字的免费版本 直接使用frida-dexdump 脱下来后备用 应用分…

【MYSQL】事务隔离级别、脏读、不可重复读、幻读

文章目录 介绍演示脏读不可重复读可重复读幻读 不可重复读和幻读的区别 参考 作者 Guide: 事务隔离级别 美团技术团队&#xff1a; Innodb中的事务隔离级别和锁的关系 介绍 SQL 标准定义了四个隔离级别&#xff1a; READ-UNCOMMITTED(读取未提交) &#xff1a;最低的隔离级别…

虚拟机启动 I/O error in “xfs_read_agi+0x95“

1.在选择系统界面按e 进入维护模式 2.找到ro把ro改成 rw init/sysroot/bin/sh 然后按Ctrlx 3.找到坏掉的分区&#xff0c;以nvme0n1p3为例进行修复 xfs_repair -d /dev/nvme0n1p3 4.init 6 重新启动 以下情况 先umount 再修复 则修复成功

SaaS行业分析

文章目录 什么是SaaS ?SaaS的标准定义什么是软件即服务&#xff1f;SaaS与传统软件的区别 &#xff1f; SaaS行业分析你知道最赚钱的行业是什么&#xff1f;互联网带给企业的变化 SaaS与PaaS、IaaS的区别&#xff1f;IaaS&#xff08;Infrastructure as a Service&#xff09;…

消除非受检警告

在Java中&#xff0c;有一些情况下编译器会生成非受检警告&#xff08;Unchecked Warnings&#xff09;。这些警告通常与泛型、类型转换或原始类型相关。消除这些警告可以提高代码的可读性和安全性。以下是一些常见的非受检警告以及如何消除它们的例子&#xff1a; 1. 泛型类型…

js传递json数据过大的解决方案

protobufjs 使用protobuf&#xff0c;定义如下结构 Person.protobuf syntax "proto3";message Person {string name 1;int32 age 2; }Person.thrift namespace java com.example.Personstruct Person {1: required string name,2: required i32 age }使用bench…

高压电气是什么

高压电气 电工电气百科 文章目录 高压电气前言一、高压电气是什么二、高压电气的类别三、高压电气的作用原理总结前言 高压电气在电力系统中起着重要的作用,它能够将电能有效地输送和分配到各个用户,为社会和工业生产提供稳定可靠的电力供应。然而,高压电气系统也需要注意安…

Jwt令牌过滤器的下发和拦截(创建在前面)

创建Jwt令牌的方法在前面&#xff1a; JWT令牌的作用和生成https://blog.csdn.net/m0_71149935/article/details/135002840?spm1001.2014.3001.5501令牌的下发&#xff1a; 说明&#xff1a; 只用在浏览器访问服务器的时候校验账户信息是否正确&#xff0c;正确就创建Jwt令…

网站服务器/域名/备案到底有什么关联?

​  在一个网站的组成中&#xff0c;网站服务器、域名、备案这几个要素是要被常提到的。在谈及三者关联之前&#xff0c;我们先了解下三者的各自概念。 域名&#xff1a;它是网站的唯一标识符&#xff0c;通俗理解来说就是用户在浏览器地址栏中输入的网址。一般来说&#xff…

Java开发工具积累(符合阿里巴巴手册规范)

文章目录 一、命名规约二、集合篇1. 栈、队列、双端队列2. List的升序倒序3. Map的升序降序4. 二维数组排序5. 集合之间的转换6. Map键值对遍历 三、并发篇1. 创建线程池2. ThreadLocal的使用 四、时间篇1. LocalDateTime的使用2. String、Date、LocalDateTime转换 五、控制块1…

[每周一更]-(第27期):HTTP压测工具之wrk

[补充完善往期内容] wrk是一款简单的HTTP压测工具,托管在Github上,https://github.com/wg/wrkwrk 的一个很好的特性就是能用很少的线程压出很大的并发量. 原因是它使用了一些操作系统特定的高性能 io 机制, 比如 select, epoll, kqueue 等. 其实它是复用了 redis 的 ae 异步事…

最新50万字312道Java经典面试题52道场景题总结(附答案PDF)

最近有很多粉丝问我&#xff0c;有什么方法能够快速提升自己&#xff0c;通过阿里、腾讯、字节跳动、京东等互联网大厂的面试&#xff0c;我觉得短时间提升自己最快的手段就是背面试题&#xff1b;花了3个月的时间将市面上所有的面试题整理总结成了一份50万字的300道Java高频面…

C#上位机与欧姆龙PLC的通信02----搭建仿真环境

在没有硬件的情况下&#xff0c;创建仿真环境非常必要&#xff0c;买硬件需要花大几K的大洋&#xff0c;这是不好的&#xff0c;对于学习培训者来说&#xff0c;有仿真环境就特别漂亮&#xff0c;现在CX-ONE已经集成了欧姆龙的编程软件&#xff0c;能够实现仿真PLC及编程&#…

java基础-1

byte&#xff1a;8位有符号二进制补码整数&#xff0c;占用1字节。 short&#xff1a;16位有符号二进制补码整数&#xff0c;占用2字节。 int&#xff1a;32位有符号二进制补码整数&#xff0c;占用4字节。 long&#xff1a;64位有符号二进制补码整数&#xff0c;占用8字节。…

uniapp:使用fixed定位,iOS平台的安全区域问题解决

manifest.json > 添加节点 "safearea": { //iOS平台的安全区域"background": "#1C1E22","backgroundDark": "#1C1E22", // HX 3.1.19支持"bottom": {"offset": "auto"} },已解决&#xff…

LabVIEW开发电能质量监测系统

LabVIEW开发电能质量监测系统 本研究基于LabVIEW开发了一个创新的电能质量监测系统&#xff0c;专注于暂态电能质量扰动信号的产生、分析与存储。该系统不仅模拟产生了电压骤降、电压波动、暂态振荡以及电压畸变等关键信号&#xff0c;还能够记录并存储这些扰动信号产生时的波…

【Linux】使用官方脚本自动安装 Docker(Ubuntu 22.04)

前言 Docker是一种开源平台&#xff0c;用于开发、交付和运行应用程序。它利用了容器化技术&#xff0c;使开发人员能够将应用程序及其依赖项打包到一个称为Docker容器的可移植容器中。这些容器可以在任何运行Docker的机器上快速、一致地运行&#xff0c;无论是开发环境、测试…

智能高效|AIRIOT智慧货运管理解决方案

随着全球贸易的增加和消费需求的不断扩大&#xff0c;货运行业面临更大的压力&#xff0c;传统货运行业运输效率低下、信息不透明&#xff0c;往往存在如下的运维问题和管理痛点&#xff1a; 无法实时定位和追踪信息&#xff1a;无法提供实时的货物位置信息&#xff0c;以便随…

C语言:指针与数组易错辨析

前言&#xff1a; 在学校学习指针和数组的联系时&#xff0c;对指针与数组的结合产生了很大的疑惑&#xff0c;后来不断查找资料&#xff0c;本人对指针与数组的综合有了一定的理解&#xff0c;现进行综合讨论辨析 数组指针&#xff1a; 数组指针&#xff0c;即为指向数组类…