c++随笔-3

c++计算eigen随笔(3)-求逆 求逆 #include <iostream> #include <Eigen/Dense> using namespace Eigen; using namespace std; int main() { Matrix3d m = Matrix3d::Random(); cout << "Here is the matrix m:" << endl ... 阅读详情

分支语句

void IfFunc() {
    bool a = true;
    std::cout.setf(std::ios::boolalpha);  // 设置cout输出bool值
    if (a) {       // 表达式结果为 true 或 不等于 0 时,进入 if 分支执行语句
        std::cout << "a value: " << a << std::endl;
    }
    
    bool b = false;
    if (b) {      // 表达式结果为 true 或 不等于 0 时,进入 if 分支执行语句
        std::cout << "b value: " << b << std::endl;
        return;   // 进入此分支,函数直接结束,不在执行后边语句
    }
    std::cout << "not into if (b) " << std::endl;
    
    int c = 100;
    std::cout.setf(std::ios::dec);   // 设置cout输出十进制值
    if (c == 100) {
        std::cout << "c == 100, c value: " << c << std::endl;
    }
    if (c != 100) {
        std::cout << "c != 100, c value: " << c << std::endl;
    }
    if (c > 100) {
        std::cout << "c > 100, c value: " << c << std::endl;
    }
    if (c < 100) {
        std::cout << "c < 100, c value: " << c << std::endl;
    }
    
    // if 嵌套,建议嵌套不要超过三层,超过三层看能否优化此结构
    if (c == 100) {
        c = 90;
        if (c == 90) {
            std::cout << "c == 90, c value: " << c << std::endl;
        }
    }
}

输出结果:
a value: true
not into if (b)
c == 100, c value: 100
c == 90, c value: 90

void IfElseFunc() {
    bool a = true;
    std::cout.setf(std::ios::boolalpha);  // 设置cout输出bool值
    if (a) {    // 此条件成立,进入 if 分支,否则进入 else 分支
        std::cout << "if a value: " << a << std::endl;
    } else {
        std::cout << "else a value: " << a << std::endl;
    }

    int b = 100;
    // if else if [else]语法,最后的else分支可选
    if (b == 100) {        // 条件成立进入if分支,执行后不在执行有else分支,条件不成立执行第一个else分支
        std::cout << "b == 100" << std::endl;
    } else if (b < 100) {  // else if又需要判断条件是否成立,条件成立进入分支,不在执行后边的else分支,条件不成立继续执行后边的else分支
        std::cout << "b < 100" << std::endl;
    } else {               // 此处else无判断条件,前边条件不满足直接进入此分支,这个else分支不是必须项
        std::cout << "b > 100" << std::endl;
    }

    // if else 嵌套
    if (b == 100) {
        b = 50;
        if (b > 50) {
            std::cout << "b > 50" << std::endl;
        } else {
            std::cout << "b <= 50" << std::endl;
        }
    } else if (b < 100) {
        if (b > 50) {
            std::cout << "b > 50" << std::endl;
        } else if (b < 50){
            std::cout << "b < 50" << std::endl;
        } else {
            std::cout << "b == 50" << std::endl;
        }
    } else if (b > 100) {
        if (b > 50) {
            std::cout << "b > 50" << std::endl;
        } else if (b < 50){
            std::cout << "b < 50" << std::endl;
        } else if (b == 50){
            std::cout << "b == 50" << std::endl;
        }
    }
}

输出结果:
if a value: true
b == 100
b <= 50

void SwitchFunc() {
    int a = 100;
    // switch 语法格式
    switch (a) {  // 关键字switch,括号中判断类型可以是 bool、整型、枚举
    case 0:       // case 相当于 if (a == 0)
        break;    // switch规则默认把每个case分支和default分支都顺序执行一次,break控制从当前位置跳出switch范围,即不在执行后边的分支语句
    case 10:
        // int s = 10;  // 此处编译报错
        a = 10;         // 可使用switch之外的变量
        break;
    case 100: {         // case 分支也可加一对大括号(语句块),这样就可以定义局部变量,否则不能定义
        int b = 10;     // 此处定义局部变量编译OK
        break;
    }
    default:            // 可选分支(若逻辑处理完整可不用写此分支),此处表示除去case判断的值之外的值进入的分支
        ;
    }
}
  • 根据不同的条件进入不同的分支执行任务
  • 常见的分支语句 if、if else、switch等

运算符

  • 按照运算符优先级顺序来排列,以下例子对所有运算符简单应用
  • 通常所见到的 std::cout 中 :: 是作用域运算符,cout 在 std 中包含
