关键字库函数

关键字库函数

转自:https://leetcode-cn.com/leetbook/read/cpp-interview-highlights/ej3mx1/

sizeof和strlen的区别

  1. strlen 是头文件<cstring> 中的函数,sizeof 是 C++ 中的运算符。

  2. strlen 测量的是字符串的实际长度(其源代码如下),以 \0 结束。而 sizeof 测量的是字符数组的分配大小。

    strlen 源代码

    size_t strlen(const char *str) {size_t length = 0;while (*str++)++length;return length;
    }
    

    举例:

    #include <iostream>
    #include <cstring>using namespace std;int main()
    {char arr[10] = "hello";cout << strlen(arr) << endl; // 5cout << sizeof(arr) << endl; // 10return 0;
    }
    
  3. 若字符数组 arr 作为函数的形参,sizeof(arr)arr 被当作字符指针来处理,strlen(arr)arr 依然是字符数组,从下述程序的运行结果中就可以看出。

    #include <iostream>
    #include <cstring>using namespace std;void size_of(char arr[])
    {cout << sizeof(arr) << endl; // warning: 'sizeof' on array function parameter 'arr' will return size of 'char*' .cout << strlen(arr) << endl; 
    }int main()
    {char arr[20] = "hello";size_of(arr); return 0;
    }
    /*
    输出结果:
    8
    5
    */
    
  4. strlen 本身是库函数,因此在程序运行过程中,计算长度;而 sizeof 在编译时,计算长度;

  5. sizeof 的参数可以是类型,也可以是变量;strlen 的参数必须是 char* 类型的变量。

lambda 表达式(匿名函数)的具体应用和使用场景

lambda 表达式的定义形式如下:

[capture list] (parameter list) -> reurn type {function body
}

其中:

  • capture list:捕获列表,指 lambda 表达式所在函数中定义的局部变量的列表,通常为空,但如果函数体中用到了 lambda 表达式所在函数的局部变量,必须捕获该变量,即将此变量写在捕获列表中。捕获方式分为:引用捕获方式 [&]、值捕获方式 [=]
  • return type、parameter list、function body:分别表示返回值类型、参数列表、函数体,和普通函数一样。

举例:

lambda 表达式常搭配排序算法使用。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main()
{vector<int> arr = {3, 4, 76, 12, 54, 90, 34};sort(arr.begin(), arr.end(), [](int a, int b) { return a > b; }); // 降序排序for (auto a : arr){cout << a << " ";}return 0;
}
/*
运行结果:90 76 54 34 12 4 3
*/

explicit 的作用(如何避免编译器进行隐式类型转换)

作用:用来声明类构造函数是显示调用的,而非隐式调用,可以阻止调用构造函数时进行隐式转换。只可用于修饰单参构造函数,因为无参构造函数和多参构造函数本身就是显示调用的,再加上 explicit 关键字也没有什么意义。

隐式转换:

#include <iostream>
#include <cstring>
using namespace std;class A
{
public:int var;A(int tmp){var = tmp;}
};
int main()
{A ex = 10; // 发生了隐式转换return 0;
}

上述代码中,A ex = 10; 在编译时,进行了隐式转换,将 10 转换成 A 类型的对象,然后将该对象赋值给 ex,等同于如下操作:

为了避免隐式转换,可用 explicit 关键字进行声明:

#include <iostream>
#include <cstring>
using namespace std;class A
{
public:int var;explicit A(int tmp){var = tmp;cout << var << endl;}
};
int main()
{A ex(100);A ex1 = 10; // error: conversion from 'int' to non-scalar type 'A' requestedreturn 0;
}

static关键字

C和C++static的区别

  • 在 C 语言中,使用 static 可以定义局部静态变量、外部静态变量、静态函数

  • 在 C++ 中,使用 static 可以定义局部静态变量、外部静态变量、静态函数、静态成员变量和静态成员函数。因为 C++ 中有类的概念,静态成员变量、静态成员函数都是与类有关的概念。

static的作用

作用:

static 定义静态变量,静态函数。

  • 保持变量内容持久:static 作用于局部变量,改变了局部变量的生存周期,使得该变量存在于定义后直到程序运行结束的这段时间。
