当前位置: 首页 > news >正文

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<3>

在这里插入图片描述

大家好啊,我是小象٩(๑òωó๑)۶
我的博客:Xiao Xiangζั͡ޓއއ

很高兴见到大家,希望能够和大家一起交流学习,共同进步
在这里插入图片描述
今天我们来对上一节做一些小补充,了解学习一下assert断言,指针的使用和传址调用等…

目录

  • 一、assert 断言
  • 二、指针的使用和传址调用
    • 2.1 strlen的模拟实现
    • 2.2 传值调用和传址调用

一、assert 断言

assert 断言是一种在程序中用于检查某个条件是否为真的语句。它基于这样的假设:在程序的某个特定点上,某个条件应该始终成立。如果这个条件确实为真,程序将继续正常执行;但如果条件为假,断言就会失败,通常会导致程序抛出一个AssertionError 异常,从而中断程序的执行。这有助于快速定位程序中的错误,尤其是在开发和测试阶段。
assert.h 头文件定义了宏 assert() ,用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。这个宏常常被称为“断言”。

作用:
调试辅助:帮助开发者快速定位程序中的逻辑错误。例如,在一个计算平均值的函数中,可以使用断言来确保传入的列表不为空,因为计算空列表的平均值是没有意义的,这能让开发者在函数被错误调用时迅速发现问题。
代码契约:在编写函数或方法时,断言可以用于定义函数的前置条件和后置条件,形成一种代码契约。比如,一个除法函数,使用断言可以确保除数不为零这个前置条件,明确函数的使用规则,也让其他阅读和使用代码的人清楚函数的约束条件。
测试验证:在测试用例中,断言是验证测试结果是否符合预期的重要手段。比如在单元测试中,使用断言来检查函数的返回值是否等于预期值,或者检查某个对象的属性是否处于特定状态,从而判断测试是否通过。

assert(p != NULL);

上面代码在程序运行到这一行语句时,验证变量 p 是否等于 NULL 。如果确实不等于 NULL ,程序继续运行,否则就会终止运行,并且给出报错信息提示。
assert() 宏接受⼀个表达式作为参数。如果该表达式为真(返回值⾮零), assert() 不会产生任何作用,程序继续运行。如果该表达式为假(返回值为零), assert() 就会报错,在标准错误流 stderr 中写入一条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。

assert() 的使用对程序员是非常友好的,使用assert()
有几个好处:它不仅能自动标识文件和出问题的行号,还有一种无需更改代码就能开启或关闭 assert()的机制。如果已经确认程序没有问题,不需要再做断言,就在 #include <assert.h> 语句的前面,定义⼀个宏 NDEBUG 。

#define NDEBUG
#include <assert.h>

然后,重新编译程序,编译器就会禁用文件中所有的 assert() 语句。如果程序又出现问题,可以移除这条 #define NDEBUG 指令(或者把它注释掉),再次编译,这样就重新启用了 assert() 语句。
assert() 的缺点是,因为引入了额外的检查,增加了程序的运行时间。
一般我们可以在 Debug 中使用,在 Release 版本中选择禁用 assert 就行,在 VS 这样的集成开发环境中,在 Release 版本中,直接就是优化掉了。这样在debug版本写有利于程序员排查问题,在 Release 版本不影响用户使用时程序的效率。

二、指针的使用和传址调用

2.1 strlen的模拟实现

库函数strlen的功能是求字符串长度,统计的是字符串中 \0 之前的字符的个数。
函数原型如下:

size_t strlen ( const char * str );

参数str接收一个字符串的起始地址,然后开始统计字符串中 \0 之前的字符个数,最终返回长度。
如果要模拟实现只要从起始地址开始向后逐个字符的遍历,只要不是 \0 字符,计数器就+1,这样直到 \0 就停止。
举个例子:

int my_strlen(const char* str)
{int count = 0;assert(str);while (*str){count++;str++;}return count;
}
int main()
{int len = my_strlen("abcdef");printf("%d\n", len);return 0;
}

2.2 传值调用和传址调用

学习指针的目的是使用指针解决问题,那什么问题,非指针不可呢?
例如:写一个函数,交换两个整型变量的值
我们可能写出这样的代码:

#include <stdio.h>
void Swap1(int x, int y)
{int tmp = x;x = y;y = tmp;
}
int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);printf("交换前:a=%d b=%d\n", a, b);Swap1(a, b);printf("交换后:a=%d b=%d\n", a, b);return 0;
}