void OperatorFunc() {    // 优先级由高到底
    // 1.  []   数组下标
    int arr[2]  = {10, 100};
    std::cout << "arr[0]: " << arr[0] <<"\tarr[1]: " << arr[1] << std::endl;
    // 2.  ()   圆括号
    int s = (arr[0] + arr[0]) * arr[0];    // (10 + 10) x 10
    std::cout << "s value: " << s << std::endl;
    // 3.  .    成员选择(对象)
    struct A {
        int a;
        int b;
    };
    A t;
    t.a = 10;
    t.b = 20;
    std::cout << "A a value:" << t.a << "\tA b value: " << t.b << std::endl;
    // 4.  ->    成员选择(对象)
    A *p = &t;
    std::cout << "A a value:" << p->a << "\tA b value: " << p->b << std::endl;  // (&t)->a 访问也可
    // 5.  - +   负号 正号(可省略) 
    s = -60 + 10;   // 10 为正数,也可写为 s = -60 + +10;
    std::cout << "s value:" << s << std::endl;
    // 6.  (类型)    强制类型转换
    s = (int)-100.5;
    std::cout << "s value:" << s << std::endl;
    // 7.  ++    自增运算符
    s = 20;
    std::cout << "s++ value:" << s++ << std::endl;  // ++ 在后,先打印值,然后值加一
    std::cout << "s value:" << s++ << std::endl;
    s = 20;
    std::cout << "++s value:" << ++s << std::endl;  // ++ 在前,先值加一,然后打印值
    std::cout << "s value:" << s << std::endl;
    // 8.  --    自减运算符
    s = 20;
    std::cout << "s-- value:" << s-- << std::endl;  // -- 在后,先打印值,然后值减一
    std::cout << "s value:" << s++ << std::endl;
    s = 20;
    std::cout << "--s value:" << --s << std::endl;  // -- 在前,先值减一,然后打印值
    std::cout << "s value:" << s << std::endl;
    // 9.  *    指针解引用运算符
    int *p1 = &s;
    std::cout << "*p1 value:" << *p1 << std::endl;  // 取出指针指向地址的值
    // 10.  &    取地址运算符
    std::cout << "s value: " << s << "\ts address: " << &s << std::endl;
    // 11.  !    逻辑非运算符
    bool i = true;
    std::cout << "i value: " << i << "\t!i address: " << !i << std::endl;
    // 12.  ~    按位取反运算符
    s = 20;    // 二进制为 1000 0000 0000 0000 0000 0000 0001 0100,最高位为符号位,1 表示有符号
    std::cout << std::hex << "s value: 0x" << s << "\t~s value: " << ~s << std::endl;
    std::cout << std::dec << "s value: " << s << "\t~s value: " << ~s << std::endl;
    unsigned int f = 20; // 二进制为 0000 0000 0000 0000 0000 0000 0001 0100,最高位为符号位,0 表示有符号
    std::cout << std::hex << "f value: 0x" << f << "\t~f value: " << ~f << std::endl;
    std::cout << std::dec << "f value: " << f << "\t~f value: " << ~f << std::endl;
    // 13.  sizeof    长度运算符,对于变量括号可省略
    std::cout << "struct A length: " << sizeof (A) << "\tA t length: " << sizeof t << std::endl;
    std::cout << "s length: " << sizeof (int) << "\tA t length: " << sizeof (s) << std::endl;
    // 14.  / * % + -    除 乘 取余 加 减,可组合成复杂算数运算
    s = 15;
    //   std::cout << "s / 0 = " << s / 0 << std::endl; // 注意除数不能为零 s / 0
    std::cout << "s / 3 = " << s / 3 << std::endl;
    std::cout << "s / 6 = " << s / 6 << std::endl;
    std::cout << "s / 7 = " << s / 7 << std::endl;
    // 会发现上边输出后面两个结果相等,且输出结果没有小数部分,规则是如果除号两侧数据类型都为整型,则结果也是整型
    std::cout << "s / 6.0 = " << s / 6.0 << std::endl;   // 将一侧数据类型改成浮点型,则结果为浮点型
    std::cout << "s / 7.0 = " << s / 7.0 << std::endl;

    std::cout << "s * 2 = " << s * 2 << std::endl;
    std::cout << "s * 3.5 = " << s * 3.5 << std::endl;

    // % 两侧的数据类型只能为整型,取余结果和被取余的数正负号相同
    std::cout << "s % 3 = " << s % 3 << std::endl;  // 余数为 0
    std::cout << "s % 7 = " << s % 7 << std::endl;  // 余数为 1
    std::cout << "s % 7 = " << s % -7 << std::endl; // 余数为 1
    s = -s;   // s = -15
    std::cout << "s % 3 = " << s % 3 << std::endl;  // 余数为 0
    std::cout << "s % 7 = " << s % 7 << std::endl;  // 余数为 -1
    std::cout << "s % 7 = " << s % -7 << std::endl; // 余数为 -1

    s = 20;
    std::cout << "s + s = " << s + s << std::endl;
    std::cout << "s + 3.25 = " << s + 3.25 << std::endl;
    std::cout << "s + -3.25 = " << s + -3.25 << std::endl;

    std::cout << "s - 35.5 = " << s - 35.5 << std::endl;
    std::cout << "s - 3.25 = " << s - +3.25 << std::endl;
    std::cout << "s - -3.25 = " << s - -3.25 << std::endl;
    // 15.  << >>    左移 右移 运算符,左移相当于乘2,右移相当于除以2
    s = 3000;
    std::cout << "s << 1 = " << (s << 1) << std::endl;
    std::cout << "s * 2 = " << s * 2 << std::endl;
    std::cout << "s << 2 = " << (s << 2) << std::endl;
    std::cout << "s * 2 * 2 = " << s * 2 * 2 << std::endl;

    std::cout << "s >> 1 = " << (s >> 1) << std::endl;
    std::cout << "s / 2 = " << s / 2 << std::endl;
    std::cout << "s >> 2 = " << (s >> 2) << std::endl;
    std::cout << "s / 2 / 2 = " << s / 2 / 2 << std::endl;
    // 16.  > >= < <= == !=    大于 大于等于 小于 小于等于 等于 不等于
    s = 100;
    std::cout.setf(std::ios::boolalpha);
    std::cout << "s > 100: " << (s > 100) << std::endl;
    std::cout << "s > 50: " << (s > 50) << std::endl;
    std::cout << "s >= 100: " << (s > 100) << std::endl;
    std::cout << "s >= 101: " << (s > 101) << std::endl;
    std::cout << "s < 100: " << (s < 100) << std::endl;
    std::cout << "s < 150: " << (s < 150) << std::endl;
    std::cout << "s <= 100: " << (s > 100) << std::endl;
    std::cout << "s <= 99: " << (s > 99) << std::endl;
    std::cout << "s == 100: " << (s == 100) << std::endl;
    std::cout << "s == 50: " << (s == 50) << std::endl;
    std::cout << "s != 100: " << (s == 100) << std::endl;
    std::cout << "s != 50: " << (s == 50) << std::endl;
    // 17.  & ^ |    按位与 按位异或 按位或
    s = 20;     // 二进制为 1000 0000 0000 0000 0000 0000 0001 0100
    int g = 12; // 二进制为 1000 0000 0000 0000 0000 0000 0000 1100
    // s  1000 0000 0000 0000 0000 0000 0001 0100
    // &
    // g  1000 0000 0000 0000 0000 0000 0000 1100
    //    1000 0000 0000 0000 0000 0000 0000 0100
    // & 规则,按二进制,s 和 g相同位上同为真(1)才为真,否则为假(0)
    std::cout << std::hex << "hex: s & g = 0x" << (s & g) << std::endl;
    std::cout << std::dec << "dec: s & g = " << (s & g) << std::endl;
    // s  1000 0000 0000 0000 0000 0000 0001 0100
    // |
    // g  1000 0000 0000 0000 0000 0000 0000 1100
    //    1000 0000 0000 0000 0000 0000 0001 1100
    // | 规则,按二进制,s 和 g相同位上同为假(0)才为假(0),否则为真(1)
    std::cout << std::hex << "hex: s | g = 0x" << (s | g) << std::endl;
    std::cout << std::dec << "dec: s | g = " << (s | g) << std::endl;
    // s  1000 0000 0000 0000 0000 0000 0001 0100
    // ^
    // g  1000 0000 0000 0000 0000 0000 0000 1100
    //    1000 0000 0000 0000 0000 0000 0001 1000
    // ^ 规则,按二进制,s 和 g相同位上值相同就为假(0),值不相同就为真(1)
    std::cout << std::hex << "hex: s ^ g = 0x" << (s ^ g) << std::endl;
    std::cout << std::dec << "dec: s ^ g = " << (s ^ g) << std::endl;
    // 18.  && ||    逻辑与 逻辑或,按值(不按位)判断真假,注意其短路规则
    s = 20;
    g = 30;
    // && 规则:运算符两边值都为真(或不为零)时才为真,否则为假
    std::cout.setf(std::ios::boolalpha);
    std::cout << "s && g: " << (s && g) << std::endl;
    g = 0;
    std::cout << "s && g: " << (s && g) << std::endl;
    // || 规则:运算符两边值都为假(或为零)时才为假,否则为真
    std::cout << "s || g: " << (s || g) << std::endl;
    g = 0;
    std::cout << "s || g: " << (s || g) << std::endl;
    // 短路规则
    g = 30;
    int j = 0;
    // 先执行 (s && j),判断为假,两个表达式中间以 &&(同为真才为真)相连,所以直接判断为假,不会继续执行后续判断
    std::cout << "(s && j) && (s && g): " << ((s && j) && (s && g)) << std::endl;
    // (s && g) 为真,是以 && 相连,继续判断(s && g),最终判断(1 || 0)结果
    std::cout << "(s && g) && (s && j): " << ((s && g) && (s && j)) << std::endl;
    // 先执行 (s && j),判断为假,两个表达式中间以 ||(同为假才为假)相连,继续判断(s && g)为真,最终判断(0 || 1)结果
    std::cout << "(s && j) || (s && g): " << ((s && j) || (s && g)) << std::endl;
    // (s && g) 为真,是以 || 相连,不在做判断,直接为真
    std::cout << "(s && g) || (s && j): " << ((s && g) || (s && j)) << std::endl;
    // 19.  ?:    条件运算符(三目运算符)
    s = 20;
    if (s == 20) {    // 条件判断 if 实现简单例子
        g = s - 10;
    } else {
        g = s + 10;
    }
    // 使用条件运算符实现,如果条件 s == 20 为真(true),执行 g = s - 10,否则执行 g = s + 10
    s == 20 ? g = s - 10 : g = s + 10;

    // 20.  = /= *= %=     赋值 除后赋值 乘后赋值 取余后赋值
    //      += -= <<= >>=    加后赋值 减后赋值 左移后赋值 右移后赋值
    //      &= ^= |=    按位与后赋值 按位异或后赋值 按位或后赋值
    // 这些运算符其实是简化代码编写
    s = 10;
    s /= 5;    // s = s / 5;
    s *= 5;    // s = s * 5;
    s %= 5;    // s = s % 5;
    s += 5;    // s = s + 5;
    s -= 5;    // s = s - 5;
    s <<= 5;   // s = s << 5;
    s >>= 5;   // s = s >> 5;
    s &= 5;    // s = s & 5;
    s ^= 5;    // s = s ^ 5;
    s |= 5;    // s = s | 5;

    // 21.  ,  逗号运算符,当顺序点用,顺序是从左至右,用来顺序求值,优先级最低
    int z = 20, x, c, v = 10;  // 定义变量
    int *k, l;     // 注意此处只有 k 为指针类型,l 为 int 类型,使用 decltype 推导变量类型
    std::cout << (typeid (int *) == typeid(decltype (k))) << std::endl;
    std::cout << (typeid (int) == typeid(decltype (l))) << std::endl;
    s = z, v; // z 值赋值给 s 而不是 v,低版本Qt可能编译报错,不支持这样的写法(实际上这种写法无任何意义)
    std::cout << std::dec << "s value: " << s << std::endl;

    int n = 0;
    int arr2[10] = {1, 2, 3, 4, 5, 6, 7, 8};
    for (n = 1, n = 2, n = 3; n < 10; ++n) {   // 注意使用逗号表达式,此处 n 循环开始值为 3
        std::cout << "arr2 index: " << n << "\tarr2 value: " << arr2[n] << std::endl;
    }
}
输出结果:  // 放在代码块里是因为有和 Markdown 符号冲突的输出
arr[0]: 10      arr[1]: 100
s value: 200
A a value:10    A b value: 20
A a value:10    A b value: 20
s value:-50
s value:-100
s++ value:20
s value:21
++s value:21
s value:21
s-- value:20
s value:19
--s value:19
s value:19
*p1 value:19
s value: 19     s address: 0x65fd54
i value: 1      !i address: 0
s value: 0x14   ~s value: ffffffeb
s value: 20     ~s value: -21
f value: 0x14   ~f value: ffffffeb
f value: 20     ~f value: 4294967275
struct A length: 8      A t length: 8
s length: 4     A t length: 4
s / 3 = 5
s / 6 = 2
s / 7 = 2
s / 6.0 = 2.5
s / 7.0 = 2.14286
s * 2 = 30
s * 3.5 = 52.5
s % 3 = 0
s % 7 = 1
s % 7 = 1
s % 3 = 0
s % 7 = -1
s % 7 = -1
s + s = 40
s + 3.25 = 23.25
s + -3.25 = 16.75
s - 35.5 = -15.5
s - 3.25 = 16.75
s - -3.25 = 23.25
s << 1 = 6000
s * 2 = 6000
s << 2 = 12000
s * 2 * 2 = 12000
s >> 1 = 1500
s / 2 = 1500
s >> 2 = 750
s / 2 / 2 = 750
s > 100: false
s > 50: true
s >= 100: false
s >= 101: false
s < 100: false
s < 150: true
s <= 100: false
s <= 99: true
s == 100: true
s == 50: false
s != 100: true
s != 50: false
hex: s & g = 0x4
dec: s & g = 4
hex: s | g = 0x1c
dec: s | g = 28
hex: s ^ g = 0x18
dec: s ^ g = 24
s && g: true
s && g: false
s || g: true
s || g: true
(s && j) && (s && g): false
(s && g) && (s && j): false
(s && j) || (s && g): true
(s && g) || (s && j): true
true
true
s value: 20
arr2 index: 3   arr2 value: 4
arr2 index: 4   arr2 value: 5
arr2 index: 5   arr2 value: 6
arr2 index: 6   arr2 value: 7
arr2 index: 7   arr2 value: 8
arr2 index: 8   arr2 value: 0
arr2 index: 9   arr2 value: 0

