ardupilot开发 --- C嘎嘎 篇


长生不老?三界六道不就毁在这4个字上?

溜撒点一起上吧

小生之前拥有C语言的基础,大学时学过机遇MFC的C++编程,硕士时对matlab语言比较熟悉,亦接触过一个开源的C++飞控源代码项目,并修改过,因此学习C++我采用了查漏补缺和拾遗的方式,即遇到不会的、陌生的、就查、就记、就学,如此而已,希望C++待我如初恋,QAQ,我们开始吧,好记性不如烂笔头,书山有路勤为径,学海无涯苦作舟!!

cout和cin的使用,标准输入输出

C++ 的 I/O 发生在流中,流是字节序列。如果字节流是从设备(如键盘、磁盘驱动器、网络连接等)流向内存,这叫做输入操作。如果字节流是从内存流向设备(如显示屏、打印机、磁盘驱动器、网络连接等),这叫做输出操作。

C++ 基本的输入输出 | 菜鸟教程

<< 和 >> 的使用

int a = 21;

int c ;

c = a;

c <<= 2;

cout << "Line 7 - <<= 运算符实例,c 的值 = : " <<c<< endl ;

数据类型(函数)模板的使用:

命名空间的使用,std命名空间

语句块

#include

using namespace std;

int main()

{

{

int x=1;

cout << x << endl;

{

cout << x << endl;

int x=2;

cout << x <<endl;

{

cout << x <<endl;

int x=3;

cout << x <<endl;

}

cout << x <<endl;

}

cout << x << endl;

}

return 0;

输出结果 1 1 2 2 3 2 1

在第一例每个语句块中,虽然变量名都一样,但是int x= ;之后x就变成另外一个变量了

且生存周期仅限于当前的语句块中

new 的使用

引用 &

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。试想变量名称是变量附属在内存位置中的标签,您可以把引用当成是变量附属在内存位置中的第二个标签。因此,您可以通过原始变量名称或引用来访问变量的内容。例如:

#include

using namespace std;

int main ()

{

// 声明简单的变量

int i;

// 声明引用变量

int& r = i;

i = 5;

cout << "Value of i : " << i << endl;

cout << "Value of i reference : " << r << endl;

return 0;

}

当上面的代码被编译和执行时,它会产生下列结果:

Value of i : 5

Value of i reference : 5

引用通常用于函数参数列表和函数返回值。

用于函数参数:

#include

using namespace std;

// 函数声明

void swap(int& x, int& y);

int main ()

{

// 局部变量声明

int a = 100;

int b = 200;

cout << "交换前,a 的值:" << a << endl;

cout << "交换前,b 的值:" << b << endl;

/* 调用函数来交换值 */

swap(a, b);

cout << "交换后,a 的值:" << a << endl;

cout << "交换后,b 的值:" << b << endl;

return 0;

}

// 函数定义

void swap(int& x, int& y)

{

int temp;

temp = x; /* 保存地址 x 的值 /
x = y; /
把 y 赋值给 x /
y = temp; /
把 x 赋值给 y */

return;

}

用于函数返回值:

通过使用引用来替代指针,会使 C++ 程序更容易阅读和维护。C++ 函数可以返回一个引用,方式与返回一个指针类似。

当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。例如,请看下面这个简单的程序:

#include

using namespace std;

double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};

double& setValues(int i) {

double& ref = vals[i];

return ref; // 返回第 i 个元素的引用,ref 是一个引用变量,ref 引用 vals[i],最后再返回 shit。

}

// 要调用上面定义函数的主函数

int main ()

{

cout << "改变前的值" << endl;

for ( int i = 0; i < 5; i++ )

{

cout << "vals[" << i << "] = ";

cout << vals[i] << endl;

}

setValues(1) = 20.23; // 改变第 2 个元素

setValues(3) = 70.8; // 改变第 4 个元素

cout << "改变后的值" << endl;

for ( int i = 0; i < 5; i++ )

{

cout << "vals[" << i << "] = ";

cout << vals[i] << endl;

}

return 0;

}

共用体union

union中的3个数据成员共享1块内存,且3个数据成员的内存起始地址一样,这在内存紧张的情况下非常有用。

union中最多只有一个数据成员是有意义的。

共用体(参考"共用体"百科词条)是一种特殊形式的变量,使用关键字union来定义

共用体声明和共用体变量定义与结构体十分相似。其形式为:

union 共用体名{

数据类型 成员名;

数据类型 成员名;

...

} 变量名;

共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。

在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。

几种定义方法:

union u_type1 { int i; double d; char c[10]; };

u_type1 u1; u1.i = 1;

union u_type2 { int i; double d; char c[10]; } u2;

union { int i; double d; char c[10]; } u3;

类对象的赋值:operator函数

对象的初始化可以在定义时将初始化参数传递给构造函数。

也可以什么都不传,后续再赋值,如:

vpBasicFeature *current_s;//定义对象

current_s = (*it_s);//赋值

此时这个赋值符号=会调用类中的这个operator函数:

/*!

Copy operator.

*/

vpBasicFeature &vpBasicFeature::operator=(const vpBasicFeature &f)

{

s = f.s;

dim_s = f.dim_s;

nbParameters = f.nbParameters;

deallocate = f.deallocate;

if (flags)

delete[] flags;

flags = new bool[nbParameters];

for (unsigned int i = 0; i < nbParameters; i++)

flags[i] = f.flags[i];

return (*this);

}

Ubuntu C++程序中执行shell命令

文言一心

待续...

Linux中的C++编译器

在Linux系统中,C++常用的编译器主要有以下几种,每种编译器都有其独特的特点和优势:

  • GNU Compiler Collection (GCC)
    特点
    • 广泛使用:GCC是Linux系统中最常用的编译器之一,支持C、C++、Ada、Fortran等多种编程语言。
    • 兼容性:GCC能够支持多种不同的目标体系结构,如X86、ARM、PowerPC等,同时它也能运行在不同的操作系统上,如Linux、Solaris、Windows等。
    • 标准库:GCC安装时会同时安装C++的标准库,使得开发者可以方便地使用标准库中的功能。
    • 优化能力:GCC提供了多种编译优化选项,可以帮助开发者生成更高效的代码。
  • G++
  • Clang
  • Intel C++ Compiler (ICC)
  • Turbo C++ Compiler

总结:

在Linux系统中,GCC因其广泛的兼容性和强大的优化能力而成为最常用的C++编译器。Clang则以其快速、占用内存少和强大的静态分析能力受到开发者的青睐。ICC则适合对性能有极高要求的开发者,特别是在使用Intel处理器时。而Turbo C++虽然主要用于Windows环境,但在Linux下通过特定工具也能使用,且适合初学者学习C++语言。开发者可以根据自己的需求和偏好选择合适的编译器。

#include<> 和 #include" "

#include指令用于导入其他头文件到当前文件位置。

假如编译器使用的是gcc,那么gcc在执行 #include<> 和 #include" "时到底做了什么?

什么时候用 #include<>?什么时候用 #include" " ?

  • #include<> 的搜索路径包括
    默认配置下,执行#include<>时编译器gcc会到这几个目录下寻找头文件:
    • 编译器设置的include路径
      • /usr/include:C/C++语言标准库的头文件安装路径。
      • /usr/local/include:用户手动安装的第三方库的头文件安装路径。
    • 环境变量包含的路径
      • CPLUS_INCLUDE_PATH,对于C++,
      • C_INCLUDE_PATH,对于C
    • 预配置的路径
      与编译器的安装和配置有关,如 /usr/lib/gcc/x86_64-linux-gnu/版本号/include
    • gcc -I指定的额外路径,如:
      main.c:#include <myheader.h>
      myheader.h位于:/home/user/include
      gcc -I/home/user/include main.c -o main
  • #include" " 的搜索路径包括
    在当前文件所在的目录、子目录中查找头文件;若找不带则到标准库目录中查找。

扩展知识点:

  • C/C++标准库;
  • C/C++标准库的存放路径;
  • GCC 是Linux系统中最常用的C/C++编译器之一;
  • ‌在Linux中,安装gcc/g++时,通常会同时安装C和C++的标准库,标准库的库文件(.so, .o)会被安装到/usr/lib下,标准库的头文件(.hpp, .h)会被安装到/usr/include下;
  • 常用的C语言标准库如 stdio.h、stdlib.h、string.h、math.h 等;
  • 常用的C++标准库如 iostream、string、vector 等;
  • 一些与编译器有关的库可能会被编译器安装在/usr/lib/gcc/x86_64-linux-gnu/版本号/include;
  • 注意,#include<>、" "的搜索路径与环境变量PATH无关。PATH用于在Linux中指定在哪些目录中寻找可执行程序,便于让你在任何目录下都能执行已安装的程序而不需要加上绝对路径。
  • make的底层调用的是gcc吗?是的。
  • 可用pkg-config查找某库的安装路径(头文件、库文件)
  • 几个容易混淆的目录
    • usr/include 头文件
    • usr/lib 库文件
    • usr/bin 可执行程序(Linux中又称命令)