我们发现其实没产生交换的效果,这是为什么呢?
在这个代码里,Swap1 函数采用的是传值调用。传值调用的特点是,函数接收的是实参的副本,而不是实参本身。具体来说:
在 main 函数中调用 Swap1(a, b) 时,a 和 b 的值会被复制一份,分别传递给 Swap1 函数的形参 x 和 y。
在 Swap1 函数内部,虽然 x 和 y 的值进行了交换,但这只是对副本的操作,并不会影响到 main 函数中原始的 a 和 b 的值。

结论:实参传递给形参的时候,形参会单独创建一份临时空间来接收实参,对形参的修改不影响实参。
所以Swap1是失败的了。

那怎么办呢?
我们现在要解决的就是当调用Swap函数的时候,Swap函数内部操作的就是main函数中的a和b,直接将a和b的值交换了。那么就可以使用指针了,在main函数中将a和b的地址传递给Swap函数,Swap函数里边通过地址间接的操作main函数中的a和b,并达到交换的效果就好了。
像这样:

#include <stdio.h>
void Swap2(int* px, int* py)
{int tmp = 0;tmp = *px;*px = *py;*py = tmp;
}
int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);printf("交换前:a=%d b=%d\n", a, b);Swap2(&a, &b);printf("交换后:a=%d b=%d\n", a, b);return 0;
}

我们可以看到实现成Swap2的方式,顺利完成了任务,这里调用Swap2函数的时候是将变量的地址传递给了函数,这种函数调用方式叫:传址调用。
传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采用传值调用。如果函数内部要修改主调函数中的变量的值,就需要传址调用。