二维数组

void ArrayTwo() {
    // 指针数组和数组指针
    int (*ae)[2]; // 是一个指针,它指向有2个元素的一维数组,它是指向数组的指针
    int *af[2];   // 是一个数组,数组的元素(2个元素存储)都是指针(int *),它是储存指针的数组
    // auto 所表示的变量代表后面赋值的 lambda(c++11特性) 函数,函数参数展示了如何传入二维指针
    auto Print = [](int **arr, int row, int col) {  // 以二重指针方式传参,不能使用arr[i][j]访问,需要手动计算元素位置
        for (int i = 0; i < row; ++i) {             // 打印二维数组,内存必须连续
            for (int j = 0; j < col; j++) {
                std::cout << "arr[" << i << "][" << j << "] = " << *((int *)arr + i * col + j) << "\t";
            }
            std::cout << "\n";
        }
    };
    auto Print2 = [](int arr[][2], int row, int col) {  // 以二维数组方式传参,退化为指针
        for (int i = 0; i < row; ++i) {                 // 打印二维数组
            for (int j = 0; j < col; j++) {
                std::cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << "\t";
            }
            std::cout << "\n";
        }
    };
    auto Print3 = [](int arr[2][2], int row, int col) {  // 以二维数组方式传参,退化为指针
        for (int i = 0; i < row; ++i) {                  // 打印二维数组
            for (int j = 0; j < col; j++) {
                std::cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << "\t";
            }
            std::cout << "\n";
        }
    };
    auto Print4 = [](int (*arr)[2], int row, int col) {  // 以数组指针方式传参,退化为指针
        for (int i = 0; i < row; ++i) {                  // 打印二维数组
            for (int j = 0; j < col; j++) {
                std::cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << "\t";
            }
            std::cout << "\n";
        }
    };
    auto Print5 = [](int *arr[2], int row, int col) {  // 以数组指针方式传参,退化为指针
        for (int i = 0; i < row; ++i) {                  // 打印二维数组
            for (int j = 0; j < col; j++) {
                std::cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << "\t";
            }
            std::cout << "\n";
        }
    };

    // 直接指定行数和列数(栈内存)
    int a[2][2] = {1, 2, 3, 4};   // 编译时会出警告,不推荐
    std::cout << "Print array a: " << std::endl;
    Print3(a, 2, 2);
    int b[2][2] = {{5, 6}, {7, 8}};
    std::cout << "Print array b: " << std::endl;
    Print4(b, 2, 2);
    // 自推导行数,列数不能省略(栈内存)
    int c[][2] = {{9, 10}, {11, 12}};
    std::cout << "Print array c: " << std::endl;
    Print((int **)c, 2, 2);

    int d[][2] = {{9, 10}, {11, 12}};   // Qt14.2 MinGW 64编译器,自动推导行
    std::cout << "Print array d: " << std::endl;
    Print2(d, 6, 2);   // 打印 6 行也不报错,只不过后边值是大于 2 行后是随机值(不推荐这样越界使用)
    // 指针创建(堆内存),这种方式创建可能二维指针内存不连续
    int **pe;
    pe = new int*[2];         // 创建数组指针
    for(int i = 0; i < 2; i++) {
        pe[i] = new int[2];   // 指针指向对应的数组首地址
    }
    pe[0][0] = 13;  // 赋值
    pe[0][1] = 14;
    pe[1][0] = 15;
    pe[1][1] = 16;
    std::cout << "Print array pe: " << std::endl;
    Print5(pe, 2, 2);
    for (int i = 0; i < 2; ++i) {  // 赋值
        for (int j = 0; j < 2; ++j) {
            pe[i][j] = 17 + i + j;
        }
    }
    std::cout << "Print array pe: " << std::endl;
    Print5(pe, 2, 2);

    // 释放
    for (int i = 0; i < 2; i++)
        delete [] pe[i];
    delete [] pe;

    // 二维数组首地址
    std::cout << "array b adderess: \t" << b << std::endl;
    std::cout << "array b[0] adderess: \t" << &b[0] << std::endl;
    std::cout << "array b[0][0] adderess: \t" << &b[0][0] << std::endl;
    // 二维数组名称加上某个数和某行的首地址值相同
    std::cout <<"b + 1: " << b + 1 << std::endl;
    std::cout <<"b[1]: " << b[1] << std::endl;

    // 二维数组总长度
    std::cout <<"total b length: " << sizeof b << std::endl;  // 2 * 2 * 4
    std::cout <<"b[0] length: " << sizeof b[0] << std::endl;  // 第一行长度
    std::cout <<"member size: " << sizeof b[0] / sizeof (int) << std::endl;  // 第一行元素数量
}