#include <iostream>
using namespace std;int fun(){static int var = 1; // var 只在第一次进入这个函数的时初始化var += 1;return var;
}int main()
{for(int i = 0; i < 10; ++i)cout << fun() << " "; // 2 3 4 5 6 7 8 9 10 11return 0;
}
  • 隐藏:static 作用于全局变量和函数,改变了全局变量和函数的作用域,使得全局变量和函数只能在定义它的文件中使用,在源文件中不具有全局可见性。(注:普通全局变量和函数具有全局可见性,即其他的源文件也可以使用。)

  • static 作用于类的成员变量和类的成员函数,使得类变量或者类成员函数和类有关,也就是说可以不定义类的对象就可以通过类访问这些静态成员。注意:类的静态成员函数中只能访问静态成员变量或者静态成员函数,不能将静态成员函数定义成虚函数。

#include<iostream>
using namespace std;class A
{
private:int var;static int s_var; // 静态成员变量
public:void show(){cout << s_var++ << endl;}static void s_show(){cout << s_var << endl;// cout << var << endl; // error: invalid use of member 'A::a' in static member function. 静态成员函数不能调用非静态成员变量。无法使用 this.var// show();  // error: cannot call member function 'void A::show()' without object. 静态成员函数不能调用非静态成员函数。无法使用 this.show()}
};
int A::s_var = 1;  // 静态成员变量在类外进行初始化赋值,默认初始化为 0int main()
{   // cout << A::sa << endl;    // error: 'int A::sa' is private within this contextA ex;ex.show();A::s_show();
}

static在类中使用的注意事项(定义、初始化和使用)

static 静态成员变量

  1. 静态成员变量是在类内进行声明,在类外进行定义和初始化,在类外进行定义和初始化的时候不要出现 static 关键字和private、public、protected 访问规则。

  2. 静态成员变量相当于类域中的全局变量,被类的所有对象所共享,包括派生类的对象。

  3. 静态成员变量可以作为成员函数的参数,而普通成员变量不可以。

    #include <iostream>
    using namespace std;class A
    {
    public:static int s_var;int var;void fun1(int i = s_var); // 正确,静态成员变量可以作为成员函数的参数void fun2(int i = var);   //  error: invalid use of non-static data member 'A::var'
    };
    int main()
    {return 0;
    }
    
  4. 静态数据成员的类型可以是所属类的类型,而普通数据成员的类型只能是该类类型的指针或引用。

    #include <iostream>
    using namespace std;class A
    {
    public:static A s_var; // 正确,静态数据成员A var;          // error: field 'var' has incomplete type 'A'A *p;           // 正确,指针A &var1;        // 正确,引用
    };int main()
    {return 0;
    }
    

static 静态成员函数:

  1. 静态成员函数不能调用非静态成员变量或者非静态成员函数,因为静态成员函数没有 this 指针。静态成员函数做为类作用域的全局函数。
  2. 静态成员函数不能声明成虚函数virtualconst 函数和 volatile 函数。

static 全局变量和普通全局变量的异同

相同点:

  • 存储方式:普通全局变量和 static 全局变量都是静态存储方式。

不同点:

  • 作用域:普通全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,普通全局变量在各个源文件中都是有效的;静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。
  • 初始化:静态全局变量只初始化一次,防止在其他文件中使用。

const、define宏定义、typedef、inline

const作用及用法

作用

  • const 修饰成员变量,定义成 const 常量,相较于宏常量,可进行类型检查,节省内存空间,提高了效率。
  • const 修饰函数参数,使得传递过来的函数参数的值不能改变。
  • const 修饰成员函数,使得成员函数不能修改任何类型的成员变量(mutable 修饰的变量除外),也不能调用非 const 成员函数,因为非 const 成员函数可能会修改成员变量。

在类中的用法

const 成员变量:

  • const 成员变量只能在类内声明、定义,在构造函数初始化列表中初始化。
  • const 成员变量只在某个对象的生存周期内是常量,对于整个类而言却是可变的,因为类可以创建多个对象,不同类的 const 成员变量的值是不同的。因此不能在类的声明中初始化 const 成员变量,类的对象还没有创建,编译器不知道他的值。

const 成员函数

  1. 不能修改成员变量的值,除非有 mutable 修饰;只能访问成员变量。

  2. 不能调用非常量成员函数,以防修改成员变量的值。

#include <iostream>
using namespace std;class A
{
public:int var;A(int tmp) : var(tmp) {}void c_fun(int tmp) const // const 成员函数{var = tmp; // error: assignment of member 'A::var' in read-only object. 在 const 成员函数中,不能修改任何类成员变量。		fun(tmp); // error: passing 'const A' as 'this' argument discards qualifiers. const 成员函数不能调用非 const 成员函数,因为非 const 成员函数可能会修改成员变量。}void fun(int tmp){var = tmp;}
};int main()
{return 0;
}

define和const的区别

区别:

  • 编译阶段:define 是在编译预处理阶段进行替换,const 是在编译阶段确定其值。
  • 安全性:define 定义的宏常量没有数据类型,只是进行简单的替换,不会进行类型安全的检查;const 定义的常量是有类型的,是要进行判断的,可以避免一些低级的错误。
  • 内存占用:define 定义的宏常量,在程序中使用多少次就会进行多少次替换,内存中有多个备份,占用的是代码段的空间;const 定义的常量占用静态存储区的空间,程序运行过程中只有一份。
  • 调试:define 定义的宏常量不能调试,因为在预编译阶段就已经进行替换了;const 定义的常量可以进行调试。

const 的优点:

  • 有数据类型,在定义式可进行安全性检查。
  • 可调式。
  • 占用较少的空间。

define和typedef的区别

  • 原理:#define 作为预处理指令,在编译预处理时进行替换操作,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。typedef 是关键字,在编译时处理,有类型检查功能,用来给一个已经存在的类型一个别名,但不能在一个函数定义里面使用 typedef

  • 功能:typedef 用来定义类型的别名,方便使用。#define 不仅可以为类型取别名,还可以定义常量、变量、编译开关等。

  • 作用域:#define 没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,而 typedef 有自己的作用域。

  • 指针的操作:typedef#define 在处理指针时不完全一样

#include <iostream>
#define INTPTR1 int *
typedef int * INTPTR2;using namespace std;int main()
{INTPTR1 p1, p2; // p1: int *; p2: intINTPTR2 p3, p4; // p3: int *; p4: int *int var = 1;const INTPTR1 p5 = &var; // 相当于 const int * p5; 常量指针,即不可以通过 p5 去修改 p5 指向的内容,但是 p5 可以指向其他内容。const INTPTR2 p6 = &var; // 相当于 int * const p6; 指针常量,不可使 p6 再指向其他内容。return 0;
}

用宏实现比大小

#include <iostream>
#define MAX(X, Y) ((X)>(Y)?(X):(Y))
#define MIN(X, Y) ((X)<(Y)?(X):(Y))
using namespace std;int main ()
{int var1 = 10, var2 = 100;cout << MAX(var1, var2) << endl;cout << MIN(var1, var2) << endl;return 0;
}
/*
程序运行结果:
100
10
*/

inline作用及使用方法

作用

inline 是一个关键字,可以用于定义内联函数。内联函数,像普通函数一样被调用,但是在调用时并不通过函数调用的机制而是直接在调用点处展开,这样可以大大减少由函数调用带来的开销,从而提高程序的运行效率。

使用方法

  1. 类内定义成员函数默认是内联函数

    在类内定义成员函数,可以不用在函数头部加 inline 关键字,因为编译器会自动将类内定义的函数(构造函数、析构函数、普通成员函数等)声明为内联函数,代码如下:

    #include <iostream>
    using namespace std;class A{
    public:int var;A(int tmp){ var = tmp;}    void fun(){ cout << var << endl;}
    };int main()
    {    return 0;
    }
    
  2. 类外定义成员函数,若想定义为内联函数,需用关键字声明

    当在类内声明函数,在类外定义函数时,如果想将该函数定义为内联函数,则可以在类内声明时不加 inline 关键字,而在类外定义函数时加上 inline 关键字。

    #include <iostream>
    using namespace std;class A{
    public:int var;A(int tmp){ var = tmp;}    void fun();
    };inline void A::fun(){cout << var << endl;
    }int main()
    {    return 0;
    }
    

    另外,可以在声明函数和定义函数的同时加上 inline;也可以只在函数声明时加 inline,而定义函数时不加 inline。只要确保在调用该函数之前把 inline 的信息告知编译器即可。

inline函数工作原理

  • 内联函数不是在调用时发生控制转移关系,而是在编译阶段将函数体嵌入到每一个调用该函数的语句块中,编译器会将程序中出现内联函数的调用表达式用内联函数的函数体来替换。
  • 普通函数是将程序执行转移到被调用函数所存放的内存地址,当函数执行完后,返回到执行此函数前的地方。转移操作需要保护现场,被调函数执行完后,再恢复现场,该过程需要较大的资源开销。

宏定义(define)和内联函数(inline)的区别

  1. 内联函数是在编译时展开,而宏在编译预处理时展开;在编译的时候,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换。
  2. 内联函数是真正的函数,和普通函数调用的方法一样,在调用点处直接展开,避免了函数的参数压栈操作,减少了调用的开销。而宏定义编写较为复杂,常需要增加一些括号来避免歧义。
  3. 宏定义只进行文本替换,不会对参数的类型、语句能否正常编译等进行检查。而内联函数是真正的函数,会对参数的类型、函数体内的语句编写是否正确等进行检查。
#include <iostream>#define MAX(a, b) ((a) > (b) ? (a) : (b))using namespace std;inline int fun_max(int a, int b)
{return a > b ? a : b;
}int main()
{int var = 1;cout << MAX(var, 5) << endl;     cout << fun_max(var, 0) << endl; return 0;
}
/*
程序运行结果:
5
1*/

new/delete和malloc/free

new的作用

new 是 C++ 中的关键字,用来动态分配内存空间,实现方式如下:

int *p = new int[5]; 

new和malloc分别如何判断是否申请到内存

  • malloc :成功申请到内存,返回指向该内存的指针;分配失败,返回 NULL 指针。
  • new :内存分配成功,返回该对象类型的指针;分配失败,抛出 bac_alloc 异常。

delete 实现原理?delete 和 delete[] 的区别?

delete 的实现原理

  • 首先执行该对象所属类的析构函数;
  • 进而通过调用 operator delete 的标准库函数来释放所占的内存空间。

delete 和 delete [] 的区别

  • delete 用来释放单个对象所占的空间,只会调用一次析构函数;
  • delete [] 用来释放数组空间,会对数组中的每个成员都调用一次析构函数。

new和malloc的区别

在使用的时候 newdelete 搭配使用,mallocfree 搭配使用。

  • mallocfree 是库函数,而 newdelete 是关键字。
  • new 申请空间时,无需指定分配空间的大小,编译器会根据类型自行计算;malloc 在申请空间时,需要确定所申请空间的大小。
  • new 申请空间时,返回的类型是对象的指针类型,无需强制类型转换,是类型安全的操作符;malloc 申请空间时,返回的是 void* 类型,需要进行强制类型的转换,转换为对象类型的指针。
  • new 分配失败时,会抛出 bad_alloc 异常,malloc 分配失败时返回空指针。
  • 对于自定义的类型,new 首先调用 operator new() 函数申请空间(底层通过 malloc 实现),然后调用构造函数进行初始化,最后返回自定义类型的指针;delete 首先调用析构函数,然后调用 operator delete() 释放空间(底层通过 free 实现)。mallocfree 无法进行自定义类型的对象的构造和析构。
  • new 操作符从自由存储区上为对象动态分配内存,而 malloc 函数从堆上动态分配内存。(自由存储区不等于堆)

(下表来自:C/C++——C++中new与malloc的10点区别)

特征new/deletemalloc/free
分配内存的位置自由存储区
内存分配失败返回值完整类型指针void*
内存分配失败返回值默认抛出异常返回NULL
分配内存的大小由编译器根据类型计算得出必须显式指定字节数
处理数组有处理数组的new版本new[]需要用户计算数组的大小后进行内存分配
已分配内存的扩充无法直观地处理使用realloc简单完成
是否相互调用可以,看具体的operator new/delete实现不可调用new
分配内存时内存不足客户能够指定处理函数或重新制定分配器无法通过用户代码进行处理
函数重载允许不允许
构造函数与析构函数调用不调用
  • malloc给你的就好像一块原始的土地,你要种什么需要自己在土地上来播种
  • 而new帮你划好了田地的分块(数组),帮你播了种(构造函数),还提供其他的设施给你使用:

malloc 的原理?malloc 的底层实现?

malloc 的原理:

  • 当开辟的空间小于 128K 时,调用 brk() 函数,通过移动 _enddata 来实现;
  • 当开辟空间大于 128K 时,调用 mmap() 函数,通过在虚拟地址空间中开辟一块内存空间来实现。

malloc 的底层实现

  • brk() 函数实现原理:向高地址的方向移动指向数据段的高地址的指针 _enddata
  • mmap 内存映射原理:
    1. 进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域;
    2. 调用内核空间的系统调用函数 mmap(),实现文件物理地址和进程虚拟地址的一一映射关系;
    3. 进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝。

class、struct、union

C 和 C++ struct 的区别?

  • 在 C 语言中 struct 是用户自定义数据类型;在 C++ 中 struct 是抽象数据类型,支持成员函数的定义。
  • C 语言中 struct 没有访问权限的设置,是一些变量的集合体,不能定义成员函数;C++ 中 struct 可以和类一样,有访问权限,并可以定义成员函数。
  • C 语言中 struct 定义的自定义数据类型,在定义该类型的变量时,需要加上 struct 关键字,例如:struct A var;,定义 A 类型的变量;而 C++ 中,不用加该关键字,例如:A var;

为什么有了 class 还保留 struct?

C++ 是在 C 语言的基础上发展起来的,为了与 C 语言兼容,C++ 中保留了 struct

struct 和 union 的区别

说明:union 是联合体,struct 是结构体。

区别:

  • 联合体和结构体都是由若干个数据类型不同的数据成员组成。使用时,联合体只有一个有效的成员;而结构体所有的成员都有效。
  • 对联合体的不同成员赋值,将会对覆盖其他成员的值,而对于结构体的对不同成员赋值时,相互不影响。
  • 联合体的大小为其内部所有变量的最大值,按照最大类型的倍数进行分配大小;结构体分配内存的大小遵循内存对齐原则。
#include <iostream>
using namespace std;typedef union
{char c[10];char cc1; // char 1 字节,按该类型的倍数分配大小
} u11;typedef union
{char c[10];int i; // int 4 字节,按该类型的倍数分配大小
} u22;typedef union
{char c[10];double d; // double 8 字节,按该类型的倍数分配大小
} u33;typedef struct s1
{char c;   // 1 字节double d; // 1(char)+ 7(内存对齐)+ 8(double)= 16 字节
} s11;typedef struct s2
{char c;   // 1 字节char cc;  // 1(char)+ 1(char)= 2 字节double d; // 2 + 6(内存对齐)+ 8(double)= 16 字节
} s22;typedef struct s3
{char c;   // 1 字节double d; // 1(char)+ 7(内存对齐)+ 8(double)= 16 字节char cc;  // 16 + 1(char)+ 7(内存对齐)= 24 字节
} s33;int main()
{cout << sizeof(u11) << endl; // 10cout << sizeof(u22) << endl; // 12cout << sizeof(u33) << endl; // 16cout << sizeof(s11) << endl; // 16cout << sizeof(s22) << endl; // 16cout << sizeof(s33) << endl; // 24cout << sizeof(int) << endl;    // 4cout << sizeof(double) << endl; // 8return 0;
}

class 和 struct 的异同

  • struct 和 class 都可以自定义数据类型,也支持继承操作。
  • struct 中默认的访问级别是 public,默认的继承级别也是 public;class 中默认的访问级别是 private,默认的继承级别也是 private。
  • 当 class 继承 struct 或者 struct 继承 class 时,默认的继承级别取决于 class 或 struct 本身, class(private 继承),struct(public 继承),即取决于派生类的默认继承级别。
  • class 可以用于定义模板参数,struct 不能用于定义模板参数。
struct A{}class B : A{}; // private 继承 
struct C : B{}// public 继承

volatile

valatile的作用?是否具有原子性?

  • volatile 的作用:当对象的值可能在程序的控制或检测之外被改变时,应该将该对象声明为 volatile,告知编译器不应对这样的对象进行优化。

  • volatile 不具有原子性。

  • volatile 对编译器的影响:使用该关键字后,编译器不会对相应的对象进行优化,即不会将变量从内存缓存到寄存器中,防止多个线程有可能使用内存中的变量,有可能使用寄存器中的变量,从而导致程序错误。

什么情况下一定要用 volatile, 能否和 const 一起使用?

使用 volatile 关键字的场景:

  • 当多个线程都会用到某一变量,并且该变量的值有可能发生改变时,需要用 volatile 关键字对该变量进行修饰;
  • 中断服务程序中访问的变量或并行设备的硬件寄存器的变量,最好用 volatile 关键字修饰。

volatile 关键字和 const 关键字可以同时使用,某种类型可以既是 volatile 又是 const ,同时具有二者的属性。

extern、sizeof、memmove、strcpy、auto杂问

extern C 的作用?

当 C++ 程序 需要调用 C 语言编写的函数,C++ 使用链接指示,即 extern "C" 指出任意非 C++ 函数所用的语言。

举例:

// 可能出现在 C++ 头文件<cstring>中的链接指示
extern "C"{int strcmp(const char*, const char*);
}

sizeof(1==1) 在 C 和 C++ 中分别是什么结果?

C 语言代码:

#include<stdio.h>void main(){printf("%d\n", sizeof(1==1));
}/*
运行结果:
4
*/