好了,这节内容便结束了,附上这两节所写的代码:

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>//int main()
//{
//	int a = 10;
//	//int* pa = &a;//int*
//	//char* pc = &a;
//	void* pv2 = &a;
//	//*pv2;
//	//pv2++;
//
//	char ch = 'w';
//	//char*pc = &ch;
//	//int* pi = &ch;
//	void* pv = &ch;//char*
//	//*pv;//err
//	return 0;
//}//void test(void* pv)
//{
//	//pv在使用的时候,会强制类型转换,然后去使用
//	//
//}
//
//
//int main()
//{
//	int a = 10;
//	test(&a);
//	char c = 'w';
//	test(&c);
//	double d = 3.14;
//	test(&d);
//
//	return 0;
//}//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int i = 0;
//	int sz = sizeof(arr) / sizeof(arr[0]);//10
//	int* p = &arr[0];
//
//	//for (i = 0; i < sz; i++)
//	//{
//	//	*(p + i) = 0;
//	//}
//
//	for (i = 0; i < sz; i++)
//	{
//		scanf("%d", p + i);
//	}
//
//
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", *(p + i));
//	}
//
//	return 0;
//}//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int i = 0;
//	int sz = sizeof(arr) / sizeof(arr[0]);//10
//	int* p = &arr[sz-1];
//
//	for (i = 0; i < sz; i++)
//	{
//		*(p - i) = i+1;
//	}
//
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//
//	return 0;
//}
//
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int i = 0;
//	int sz = sizeof(arr) / sizeof(arr[0]);//10
//	int* p = &arr[sz - 1];
//
//	for (i = 0; i < sz; i++)
//	{
//		*p = i + 1;
//		p--;
//	}
//
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//
//	return 0;
//}//int main()
//{
//	int arr[10] = { 0 };
//	int n = &arr[0] - &arr[9];
//	printf("%d\n", n);
//
//	return 0;
//}//int main()
//{
//	int arr[10] = { 0 };
//	char ch[5] = {0};
//	printf("%d\n", & arr[9] - &ch[0]);//err
//
//	return 0;
//}#include <string.h>
//strlen 是求字符串长度,统计的是字符串中\0之前的字符个数//int main()
//{
//	char arr[] = "abcdef";
//	//a b c d e f \0
//	//数组名其实是数组首元素的地址
//	//arr == &arr[0]
//	size_t len = strlen(arr);//6
//	printf("%zd\n", len);
//
//	return 0;
//}//size_t my_strlen(char* str)
//{
//	size_t count = 0;
//	while (*str != '\0')
//	{
//		count++;
//		str++;
//	}
//	return count;
//}
//
//size_t my_strlen(char* str)
//{
//	char* start = str;
//	while (*str != '\0')
//		str++;
//	return str - start;//指针-指针
//}
//
//
//int main()
//{
//	char arr[] = "abcdefghi";
//	//a b c d e f \0
//	//数组名其实是数组首元素的地址
//	//arr == &arr[0]-- char*
//	size_t len = my_strlen(arr);//6
//	printf("%zd\n", len);
//
//	return 0;
//}
////
//int main()
//{
//	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	int* p = arr;
//	while (p < &arr[sz])
//	{
//		printf("%d ", *p);
//		p++;
//	}
//
//
//
//	//int i = 0;
//	//int* p = arr;//p = &arr[0];
//	//for (i = 0; i < sz; i++)
//	//{
//	//	printf("%d ", *(p + i));
//	//}
//
//
//	//for (i = 0; i < sz; i++)
//	//{
//	//	printf("%d ", arr[i]);
//	//}
//
//
//	return 0;
//}//const 是常属性-不能改变的属性//int main()
//{
//	const int a = 10;
//	//a变成了常变量,a的本质还是变量,但是因为被const修饰,所以不能改变
//	//a = 1;//err
//	int* p = &a;
//	*p = 1;
//
//	printf("%d\n", a);
//
//	return 0;
//}//int main()
//{
//	const int n = 10;
//	int arr[n];
//
//	return 0;
//}//int main()
//{
//	const int a = 10;
//	//a变成了常变量,a的本质还是变量,但是因为被const修饰,所以不能改变
//	//a = 1;//err
//	const int* p = &a;
//	*p = 1;
//
//	printf("%d\n", a);
//
//	return 0;
//}//const 修饰指针变量
//可以放在*的左边,也可以放在*的右边,意义是不一样的
//const 放在*的左边表示指针指向的内容,不能通过指针来改变了,但是指针变量本身是可以改变的
//const 放在*的右边表示指针变量本身不能被修改了,但是指针指向的内容是可以通过指针变量来改变的//int main()
//{
//	int a = 100;
//	int b = 1000;
//	int* const p = &a;
//	*p = 0;//ok
//	p = &b;//err
//
//	return 0;
//}//int main()
//{
//	int a = 100;
//	int b = 1000;
//	const int * p = &a;
//	//*p = 0;//err
//	p = &b;
//
//	return 0;
//}//int main()
//{
//	int a = 100;
//	int b = 1000;
//
//	const int* const p = &a;
//
//	return 0;
//}
//
//
//
////int main()
//{
//	int* p;//局部变量不初始化的时候,里边放的是随机值
//
//	*p = 20;//非法访问,p就是野指针
//
//	return 0;
//}//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int* p = arr;
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	int i = 0;
//	for (i = 0; i <= sz; i++)
//	{
//		*p = i;
//		p++;
//	}
//
//	return 0;
//}
////
//int* test()
//{
//	int n = 100;
//	return &n;
//}
//
//int main()
//{
//	int* p = test();
//	printf("%d\n", *p);
//
//	return 0;
//}//
//int main()
//{
//	int* p = NULL;
//	if(p != NULL)
//		*p = 200;
//
//	return 0;
//}
//#define NDEBUG
#include <assert.h>//int main()
//{
//	int arr[10] = { 1,2,3,4,5 };
//	int* p = arr;
//	assert(p != NULL);
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		printf("%d ", *p);
//		p++;
//	}
//	//
//	return 0;
//}//int main()
//{
//	int arr[10] = { 1,2,3,4,5 };
//	int* p = arr;
//	assert(p != NULL);
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		printf("%d ", *p);
//		p++;
//	}
//	
//	return 0;
//}//int main()
//{
//	int a = 5;
//	assert(a != 5);
//
//	return 0;
//}
//
//size_t my_strlen(const char* str)
//{
//	size_t count = 0;
//	assert(str != NULL);
//
//	while (*str)//'\0' -- 0
//	{
//		count++;
//		str++;
//	}
//	return count;
//}
//
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len =  my_strlen(arr);
//	printf("%zd\n", len);
//
//	return 0;
//}//void Swap1(int x, int y)
//{
//	int z = 0;
//	z = x;
//	x = y;
//	y = z;
//}
//
//int main()
//{
//	int a = 0;
//	int b = 0;
//	scanf("%d %d", &a, &b);
//	//写一个函数,交换a和b的内容
//
//	printf("交换前:a = %d b = %d\n", a, b);
//	Swap1(a, b);
//	printf("交换后:a = %d b = %d\n", a, b);
//	
//	return 0;
//}//int main()
//{
//	int a = 10;
//	int* p = &a;
//	*p = 20;
//	return 0;
//}//void Swap2(int* pa, int* pb)
//{
//	int z = 0;
//	z = *pa;//z = a
//	*pa = *pb;//a = b
//	*pb = z;//b = z
//}
//
//int main()
//{
//	int a = 0;
//	int b = 0;
//	scanf("%d %d", &a, &b);
//	//写一个函数,交换a和b的内容
//
//	printf("交换前:a = %d b = %d\n", a, b);
//	Swap2(&a, &b);
//	printf("交换后:a = %d b = %d\n", a, b);
//	
//	return 0;
//}//int Add(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	int a = 3;
//	int b = 5;
//	int r = Add(a, b);//传值调用
//	printf("%d\n", r);
//	return 0;
//}//    3      5
int Max(int x, int y)
{return (x > y ? x : y);
}int main()
{int a = 3;int b = 5;int r = Max(a, b);//传值调用printf("%d\n", r);return 0;
}