输出结果:
Print array a:
arr[0][0] = 1 arr[0][1] = 2
arr[1][0] = 3 arr[1][1] = 4
Print array b:
arr[0][0] = 5 arr[0][1] = 6
arr[1][0] = 7 arr[1][1] = 8
Print array c:
arr[0][0] = 9 arr[0][1] = 10
arr[1][0] = 11 arr[1][1] = 12
Print array d:
arr[0][0] = 9 arr[0][1] = 10
arr[1][0] = 11 arr[1][1] = 12
arr[2][0] = 9 arr[2][1] = 10
arr[3][0] = 11 arr[3][1] = 12
arr[4][0] = 5 arr[4][1] = 6
arr[5][0] = 7 arr[5][1] = 8
Print array pe:
arr[0][0] = 13 arr[0][1] = 14
arr[1][0] = 15 arr[1][1] = 16
Print array pe:
arr[0][0] = 17 arr[0][1] = 18
arr[1][0] = 18 arr[1][1] = 19
array b adderess: 0x65fd20
array b[0] adderess: 0x65fd20
array b[0][0] adderess: 0x65fd20
b + 1: 0x65fd28
b[1]: 0x65fd28
total b length: 16
b[0] length: 8
member size: 2

  • 一维数组在内存存储是连续的,二维数组在内存中仍然像一维数组那样连续存储
  • 注意二维数组作为函数参数时的用法,具体参照例子