C++ 代码:

#include <iostream>
using namespace std;int main() {cout << sizeof(1==1) << endl;return 0;
}/*
1
*/

C语言:

sizeof(1 == 1) === sizeof(1)按照整数处理,所以是4字节,这里也有可能是8字节(看操作系统)

C++:

因为有bool 类型,sizeof(1 == 1) == sizeof(true) 按照bool类型处理,所以是1个字节

memmove与memcpy

详见:memmove 和 memcpy的区别以及处理内存重叠问题

strcpy 函数有什么缺陷?

strcpy 函数的缺陷:strcpy 函数不检查目的缓冲区的大小边界,而是将源字符串逐一的全部赋值给目的字符串地址起始的一块连续的内存空间,同时加上字符串终止符,会导致其他变量被覆盖。

#include <iostream>
#include <cstring>
using namespace std;int main()
{int var = 0x11112222;char arr[10];cout << "Address : var " << &var << endl;cout << "Address : arr " << &arr << endl;strcpy(arr, "hello world!");cout << "var:" << hex << var << endl; // 将变量 var 以 16 进制输出cout << "arr:" << arr << endl;return 0;
}/*
Address : var 0x23fe4c
Address : arr 0x23fe42
var:11002164
arr:hello world!
*/

说明:从上述代码中可以看出,变量 var 的后六位被字符串 "hello world!""d!\0" 这三个字符改变,这三个字符对应的 ascii 码的十六进制为:\0(0x00),!(0x21),d(0x64)。
原因:变量 arr 只分配的 10 个内存空间,通过上述程序中的地址可以看出 arrvar 在内存中是连续存放的,但是在调用 strcpy 函数进行拷贝时,源字符串 "hello world!" 所占的内存空间为 13,因此在拷贝的过程中会占用 var 的内存空间,导致 var 的后六位被覆盖。

