PCL学习01之点云的基本操作_pcl导出点云-程序员宅基地

技术标签: 学习  c++  PCL  

1、向pcd文件写入点云数据

个人笔记:

  1. 实例化的模板类PointCloud 每一个点的类型都设置为pcl::PointXYZ
    点PointXYZ类型对应的数据结构
    Structure PointXYZ{
    float x;
    float y;
    float z;
    };
  2. PointXYZ是一个vector
  3. 判断点云是否有序:cloud.isOrganized()
  4. argc 表示你在命令行下输入命令的时候,一共有多少个参数, argv 用来取得你所输入的参数

存储点云文件:pcl::io::savePCDFileASCII(“…/path”, cloud);

#include<iostream>
#include<pcl/io/pcd_io.h>//pcd读写相关的头文件夹
#include<pcl/point_types.h>//pcd中支持的点类型头文件,比如pcl::PointXYZ
   //1、写入数据
int main01(int argc, char** argv)
{
    
    //创建点云  描述我们将创建模板化PointCloud结构
    pcl::PointCloud<pcl::PointXYZ> cloud;

    //设置相关参数
    /*
    cloud.height = 1;  用来判断是否为有序点云,=1为无序点云
    无序点云: cloud.width指点云的个数,结构点云:云数据集一行上点的个数
    cloud.is_dense(bool)  判断points中数据是否有限或者判断点云中的点是否包含 Inf/NaN这种值(包含为false)
    */
    cloud.width = 5;
    cloud.height = 1;
    cloud.is_dense = false;//不是稠密型
    cloud.points.resize(cloud.width * cloud.height);//点云的总数

    //用随机数的值填充PointCloud点云对象
    //for(auto &point:cloud)
    for (size_t i = 0; i < cloud.points.size(); ++i)
    {
    
       //0~1024之间不等于1024的一个随机浮点数
        cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
    }

    //把PointCloud对象存储在test_pcd.pcd文件中
    //pcl::io::savePCDFileASCII("D://0718box//test_pcd.pcd", cloud);
    pcl::io::savePCDFileASCII("../test_pcd.pcd", cloud);

    //打印输出存储点云的数据
    std::cerr << "Saved:" << cloud.points.size() << "data points to test_pcd.cpp" << std::endl;
    for (size_t i = 0; i < cloud.points.size(); ++i)
        std::cerr << "     " << cloud.points[i].x << "   "
        << cloud.points[i].y << "    " << cloud.points[i].z << std::endl;

    return (0);
}

2、从pcd文件读取点云数据

笔记:
出现原因:在读取点云时,debug下不能正常运行,release可以

debug:会增加调试代码
release用于发布   release下不报错是忽略了错误而不是没有错误

*打开点云文件:pcl::io::loadPCDFilepcl::PointXYZ(pcd_path, cloud)
步骤:

  1. 创建一个 PointCloud提升共享指针并对其进行初始化。
  2. 将test_pcd.pcd 加载到二进制blob中
  3. 读取二进制blob并将其转换为模板化的PointCloud格式
#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>

int main02(int argc, char** argv)
{
    
	//创建一个PointCloud<pcl::PointXYZ> 
	//boost共享指针进行初始化
	//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud< pcl::PointXYZ >);
	//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = std::make_shared<pcl::PointCloud<pcl::PointXYZ>>();
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	std::string pcd_path = "../test_pcd.pcd";
	//打开点云文件
	// 将test_pcd.pcd 加载到二进制blob中
	
	//if (pcl::io::loadPCDFile<pcl::PointXYZ>("D://0718box//test_pcd.pcd", *cloud) == -1)
	if (pcl::io::loadPCDFile<pcl::PointXYZ>(pcd_path, *cloud) == -1)
	{
    
		//PCL_ERROR("Cloud not read file test_pcd.pcd \n");
		std::cerr << "Cloud not read file test_pcd.pcd" << std::endl;
		return  (-1);
	}

	std::cout << " Loaded "
		<< cloud->width * cloud->height
		<< " data points from test_pcd.pcd with the following fields:"
		<< std::endl;

	//for (size_t i = 0; i < cloud->points.size(); ++i)
	//{
    
	//	std::cout << "  " << cloud->points[i].x
	//		<< "  " << cloud->points[i].y
	//		<< "  " << cloud->points[i].z << std::endl;
	//}

	//读取二进制blob并将其转换为模板化的PointCloud格式
	for (const auto& point : *cloud)
	{
    
		std::cout << "  "<<point.x << "   " << point.y << "   " << point.z << std::endl;
	}
	return (0);
}

3、连接两个不同点云为一个点云

点云连接 concatenate points  列的下方连接
字段连接 concatenate fields  行的基础后连接    
**pcl::concatenateFields(cloud_a, n_cloud_b,p_n_cloud_c);**
	在连接两个点云前,要确保两个数据集中字段的类型相同和维度相同,