相关文章:

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<3>

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。 今天我们来对上一节做一些小补充&#xff0c;了解学习一下assert断言&#xff0c;指针的使用和传址调用…...

(三)QT——信号与槽机制——计数器程序

目录 前言 信号&#xff08;Signal&#xff09;与槽&#xff08;Slot&#xff09;的定义 一、系统自带的信号和槽 二、自定义信号和槽 三、信号和槽的扩展 四、Lambda 表达式 总结 前言 信号与槽机制是 Qt 中的一种重要的通信机制&#xff0c;用于不同对象之间的事件响…...

Qt 5.14.2 学习记录 —— 이십이 QSS

文章目录 1、概念2、基本语法3、给控件应用QSS设置4、选择器1、子控件选择器2、伪类选择器 5、样式属性box model 6、实例7、登录界面 1、概念 参考了CSS&#xff0c;都是对界面的样式进行设置&#xff0c;不过功能不如CSS强大。 可通过QSS设置样式&#xff0c;也可通过C代码…...

Hot100之哈希

1两数之和 题目 思路解析 解法1--两次循环 解法2--哈希表一次循环 代码 解法1--两次循环 class Solution {public int[] twoSum(int[] nums, int target) {int nums1[] new int[2];int length nums.length;for (int i 0; i < length; i) {for (int j i 1; j < …...

油漆面积——蓝桥杯

1.题目描述 X 星球的一批考古机器人正在一片废墟上考古。 该区域的地面坚硬如石、平整如镜。 管理人员为方便&#xff0c;建立了标准的直角坐标系。 每个机器人都各有特长、身怀绝技。它们感兴趣的内容也不相同。 经过各种测量&#xff0c;每个机器人都会报告一个或多个矩…...

深度解析:网站快速收录与服务器性能的关系

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/37.html 网站快速收录与服务器性能之间存在着密切的关系。服务器作为网站运行的基础设施&#xff0c;其性能直接影响到搜索引擎对网站的抓取效率和收录速度。以下是对这一关系的深度解析&am…...

925.长按键入

目录 一、题目二、思路三、解法四、收获 一、题目 你的朋友正在使用键盘输入他的名字 name。偶尔&#xff0c;在键入字符 c 时&#xff0c;按键可能会被长按&#xff0c;而字符可能被输入 1 次或多次。 你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字&am…...

JavaScript 中的 var 和 let :关键区别与使用建议

在 JavaScript 开发中&#xff0c;变量声明是基础且重要的部分。 var 和 let 都是用于声明变量的关键字&#xff0c;但它们在作用域、变量提升、重复声明等方面存在显著差异。本文将详细探讨它们的区别&#xff0c;并给出使用建议。 1. 作用域 1.1 var 的作用域 …...

寒假刷题Day19

一、923. 三数之和的多种可能 class Solution { public:int threeSumMulti(vector<int>& arr, int target) {const int MOD 1000000007; // 正确的模数long long ans 0; // 使用 long long 防止溢出std::sort(arr.begin(), arr.end());for (size_t i 0; i < a…...

写好简历的三个关键认知

在当今竞争激烈的就业市场中&#xff0c;一份优秀的简历往往是敲开理想企业大门的第一把钥匙。然而&#xff0c;很多求职者在写简历时往往不得要领&#xff0c;让宝贵的机会从指间溜走。今天&#xff0c;让我们一起探讨如何提升简历写作水平&#xff0c;让你的职业之路走得更顺…...

工具的应用——安装copilot

一、介绍Copilot copilot是一个AI辅助编程的助手&#xff0c;作为需要拥抱AI的程序员可以从此尝试进入&#xff0c;至于好与不好&#xff0c;应当是小马过河&#xff0c;各有各的心得。这里不做评述。重点在安装copilot的过程中遇到了一些问题&#xff0c;然后把它总结下&…...

Koa 基础篇(二)—— 路由与中间件

let app new Koa() router.get(“/”,async ctx > { ctx.body “hello koa router” }) app.use(router.routes()) app.use(router.allowedMethods()) app.listen(3000) 运行项目&#xff0c;在浏览器访问本地3000端口&#xff0c;在页面上就会看到输出的语句。这就…...

帆软 FCA -业务分析师认证学习

帆软 FCA -业务分析师认证学习 认证概述 适合人群 企业中有需求管理、指标梳理、业务逻辑梳理、项目规划等需求的人员&#xff0c;想提升综合数据能力、推进数据应用落地的业务/IT骨干。 具体-FCA-业务分析理论 考试要求&#xff1a; FCA-业务分析理论考试- 费用&#xff1a…...

Miniconda 安装及使用

文章目录 前言1、Miniconda 简介2、Linux 环境说明2.1、安装2.2、配置2.3、常用命令2.4、常见问题及解决方案 前言 在 Python 中&#xff0c;“环境管理”是一个非常重要的概念&#xff0c;它主要是指对 Python 解释器及其相关依赖库进行管理和隔离&#xff0c;以确保开发环境…...

solidity高阶 -- Eth支付

在区块链的世界里&#xff0c;智能合约是实现去中心化应用&#xff08;DApp&#xff09;的核心技术之一。Solidity 是一种专门用于编写以太坊智能合约的编程语言&#xff0c;它可以帮助开发者构建各种功能&#xff0c;包括支付功能。 今天&#xff0c;我们就来探讨如何使用 Sol…...

深入理解Java中的String

前言 在Java中&#xff0c;String类是一个非常重要的内置类&#xff0c;用于处理字符串数据。字符串是不可变的&#xff08;immutable&#xff09;&#xff0c;这意味着一旦创建&#xff0c;字符串的内容不能被修改。作为Java中最为基础和常用的类之一&#xff0c;String类在内…...

洛谷 P1734 最大约数和 C语言

P1734 最大约数和 - 洛谷 | 计算机科学教育新生态 题目描述 选取和不超过 S 的若干个不同的正整数&#xff0c;使得所有数的约数&#xff08;不含它本身&#xff09;之和最大。 输入格式 输入一个正整数 S。 输出格式 输出最大的约数之和。 输入输出样例 输入 #1复制 …...

Golang 执行流程分析

文章目录 1. 编译和运行2. 编译和运行说明 1. 编译和运行 如果是对源码编译后&#xff0c;再执行&#xff0c;Go的执行流程如下图 如果我们是对源码直接 执行 go run 源码&#xff0c;Go的执行流程如下图 两种执行流程的方式区别 如果先编译生成了可执行文件&#xff0c;那么…...

python学opencv|读取图像(五十一)使用修改图像像素点上BGR值实现图像覆盖效果

【1】引言 前序学习了图像的得加方法&#xff0c;包括使用add()函数直接叠加BGR值、使用bitwise()函数对BGR值进行按位计算叠加和使用addWeighted()函数实现图像加权叠加至少三种方法。文章链接包括且不限于&#xff1a; python学opencv|读取图像&#xff08;四十二&#xff…...

Flask数据的增删改查(CRUD)_flask删除数据自动更新

查询年龄小于17的学生信息 Student.query.filter(Student.s_age < 17) students Student.query.filter(Student.s_age.__lt__(17))模糊查询&#xff0c;使用like&#xff0c;查询姓名中第二位为花的学生信息 like ‘_花%’,_代表必须有一个数据&#xff0c;%任何数据 st…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...