在这里插入图片描述

auto 类型推导的原理

auto 类型推导的原理:

编译器根据初始值来推算变量的类型,要求用 auto 定义变量时必须有初始值。编译器推断出来的 auto 类型有时和初始值类型并不完全一样,编译器会适当改变结果类型使其更符合初始化规则。

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

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

相关文章

memcpy和memmove的区别以及内存重叠问题

memcpy和memmove的区别以及内存重叠问题 转自&#xff1a;https://www.codecomeon.com/posts/89/ 区别 memcpy() 和 memmove() 都是C语言中的库函数&#xff0c;在头文件 string.h 中&#xff0c;作用是拷贝一定长度的内存的内容&#xff0c;原型分别如下&#xff1a; void…

从头搭建一个深度学习框架

从头搭建一个深度学习框架 转自&#xff1a;Build a Deep Learning Framework From Scratch 代码&#xff1a;https://github.com/borgwang/tinynn 当前深度学习框架越来越成熟&#xff0c;对于使用者而言封装程度越来越高&#xff0c;好处就是现在可以非常快速地将这些框架作为…

Docker概念理解

Docker概念理解 本文非Docker命令大全&#xff0c;而是对Docker的概念、原理等作说明&#xff0c;适合有一定实操经验后来加深理解。 转自&#xff1a;docker从入门到实践 Docker简介 本章将带领你进入 Docker 的世界。 什么是 Docker&#xff1f; 用它会带来什么样的好处&a…

