🔮
Rust学习笔记
  • 介绍
  • Rust入门
    • 安装使用
    • Cargo初用
    • 其他工具
    • 实例1
    • vim安装及配置
    • rust analyzer速度慢
  • rust基础
    • 关键字
    • 模块module和测试
    • 变量-数据类型
      • 浮点数
      • NaN
      • 有理数和复数
    • 单元类型
    • 字符串-切片-数组-元组-hashpmap
    • 结构体和枚举
    • 控制语句
    • 模式匹配match
    • 函数-method 闭包 迭代器
    • File操作
  • Rust进阶
    • 所有权
      • 所有权基础
      • 如何让函数使用某个值,但不获得其所有权
      • 切片
    • Rust VS C
    • 函数指针
  • Q&A
    • Rust的宏
    • cargo expand
    • web server
    • cargo watch使用
    • lib分类
    • cargo源
  • 参考
    • 博客
    • 项目
  • rust内存泄露
  • 智能指针
  • Tauri类似electron的框架
  • Tokio包使用
  • Rust wasm介绍
  • 多线程
    • C语言
  • Golang语言
    • 项目
  • Java
  • Javascript
Powered by GitBook
On this page
  • head
  • strcut
  • 函数
  1. Rust进阶

Rust VS C

Previous切片Next函数指针

Last updated 2 years ago

head

#include <stdint.h>
#include <stdalign.h>
#include <immintrin.h>
#include <math.h>
#include <stdio.h>
use std::mem;
use std::arch::x86_64::*;
use std::f64::consts::PI;

strcut

// intptr_t should be the native integer type on most 
// sane systems.
typedef intptr_t intnative_t;

typedef struct{
    double position[3], velocity[3], mass;
} body;
// Note 1
#![allow(
    non_upper_case_globals,
    non_camel_case_types,
    non_snake_case,
)]

#[repr(C)]  // Note 2
struct body {
    position: [f64; 3],
    velocity: [f64; 3],
    mass: f64,
}

此allow 属性(类似于 a #pragma)通知编译器我们希望允许偏离命名约定

#[repr(C)]标记struct要求 Rust 布局struct 与 C 完全相同 ,没有的话它会优化它们以获得最佳的打包和对齐——这可能是你以前手工完成的。

#define SOLAR_MASS (4*M_PI*M_PI)
#define DAYS_PER_YEAR 365.24
#define BODIES_COUNT 5
// Note 1
const SOLAR_MASS: f64 = 4. * PI * PI;
const DAYS_PER_YEAR: f64 = 365.24;
const BODIES_COUNT: usize = 5;

#defines 可以被 Rust 替换const,它声明了一个常量

函数

static void offset_Momentum(body bodies[]){

    for(intnative_t i=0; i<BODIES_COUNT; ++i)
        for(intnative_t m=0; m<3; ++m)
            bodies[0].velocity[m]-=
              bodies[i].velocity[m]*bodies[i].mass/SOLAR_MASS;



}
// v------------------------------------ Note 1
unsafe fn offset_Momentum(bodies: *mut body) {
// ^                               ^---- Note 2
    for i in 0..BODIES_COUNT {  // <---- Note 3
        for m in 0..3 {
            (*bodies.add(0)).velocity[m] -=  // <- Note 4
                (*bodies.add(i)).velocity[m] // <- Note 5
                * (*bodies.add(i)).mass / SOLAR_MASS;
        }
    }
}

在 C 中,bodies[i]完全一样*(bodies + i)——它执行指针算术和解引用,仅此而已。特别是,它假定您有理由知道这i是数组的有效索引。这是 C 语言中的常见情况,可以使用方括号进行速记。

static void advance(body bodies[]){

    #define INTERACTIONS_COUNT \
        (BODIES_COUNT*(BODIES_COUNT-1)/2)
    #define ROUNDED_INTERACTIONS_COUNT \
        (INTERACTIONS_COUNT+INTERACTIONS_COUNT%2)

    //  ,--------------------------------- Note 1
    // v       v-------------------------- Note 2
    static alignas(__m128d) double
      position_Deltas[3][ROUNDED_INTERACTIONS_COUNT],
      magnitudes[ROUNDED_INTERACTIONS_COUNT];
unsafe fn advance(bodies: *mut body) {

    const INTERACTIONS_COUNT: usize =
        BODIES_COUNT * (BODIES_COUNT - 1) / 2;
    const ROUNDED_INTERACTIONS_COUNT: usize =
        INTERACTIONS_COUNT + INTERACTIONS_COUNT % 2;

    // Note 1
    #[repr(align(16))]
    #[derive(Copy, Clone)]
    struct Align16([f64; ROUNDED_INTERACTIONS_COUNT]);

    // Note 2
    static mut position_Deltas: [Align16; 3] =
        [Align16([0.; ROUNDED_INTERACTIONS_COUNT]); 3];
    static mut magnitudes: Align16 =
        Align16([0.; ROUNDED_INTERACTIONS_COUNT]);

在 Rust 中,常见用例使用引用而不是指针并进行边界检查,因此用例得到简写bodies[i]。做未经检查的指针算术是例外而不是规则,因此我们必须更加刻意地表达它。

最后,我们必须写*bodies.add(i)而不是*(bodies + i)因为 Rust 不会为指针重载算术运算符。相反,指针提供了add、sub和其他在代码审查中更容易发现的操作;如果您好奇,

Learn Rust the Dangerous Way
3
这里是完整列表。