同时了解如何连接两个不同点云的字段颜色,法线),这种操作的强制约束条件是两个数据集中的点数目必须一样

个人笔记:
1、std::cerr与std::cout的区别
cerr是一个ostream对象,C++标准错误输出流,关联到标准错误,写到cerr的数据是不缓冲的,
cree通常用于输出错误与其他不属于正常逻辑的输出内容
cree的目的:在紧急情况下,能得到输出功能。
缓冲区:减少刷屏的次数,不带缓冲,就会每写一个字母,输出一个字母,不断刷屏;有了缓冲区,就会看到很多个语句同时出现在屏幕上

2、pcl::Normal 是最常见的一种点的类型,代表了给定点的曲面法线(normal)和曲率的测量
pcl::PointCloud类的模板参数,定义了点云的存储类型
常用的点的类型:
pcl::PointXYZ,存储着点的x,y,z信息
pcl::PointXYZI,在上面的基础上,包含了一个域描述点的密集程度
pcl::PointWithRange,存储点的范围
pcl::PointXYZRGBA:存储3D信息的同时和RGB与Alpha(透明度)
用户也可以自己定义自己的类型

#pragma warning(disable:4996)
#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>


int main03(int argc, char** argv)
{
    
	pcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b, cloud_c;//三个输入点云
	pcl::PointCloud<pcl::Normal> n_cloud_b;// 两个输出点云,储存法线的点云
	pcl::PointCloud<pcl::PointNormal> p_n_cloud_c;//储存xyz和法线的点云

	//创建点云数据
	cloud_a.width = 3;
	cloud_a.height = cloud_b.height= n_cloud_b.height=1;//无序点云
	cloud_a.points.resize(cloud_a.width * cloud_a.height);

	cloud_b.width = 5;//点云连接---列下面连接
	cloud_b.points.resize(cloud_b.width * cloud_b.height);

	n_cloud_b.width = 3;//字段连接---行后面连接
	n_cloud_b.points.resize(n_cloud_b.width * n_cloud_b.height);

	//填充点云cloud_a的数据
	for (size_t i = 0; i < cloud_a.points.size(); ++i)
	{
    
		cloud_a.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud_a.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud_a.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
	}

	//填充点云cloud_b的数据
	for (size_t i = 0; i < cloud_b.points.size(); ++i)
	{
    
		cloud_b.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud_b.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud_b.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
	}

	//填充点云n_cloud_b的数据
	for (size_t i = 0; i < n_cloud_b.points.size(); ++i)
	{
    
		n_cloud_b.points[i].normal[0] = 1024 * rand() / (RAND_MAX + 1.0f);
		n_cloud_b.points[i].normal[1] = 1024 * rand() / (RAND_MAX + 1.0f);
		n_cloud_b.points[i].normal[2] = 1024 * rand() / (RAND_MAX + 1.0f);
	}

	//输出点云数据
	std::cerr << "Cloud A:" << std::endl;
	for (size_t i = 0; i < cloud_a.points.size(); ++i)
	{
    
		std::cerr << cloud_a.points[i].x << "  "
			<< cloud_a.points[i].y << "  " << cloud_a.points[i].z << "  " << std::endl;
	}

	std::cerr << "Cloud B:" << std::endl;
	for (size_t i = 0; i < cloud_b.points.size(); ++i)
	{
    
		std::cerr << cloud_b.points[i].x << "  "
			<< cloud_b.points[i].y << "  " << cloud_b.points[i].z << "  " << std::endl;
	}
	std::cerr << "n_Cloud_b:" << std::endl;
	for (size_t i = 0; i < n_cloud_b.points.size(); ++i)
	{
    
		std::cerr << n_cloud_b.points[i].normal[0]<< "  "
			<< n_cloud_b.points[i].normal[1] << "  " 
			<< n_cloud_b.points[i].normal[2] << "  " << std::endl;
	}

	//点云连接 cloud_c = cloud_a + cloud_b
	cloud_c = cloud_a + cloud_b;
	std::cerr << "点云连接   Cloud C:" << std::endl;
	for (size_t i = 0; i < cloud_c.points.size(); ++i)
	{
    
		std::cerr << cloud_c.points[i].x << "  "
			<< cloud_c.points[i].y << "  " << cloud_c.points[i].z << "  " << std::endl;
	}

	//字段连接   pcl::concatenateFields(cloud_a, n_cloud_b, p_n_cloud_c);
	//错误的:p_n_cloud_c = cloud_a + n_cloud_b;
	//解决办法:把cloud_a和n_cloud_b字段连接,一起创建p_n_cloud_c
	pcl::concatenateFields(cloud_a, n_cloud_b, p_n_cloud_c);
	std::cerr << "字段连接   p_n_Cloud C:" << std::endl;
	for (size_t i = 0; i < p_n_cloud_c.points.size(); ++i)
	{
    
		std::cerr << p_n_cloud_c.points[i].x << "  "
			<< p_n_cloud_c.points[i].y << "  " << p_n_cloud_c.points[i].z << "  "
			<< p_n_cloud_c.points[i].normal[0] << "  "
			<< p_n_cloud_c.points[i].normal[1] << "  "
			<< p_n_cloud_c.points[i].normal[2] << "  "<<std::endl;
	}
	return (0);
}