gcc/g++编译C++程序时常用的环境变量有哪些?

Linux中用gcc或g++编译C++程序时常用的环境变量有哪些?

在Linux系统中,使用gcc或g++编译C++程序时,常用的环境变量主要有以下几个:

  1. PATH :这是最基本的环境变量之一,用于指定系统在哪些目录中寻找可执行程序。对于gcc和g++来说,它们的可执行文件通常位于/usr/bin目录下。因此,确保/usr/bin目录在PATH环境变量中是很重要的。这样,在终端中输入gcc或g++命令时,系统就能找到并执行这些程序。

  2. CCCXX :这两个环境变量分别用于指定默认的C语言编译器和C++编译器。虽然它们不是直接由gcc或g++命令使用时必需的,但在某些自动化构建系统或脚本中,可能会根据这些环境变量来选择编译器。如果你希望默认使用gcc作为C语言编译器,g++作为C++编译器,可以将它们分别设置为gccg++

  3. CFLAGSCXXFLAGS :这两个环境变量分别用于指定编译C程序和C++程序时的编译选项。通过设置这些环境变量,你可以为gcc和g++命令提供默认的编译选项,而无需在每次编译时都手动指定它们。例如,你可以设置CFLAGSCXXFLAGS来包含调试信息、优化级别等。

  4. LD_LIBRARY_PATH :这个环境变量用于指定动态链接器在运行时搜索共享库(.so文件)的额外路径。如果你的程序依赖于非标准路径下的共享库,那么设置LD_LIBRARY_PATH可以帮助系统找到这些库。需要注意的是,LD_LIBRARY_PATH主要用于运行时库搜索,而不是编译时。编译时可以通过gcc或g++的-L选项来指定库文件的搜索路径。

  5. LIBRARY_PATH :这个环境变量在某些情况下用于指定链接器(ld)搜索静态库(.a文件)的路径。然而,在现代Linux系统中,它可能不是必需的,因为链接器通常会搜索/lib/usr/lib等标准路径。如果需要链接非标准路径下的静态库,建议直接使用gcc或g++的-L选项来指定搜索路径。

  6. C_INCLUDE_PATHCPLUS_INCLUDE_PATH :这两个环境变量分别用于指定C和C++编译器搜索头文件的额外路径。虽然gcc和g++命令本身提供了-I选项来指定头文件搜索路径,但设置这些环境变量可以作为一种全局或默认的方式来实现相同的目的。

VSCode 中F12无法打开#include中的头文件

vscode提示can not open source file xxx/xxx.h

解决办法:

  • 检查#include中的头文件路径是否正确。
  • 配置 c_cpp_properties.json 让 VSCode 能够正确智能感知、检查编译错误:
    • 为VSCode安装C/C++ 扩展插件;
    • Ctrl+Shift+P 输入 C/C++: Edit Configurations (UI)并打开;
    • 在配置界面中,找到 Include path 部分,并添加你的头文件所在的目录。
相关推荐
EmotionFlying24 天前
(11)(2.1.6) Hobbywing DroneCAN ESC(一)
copter·ardupilot·1024程序员节·电调和电机
EmotionFlying1 个月前
(11)(2.1.7) FETtec OneWire ESCs(一)
copter·ardupilot·电调和电机
EmotionFlying1 个月前
(11)(2.1.4) DroneCAN ESCs
外设硬件·copter·ardupilot
EmotionFlying2 个月前
(11)(2.1.3) KDE CAN ESCs(二)
外设硬件·copter·ardupilot
EmotionFlying2 个月前
(11)(2.1.2) DShot ESCs(四)
外设硬件·copter·ardupilot
EmotionFlying2 个月前
(11)(2.1.2) DShot ESCs(一)
外设硬件·copter·ardupilot
EmotionFlying3 个月前
(24)(24.2) Minim OSD快速安装指南(二)
外设硬件·copter·ardupilot
干了这碗汤4 个月前
ardupilot开发 --- 网络技术综述 篇
ardupilot
干了这碗汤4 个月前
ardupilot开发 --- Rpanion-server 篇
ardupilot