c/c++中一些不常用但有用的知识

1.变长数组

bool fun(int cnt)
{
    unsigned char data[cnt];
    return true;
}

         在 C 语言中,变长数组(Variable Length Arrays,VLA)是 C99 标准引入的特性,允许使用变量来定义数组的长度。因此,在 C 版本的代码中,可以使用您提供的方式来动态申请数组,前提是编译器支持 C99 标准。

2.c++的函数作为回调函数传给c

class UdpTask : public QObject
{
    Q_OBJECT

public:
    static UdpTask &instance()
    {
        static UdpTask self;
        return self;
    }
     void registration();

signals:
    void sendImage(QImage image);
private:
    explicit UdpTask(QObject *parent = nullptr);
    //~UdpTask();
    UdpTask(const UdpTask &self);
    const UdpTask &operator=(const UdpTask &self);
    static void receivedDataHandle(int frame_id, void* buffer, int buffer_len);
   
};
void UdpTask::receivedDataHandle(int frame_id, void* buffer, int buffer_len)
{
    /* 发送信号 */
    memcpy(instance().image->bits(), &buffer, buffer_len);
    emit instance().sendImage(*instance().image);
}
extern "C" {
    // C 语言写的回调注册函数
typedef void(*eth_recv_func_t)(int frame_id, void* buffer, int buffer_len);
ETHTRANSFERLIB_API int StartReceiveData(eth_recv_func_t func, int data_size);
}

void UdpTask::registration(int len)
{
    StartReceiveData(receivedDataHandle, len);
}

这里用了 C++ 类的静态函数作为回调函数,

静态的单例函数 instance() 用于获取 UdpTask 的唯一实例。

是为了在静态函数中调用其他变量(如image,sendimage等),否则其他变量都需要申请为静态的。

3.动态加载dll

当某些静态库的函数名称与头文件中的声明不匹配时,如下图。一般为编译不规范没有加def文件导致的,我们利用下面命令读一下dll中的信息

dumpbin /headers your_dll_file.dll

 这是一段利用qt加载动态库的方法

#include <QLibrary>
#include <QDebug>

int main() 
{
    // 创建 QLibrary 对象并加载动态库
    QLibrary myLib("./lib/xxx.dll");
    if (myLib.load()) 
    {
        // 获取函数地址 可以用之前出现乱码字符串来找到真正的函数
        void* symbol = myLib.resolve("?myFunctionName@@YAXXZ");
        //这样就可以调用了
        symbol();
        // 卸载动态库
        myLib.unload();
    } 
    return 0;
}

4.malloc(0)

因为C标准规定,malloc(0)应该返回一个指向合法且可以被free()释放的内存块的指针,个人理解参照单片机实现动态内存管理_单片机内存池设计-CSDN博客,事实上会将这个内存块的维护信息如是否有效长度(虽然是0),list 信息等申请出来。

5.关于中断函数

1)ISR 不能返回一个值

2) ISR 不能传递参数。

3) 在许多的处理器/编译器中,浮点一般都是不可重入的。

4)printf()一般都是不可重入的。

6.有符号加减的表达式

void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6) ? puts("> 6") : puts("<= 6");
} 

是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6

7.a++和++a

a++是后缀递增运算符,它会先使用变量的值,然后再将变量的值加1。例如,int a = 5; int b = a++;b的值为5,而a的值变为6。

++a是前缀递增运算符,它会先将变量的值加1,然后再使用变量的值。例如,int a = 5; int b = ++a;b的值为6,而a的值也是6。

总结起来:

  • a++会先使用变量的值,然后再递增变量的值。
  • ++a会先递增变量的值,然后再使用递增后的值。

8.delete[]是怎样知道数组长度的? 

delete,free向前偏移多少(看是怎么设计的)就知道了 参照单片机实现动态内存管理_单片机内存池设计-CSDN博客 

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值