4、获取传感器深度

boost::signals2实现了线程安全,是一种函数的回调机制

#include<pcl/point_cloud.h>//点云类定义头文件
#include<pcl/point_types.h>//点 类型定义头文件
#include<pcl/io/openni2_grabber.h>//OpenNI数据流获取头文件
#include<pcl/common/time.h>//时间头文件
#include<boost/thread/thread.hpp>//用来创建一个新线程,简化多线程的开发

//类SimpleOpenNIProcessor 的回调函数,对数据进行处理的回调函数的封装
class SimpleOpenNIProcessor
{
    
public:
	void cloud_cb(const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr& cloud)
	{
    
		static unsigned count = 0;
		static double last = pcl::getTime();//获取当前时间
		if (++count == 30)//30ms
		{
    
			double now = pcl::getTime();
			std::cout << "中心像素的位置:" << cloud->points[(cloud->width >> 1)
			 * (cloud->height + 1)].z
				<< "mm. Average framerate:" << double(count) / double(now - last) 
				<< " Hz" << std::endl;
			last = now;
			count = 0;
		}
	}

	//pcl::Grabber
	void run()
	{
    
		//创建一个:OpenNI2Grabber接口
		pcl::Grabber* interface = new pcl::io::OpenNI2Grabber();

		//定义回调函数
		boost::function<void(const pcl::PointCloud <pcl::PointXYZRGB>::ConstPtr&)>f =
			boost::bind(&SimpleOpenNIProcessor::cloud_cb, this,-1);

		boost::signals2::connection conn = interface->registerCallback(f);//注册回调函数

		interface->start();//开始接收点云数据

		while (true)
			//添加头文件:#include<boost/thread/thread.hpp>
			boost::this_thread::sleep(boost::posix_time::seconds(1));
			
			//停止采集
			interface->stop();
	}
};

int main04()
{
    
	SimpleOpenNIProcessor sONIP;
	sONIP.run();
	return 0;
}

个人笔记:
1、cloud.makeShared();
pcl::PointCloud.makeshared()返回的是一个对当前点云深度复制后的对象的智能指针
也就是说
pcl::PointCloudcloud;
pcl::PointCloud::Ptr p=cloud.makeshared();
其中p并不指向cloud的空间,而是深拷贝了cloud放在新的内存空间上,然后返回新空间的指针
所以,用过p操作点云,cloud不会改变
2、加快ASCII格式存储,将pcd文件换成Binary格式存储
pcl::io::savePCDFileBinary(“path”,*cloud);

5、获取pcd文件点云格式

void get_PCD_Fromat()
{
    
	pcl::PCLPointCloud2 cloud;
	pcl::PCDReader reader;
	reader.readHeader("D://0718box//test_pcd.pcd", cloud);
	for (int i = 0; i < cloud.fields.size(); i++)
	{
    
		std::cout << cloud.fields[i].name<<std::endl;//cout:xyz型
	}
}

6、实现pcl::PointCloud::Ptr 和pcl::PointCloud的两个类型转换

void type_Conversion()
{
    
	//创建存放点云的对象
	pcl::PointCloud < pcl::PointXYZ>::Ptr cloudPointer(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>cloud;
	cloud = *cloudPointer;
	cloudPointer = cloud.makeShared();
}

7、给pcl::PointXYZ类型的点云在显示时指定颜色

头文件:#include<pcl/visualization/pcl_visualizer.h>
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> sig(cloud, 255, 22, 99);
#include<pcl/visualization/pcl_visualizer.h>
void pcd_visualization()
{
    
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile<pcl::PointXYZ>("D://0718box//0718-04.pcd", *cloud);

	pcl::visualization::PCLVisualizer viewer("pointcloud viewer");
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> sig(cloud, 255, 22, 99);
	viewer.addPointCloud(cloud, sig, "cloud");
	//设置大小
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1);
	//添加一个坐标系
	viewer.addCoordinateSystem(500);
	while (!viewer.wasStopped())
	{
    
		viewer.spinOnce();
	}
}

8、查找点云的x,y,z的极值