《随笔3》——C++中的“隐藏的this指针、Stataic数据成员、Stataic静态成员函数” 目录 隐藏的this指针 静态数据成员 const 静态成员数据的初始化 静态成员能用于某些场景,而普通成员不能 static 成员函数 隐藏的this指针 ●  对于类的非静态成员,每一个对象都有自己的一份拷贝, 即每个对象都有自己的数据成员, 不过成员函数却是每个对象共享的。 那么调用共享的成员函数是如何区分自己的的数据成员呢,答案就是通过类中隐藏的this 指针。 ●  th... 阅读详情

相关推荐

【BOOST C++ (5)算法】【01】 Boost.Algorithm

Boost.Algorithm 提供了补充标准库算法的算法。与 Boost.Range 不同,Boost.Algorithm 没有引入新概念。 Boost.Algorithm 定义的算法类似于标准库中的算法。

gongdiwudu的专栏 5370

C++ 中的 cout.setf() 函数

代码cout.setf(ios_base::fixed, ios_base::floatfield)怎么解释? C++中通过cout来实现格式输出,就类似于C语言中通过printf()来实现格式输出。cout.setf()的作用是通过设置格式标志来控制输出形式,其中ios_base::fixed表示:用正常的记数方法显示浮点数(与科学计数法相对应);ios_base::floatfield表示小