Linux内存背后的那些神秘往事

Linux内存背后的那些神秘往事 作者&#xff1a;大白斯基&#xff08;公众号&#xff1a;后端研究所&#xff09; 转自&#xff1a;https://mp.weixin.qq.com/s/l_YdpyHht5Ayvrc7LFZNIA 前言 大家好&#xff0c;我的朋友们&#xff01; CPU、IO、磁盘、内存可以说是影响计算机…

精简CUDA教程——CUDA Driver API

精简CUDA教程——CUDA Driver API tensorRT从零起步迈向高性能工业级部署&#xff08;就业导向&#xff09; 课程笔记&#xff0c;讲师讲的不错&#xff0c;可以去看原视频支持下。 Driver API概述 CUDA 的多级 API CUDA 的 API 有多级&#xff08;下图&#xff09;&#xff…

CUDA编程入门极简教程

CUDA编程入门极简教程 转自&#xff1a;CUDA编程入门极简教程 作者&#xff1a;小小将 前言 2006年&#xff0c;NVIDIA公司发布了CUDA&#xff0c;CUDA是建立在NVIDIA的CPUs上的一个通用并行计算平台和编程模型&#xff0c;基于CUDA编程可以利用GPUs的并行计算引擎来更加高效地…

精简CUDA教程——CUDA Runtime API