pcl::getMinMax3D函数说明:
cloud为输入点云,而非指针(共享指针则写为*cloud),
输出min_pt为所有点中最小的x值,y值,z值,输出max_pt为为所有点中最大的x值,y值,z值.而非某个点。
头文件:#include<pcl/common/common.h>

void pcl_Max_Min()
{
    
	//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
	cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile<pcl::PointXYZ>("D://0718box//0718-04.pcd", *cloud);
	pcl::PointXYZ minPt, maxPt; 
		pcl::getMinMax3D(*cloud, minPt, maxPt);
		//pcl::getMinMax3D(*cloud, minPt, maxPt);
		std::cout << "Max_x:" << maxPt.x << "   " << "Max_y:" << maxPt.y << "   " << "Max_z:" << maxPt.z << std::endl;
		std::cout << "Min_x:" << maxPt.x << "   " << "Min_y:" << minPt.y<< "   " << "Min_z:" << minPt.z << std::endl;
}

9、根据索引将原点云copy到新点云

#include<pcl/visualization/cloud_viewer.h>
#include<pcl/visualization/pcl_visualizer.h>
void pcl_Copy()
{
    
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile<pcl::PointXYZ>("D://0718box//0718-04.pcd", *cloud);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_Out(new pcl::PointCloud<pcl::PointXYZ>);
	std::vector<int> index = {
     1, 3, 5, 7, 8, 11, 56, 77 };
	pcl::copyPointCloud(*cloud, index, *cloud_Out);
	pcl::io::savePCDFileASCII("D://0718box//0718-04_test.pcd", *cloud_Out);

	//打印输出点云数据
	for (size_t i = 0; i < cloud_Out->points.size(); ++i)
	{
    
		std::cout << cloud->points[i].x << "  " << cloud->points[i].y << "  " << cloud->points[i].z << std::endl;
	}

	//可视化
	pcl::visualization::PCLVisualizer viewer("Cloud Viewer");//创建对象
	viewer.setBackgroundColor(0.05, 0.05, 0.05, 0);//背景为白色

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> sig(cloud, 230, 66, 99);
	viewer.addPointCloud(cloud_Out, sig, "cloud");
	//设置大小
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5);
	pcl::io::savePCDFileASCII("D://0718box//0718-04_test.pcd", *cloud_Out);
	//直到关闭窗口结束循环
	while (!viewer.wasStopped())
	{
    
		//每次循环调用内部的重绘函数
		viewer.spinOnce();
	}
}

10、从点云中添加和删除点

//从点云中添加和删除点
void pcd_del()
{
    
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile<pcl::PointXYZ>("D://0718box//0718-04.pcd", *cloud);
	pcl::PointCloud<pcl::PointXYZ>::iterator index = cloud->begin();

	cloud->erase(index, index + 999);//区间删除

	index = cloud->begin() + 999;//单个删除
	cloud->erase(cloud->begin());
	//可视化
	pcl::visualization::PCLVisualizer viewer("Cloud Viewer");//创建对象
	viewer.setBackgroundColor(0.05, 0.05, 0.05, 0);//背景为白色

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> sig(cloud, 230, 66, 99);
	viewer.addPointCloud(cloud, sig, "cloud");
	//设置大小
	//viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1);
	//直到关闭窗口结束循环
	while (!viewer.wasStopped())
	{
    
		//每次循环调用内部的重绘函数
		viewer.spinOnce();
	}

}

void pcd_add()
{
    
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile<pcl::PointXYZ>("D://0718box//0718-04_test.pcd", *cloud);
	pcl::PointCloud<pcl::PointXYZ>::iterator index = cloud->begin();
	pcl::PointXYZ point = {
     1,1,1 };
	//std::vector<int> index = { 1, 3, 5, 7, 8, 11, 56, 77 };
	cloud->insert(cloud->begin() + 7, point);//在索引号为7的位置1上插入一点,原来的点后移一位
	cloud->push_back(point);//在点云最后面插入一点
	std::cout << cloud->points[7].x<<std::endl;
	//打印输出点云数据
	for (size_t i = 0; i < cloud->points.size(); ++i)
	{
    
		std::cout << cloud->points[i].x << "  " << cloud->points[i].y << "  " << cloud->points[i].z << std::endl;
	}

	//可视化
	pcl::visualization::PCLVisualizer viewer("Cloud Viewer");//创建对象
	viewer.setBackgroundColor(0.05, 0.05, 0.05, 0);//背景为白色

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> sig(cloud, 230, 66, 99);
	viewer.addPointCloud(cloud, sig, "cloud");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5);

	//直到关闭窗口结束循环
	while (!viewer.wasStopped())
	{
    
		//每次循环调用内部的重绘函数
		viewer.spinOnce();
	}
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/anywhereyouare/article/details/125888447

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签