白水的博客 5万+

C++:随笔3--复杂的数据结构

所谓函数重载的实质就是用同样的名字再定义一个有着不同参数但有着同样用途的函数。(多重身份) 注意:可以是参数个数上的不同,也可以是参数数据类型上的不同。

m0_37957160的博客 432

C++中cout.setf()函数

C++中cout.setf(ios::left,ios::adjustfield); cout.setf(ios::showpoint,ios::showpint); cout.setf(ios::scientific,ios::floatfield); 分别表示什么 参考以下: 1.使用控制符控制输出格式 控制符 作用  dec 设置整数的基数为10  hex 设置整数的基

荪荪的博客 3万+

Github多人协作

最近有门课程需要几个人一起开发一个项目,此前我们基本都是单干的,多人合作意味着需要及时将我们每个人的代码进行合并,U盘传文件这种方式太慢了,效率不行,而且没法解决两个人同时修改一个文件的问题,这次我们就尝试使用Github来协助开发。下面就来记录一下这次开发遇到的一些问题和解决的方法。 Git的安装 从官网下载最新版按照默认安装即可。 此处不多加说明。 Git常用命令 在此放上一...

yzr1216的博客 1万+

告别底噪和发热:TPA3255的PCB布局与散热设计保姆级教程(附嘉立创EDA文件)