精简CUDA教程——CUDA Runtime API tensorRT从零起步迈向高性能工业级部署&#xff08;就业导向&#xff09; 课程笔记&#xff0c;讲师讲的不错&#xff0c;可以去看原视频支持下。 Runtime API 概述 环境 图中可以看到&#xff0c;Runtime API 是基于 Driver API 之上开发的…

TensorRT ONNX 基础

TensorRT ONNX 基础 tensorRT从零起步迈向高性能工业级部署&#xff08;就业导向&#xff09; 课程笔记&#xff0c;讲师讲的不错&#xff0c;可以去看原视频支持下。 概述 TensorRT 的核心在于对模型算子的优化&#xff08;合并算子、利用当前 GPU 特性选择特定的核函数等多种…

mmdetection tools工具梳理

mmdetection tools工具梳理 mmdetection 是一个非常好用的开源目标检测框架&#xff0c;我们可以用它方便地训练自己的目标检测模型&#xff0c;mmdetection 项目仓库提供许多实用的工具来实现帮助我们进行各种测试。本篇将梳理以下 mmdetection 项目仓库 tools 目录下的各种实…

TensorRT ONNX 基础(续)

TensorRT ONNX 基础&#xff08;续&#xff09; PyTorch正确导出ONNX 几条推荐的原则&#xff0c;可以减少潜在的错误&#xff1a; 对于任何使用到 shape、size 返回值的参数时&#xff0c;例如 tensor.view(tensor.size(0), -1) 这类操作&#xff0c;避免直接使用 tensor.s…

