指向数组的指针,返回 Zig 中的数组

问题描述 投票:0回答:1

我需要在某个函数中创建一个数组(将大小作为参数),然后返回它以便在一个干净的行中轻松声明。它已经引起了很多问题:

  • 据我所知,Zig 没有隐藏的控制和内存分配,因此,如果我传递一个数组作为参数,编译器将像处理 int 那样克隆它(正如它应该的那样),还是会像 C 或 Java 中那样创建一个指针?
  • 函数
    return
    可以是数组吗?如果可以的话,我需要
    const
    comptime
    作为长度值吗?
  • 如果我需要传递一个指向数组(或其地址)的指针,我该如何声明它,从中提取一个值?
  • 如果我需要传递指针而不是
    const length: usize
    我该怎么做?如果我通过
    &size
    编译器说该函数需要
    *usize
    而不是
    const *usize
    但我无法将其重写为
    const length: *usize
    因为长度应该是 comptime。

这是我需要的代码示例:

const std = @import("std");

pub fn sorted_array(comptime len: usize) *[]i32 {
    comptime var array: [len]i32 = undefined;
    for (&array, 0..) |*item, i| {
        item.* = @intCast(i);
    }
    return &array;
}

pub fn main() void {
    const size: usize = 10;
    const array: *[]i32 = sorted_array(size);
    for (&array.*) |*item| {
        std.debug.print("{} ", .{item.*});
    }
}

但是当然它不能编译,因为它是 Zig。我也有相同的代码,但我真正需要的是,它用 C 编译和编写:

#include <stdio.h>
#include <malloc.h>

int* sorted_array(const size_t* size) {
    int* array = (int*)malloc(sizeof(int) * *size);
    for (size_t i = 0; i < *size; i++)
        array[i] = i;
    return array;
}

int main(void) {

    const size_t size = 1000;
    int* array = sorted_array(&size);

    return 0;
}

我对其进行编码以立即执行某些操作,如果您回答我的问题并重新编码我的初学者 Zig 尝试,我将不胜感激

arrays pointers zig
1个回答
0
投票

您确定要使用数组吗? Zig 数组与 C 数组几乎相同,其大小必须在编译时已知。但是你的 C 代码会动态分配内存并返回指向它的指针,Zig 为此提供了一个很好的抽象,称为 slices。切片是指向内存的多项指针加上长度。

C 代码的 Zig 函数等效项如下所示:

fn create_sorted_array(allocator: std.mem.Allocator, len: *const usize) ![]i32 {
    const array = try allocator.alloc(i32, len.*);
    for (array, 0..) |*item, i| {
        item.* = @intCast(i);
    }
    return array;
}

据我所知,Zig 没有隐藏的控制和内存分配,因此,如果我传递一个数组作为参数,编译器将像处理 int 那样克隆它(正如它应该的那样),还是会像 C 或 Java 中那样创建一个指针?

内存总是被复制,但是切片包含一个指针,它指向的内存不会被复制。

函数可以返回数组吗?如果可以的话,我需要 const 或 comptime 作为长度值吗?

是的,长度必须是

comptime
(在编译时已知)。

如果我需要传递一个指向数组(或其地址)的指针,我该如何声明它,从中提取一个值?

声明和使用与任何其他指针没有什么不同(

*[xxx]i32
用于声明,
pointer.*
用于取消引用),但在编译时必须知道长度可能会很不方便。切片在这里更方便,甚至不必使用指向切片的指针(尽管可以)。

如果我通过

&size
编译器表示该函数需要
*usize
而不是
const *usize

使用

*const usize
。您不需要大小可变。

但我不能将其重写为

const length: *usize
,因为长度应该是comptime。

这似乎可行,尽管对我来说没有多大意义(编译时已知的指针?):

fn sorted(comptime len: *const usize) [len.*]i32 {
    const array: [len.*]i32 = undefined;
    // ...
    return array;
}
© www.soinside.com 2019 - 2024. All rights reserved.