本文详细解析TPA3255 Class D音频功放的PCB布局与散热设计,提供从电源系统分层架构到热管理系统的全流程优化方案。通过实战案例展示如何消除底噪、降低发热,并附嘉立创EDA文件,助力工程师快速设计高性能音频功放。

weixin_29208077的博客 376

C++固定格式输出:cout.setf(........)

/命令cout显示true和false。

m0_68731112的博客 727

HDMI协议介绍(二)--DataIsland Packets

前文简单介绍了HDMI传输的三个周期:控制周期、DataIsland周期和Video周期。DataIsland传输音频和辅助数据,这些数据以Packet的形式传输。本文简单介绍DataIsland Packet。

SlamDunk的博客 5674

C++中浮点数的格式化输出

C++中浮点数的输出方式有: 定点输出法:我们平常日常生活中书写小数的方法,小数点不能随便移动,如3.1415926、123456.789; //设置浮点数按定点方式输出 std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield); 科学计数输出法:将一个浮点数写成一个数乘以10的n次方的形式,如123456.789可以写成1.23456789乘以10的5次方,0.618可以写成6.18乘以10的-1次方,在C++中分别表示

1万+

《网络摄像机实战11:flutter_webrtc支持 AWS Kinesis Video Streams信令服务器》

本文介绍了如何在Flutter项目中集成WebRTC实现网络摄像头的实时视频和音频对讲功能。通过使用flutter_webrtc插件,开发者可以快速构建跨平台的视频通信应用。文章详细说明了集成步骤:1)安装flutter_webrtc插件;2)配置信令服务器和KVS服务;3)初始化本地/远程视频渲染器;4)建立WebRTC连接并进行设备呼叫。最后展示了实际应用效果图,证明该方案能有效实现移动端与摄像头的实时音视频交互。该方案为开发智能家居监控等应用提供了技术参考。

lvj_158的专栏 356

【深度学习新浪潮】Qwen门控注意力斩获NeurIPS 2025最佳论文!技术解析与代码实现

Qwen团队的门控注意力机制获得NeurIPS 2025最佳论文,不仅是中国AI研究的重大突破,更是大模型架构创新的重要里程碑。这项研究证明,通过巧妙的架构设计,可以在不显著增加计算成本的前提下,大幅提升模型性能。正如论文所展示的,用一个极其简单的改动,同时解决了Transformer架构中的多个核心问题,这正是优秀研究的价值所在。该技术已成功应用于Qwen3大模型,为通义千问系列产品的性能提升提供了坚实的技术支撑。轻量化大模型设计多模态统一架构专用领域大模型优化边缘计算场景部署。

专注:太空算力、AI infra、异构调度、大模型成本工程 570

c++随笔3——C++对C的函数扩展

C++随笔

qq_43159510的博客 482

JAX/JAXlib GPU 加速版本安装教程(CUDA)

本文介绍了在Windows WSL2+Ubuntu22.04环境下配置JAX/JAXlib GPU加速版本的详细步骤。使用RTX 4060显卡,安装CUDA 12.4和cuDNN 8.9.7驱动,通过Miniconda创建Python 3.9虚拟环境。具体步骤包括:安装Miniconda、配置CUDA环境变量、安装cuDNN驱动、下载并安装JAX/JAXlib。最后通过测试代码验证GPU加速功能,成功检测到GPU并完成矩阵运算。整个过程配有详细命令和截图说明,适合需要搭建JAX GPU开发环境的用户参考。

猿小白的博客 627

读Defective C++随笔 3

读Defective C++随笔 3不尽知用兵之害者,则不能尽知用兵之利也 ——《孙子兵法》 5.const完备问题对C来说,const看起来是很合理的,将参数声明成const的,可以利用编译器的语法检查避免一些不期望的修改错误,而且可能帮助编译器做一些优化。多数官方文献都强烈要求程序员编写const完备的C++代码,极力避免const_cast,但现实中大部分代码只能是基本使用了const。