frp实现内网穿透极简教程

frp实现内网穿透极简教程 本文是内网穿透极简教程&#xff0c;为求简洁&#xff0c;我们不介绍为什么内网穿透也不介绍其原理&#xff0c;这里假设各位读者都已经明确的知道自己的目的&#xff0c;本文仅介绍如何安装配置 frp 实现内网穿透。 简单来说&#xff0c;内网穿透就…

图像预处理之warpaffine与双线性插值及其高性能实现

图像预处理之warpaffine与双线性插值及其高性能实现 视频讲解&#xff1a;https://www.bilibili.com/video/BV1ZU4y1A7EG 代码Repo&#xff1a;https://github.com/shouxieai/tensorRT_Pro 本文为视频讲解的个人笔记。 warpaffine矩阵变换 对于坐标点的变换&#xff0c;我们通…

sed 简明教程

sed 简明教程 转自&#xff1a;https://coolshell.cn/articles/9104.html awk于1977年出生&#xff0c;今年36岁本命年&#xff0c;sed比awk大2-3岁&#xff0c;awk就像林妹妹&#xff0c;sed就是宝玉哥哥了。所以 林妹妹跳了个Topless&#xff0c;他的哥哥sed坐不住了&#xf…

[深度][PyTorch] DDP系列第一篇:入门教程