Dev in Nightmare 1608

【LangChain编程:从入门到实践】实现多模态代理

【LangChain编程:从入门到实践】实现多模态代理 关键词:LangChain, 多模态代理, 自然语言处理, 机器学习, 知识图谱, 对话系统, 代码生成, AI代理 1. 背景介绍 随着人工智

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 581

SAP-ABAP:SAP创建CDS视图(SQL语句创建)实例详解

通过Eclipse和ADT创建CDS视图是SAP开发中的一项重要技能。CDS视图不仅简化了数据建模,还提供了高性能和灵活性。掌握CDS视图的开发和使用,可以帮助你更好地支持SAP S/4HANA和Fiori应用的开发。

baidu_35680696的博客 1824

C++学习随笔(3)——auto和for

介绍C++中的auto,for,nullptr

2301_77272486的博客 1513

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

c++学习随笔3

复合语句:用花括号({})将多条语句组合在一起,以创建复合语句 使用运算符: 赋值运算符( = ), 加( + )减( - )乘( * )除( / )和求模运算符(%)(最后这个书里是这么写,我感觉是相当于delphi的mod) 递增运算符(++) 递减运算符(--) 后缀运算符是 先将右值赋给左值,再将右值递增或递减,前缀运算符的行为相反 相等运算符( == ) 和不等运算符( !=...

weixin_33725272的博客 87

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++类和对象复习随笔3

假设B类是A类中的类,那么B默认是A的友元类,可以访问A的私有成员。初始化列表顺序只与类成员声明顺序有关,跟初始化列表顺序无关。友元会增加耦合度,在一定程度上破坏封装。(这点通过引用可以看出)

2301_80472857的博客 625

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++ primer 随笔(3)

标准库类型 涉及命名空间的声明分为两种:命名空间指令与命名空间声明 using namespace::std; 是命名空间指令,加入该语句后,可使用std中定义的所有标识符 using std::cin; using std::cout; 是命名空间声明,应注意的是:一个using声明只作用于一个命名空间成员 两者相比之下,命名空间声明要更加安全,因为命名空间指令中的冲突直接覆盖,而命名空间声明遇...

lxx909546478的博客 167

c++随笔,关于模板的第二个小记 16.1.3模板参数

16.1.3模板参数 很多时候我们把参数名字定义为T,但是实际上我们可以使用任何的名字 比如 template <typename DATA>using partNo = BlobA<DATA>; 模板参数和作用域规则。一个模板参数名的可用范围是在其声明之后,至模板声明或定义结束之前。与其他任何名字都一样,模板参数会隐藏外层作用域中声明的相同的名字。但是,与大多...

qq_32783703的博客 303

C++随笔:.NET CoreCLR之GC探索(3)

  有几天没写GC相关的文章了哈,今天我讲GC的方式是通过一个小的Sample来讲解,这个小的示例代码只有全部Build成功了才会有。地址为D:\coreclr2\coreclr\bin\obj\Windows_NT.x64.Debug\src\gc\sample,前缀路径大家替换成自己的路径就OK了。   首先我们还是从main函数来入手吧。首先是初始化GC。 int __cdecl m...

weixin_33854644的博客 127

Thrift0.9.3 C++版代码阅读随笔——TNonblockingServer

0.一些参考资料 (参考资料1)对thrift的一个基本介绍可以参考: http://wenku.baidu.com/link?url=LLL5H3qL4hJ3o6dfq0SBgztqtxYFR5vDyftwowKNRMWiIQ3t87mCu-GMZljxcZVryxxhqna1hM4eu3F7AyCMlC7fFy7yWl18IIl6nY7JKca (参考资料2)thrif...

weixin_30564901的博客 314

c++计算eigen随笔(10)-数组、矩阵、向量(3)

默认构造函数总是可用的,从不执行任何动态内存分配,也从不初始化矩阵系数 Matrix3f a; MatrixXf b; 在这里, a是一个3×3矩阵,带有一个未初始化系数的普通浮点]数组, b是一个动态大小的矩阵,它当前的大小是0乘0,它的系数数组还没有被分配。 也可以使用具有大小的构造函数。对于矩阵,总是先传递行数。对于向量,只需传递向量的大小。他们分配的给定的大小系数数组,但不初始化的系数本...

The research on computer technolog 593
上一篇: c++随笔-2
下一篇: c++随笔-4
无夜_
博客等级 码龄7年 2916粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值