[深度][PyTorch] DDP系列第一篇&#xff1a;入门教程 转自&#xff1a;[原创][深度][PyTorch] DDP系列第一篇&#xff1a;入门教程 概览 想要让你的PyTorch神经网络在多卡环境上跑得又快又好&#xff1f;那你definitely需要这一篇&#xff01; No one knows DDP better than I…

[深度][PyTorch] DDP系列第二篇:实现原理与源代码解析

[深度][PyTorch] DDP系列第二篇&#xff1a;实现原理与源代码解析 转自&#xff1a;https://zhuanlan.zhihu.com/p/187610959 概览 想要让你的PyTorch神经网络在多卡环境上跑得又快又好&#xff1f;那你definitely需要这一篇&#xff01; No one knows DDP better than I do! …

[深度][PyTorch] DDP系列第三篇:实战与技巧

[深度][PyTorch] DDP系列第三篇&#xff1a;实战与技巧 转自&#xff1a;https://zhuanlan.zhihu.com/p/250471767 零. 概览 想要让你的PyTorch神经网络在多卡环境上跑得又快又好&#xff1f;那你definitely需要这一篇&#xff01; No one knows DDP better than I do! – – …

机器学习:系统设计与实现 分布式训练

机器学习系统:设计与实现 分布式训练 转自&#xff1a;https://openmlsys.github.io/chapter_distributed_training/index.html 随着机器学习的进一步发展&#xff0c;科学家们设计出更大型&#xff0c;更多功能的机器学习模型&#xff08;例如说&#xff0c;GPT-3&#xff09;…

从零Makefile落地算法大项目,完整案例教程

从零Makefile落地算法大项目&#xff0c;完整案例教程 转自&#xff1a;从零Makefile落地算法大项目&#xff0c;完整案例教程 作者&#xff1a;手写AI 前言 在这里&#xff0c;你能学到基于Makefile的正式大项目的使用方式和考虑&#xff0c;相信我&#xff0c;其实可以很简单…

PyTorch扩展自定义PyThonC++(CUDA)算子的若干方法总结

PyTorch扩展自定义PyThon/C(CUDA)算子的若干方法总结 转自&#xff1a;https://zhuanlan.zhihu.com/p/158643792 作者&#xff1a;奔腾的黑猫 在做毕设的时候需要实现一个PyTorch原生代码中没有的并行算子&#xff0c;所以用到了这部分的知识&#xff0c;再不总结就要忘光了 &a…

给 Python 算法插上性能的翅膀——pybind11 落地实践

给 Python 算法插上性能的翅膀——pybind11 落地实践 转自&#xff1a;https://zhuanlan.zhihu.com/p/444805518 作者&#xff1a;jesonxiang&#xff08;向乾彪&#xff09;&#xff0c;腾讯 TEG 后台开发工程师 1. 背景 目前 AI 算法开发特别是训练基本都以 Python 为主&…