web-dev-qa-db-fra.com

Utilisation d'un pointeur sur un tableau

Je joue un peu avec le langage Go de Google, et j'ai rencontré quelque chose qui est assez basique en C mais qui ne semble pas être couvert dans la documentation que j'ai vue jusqu'à présent.

Lorsque je passe un pointeur sur une tranche à une fonction, je suppose que nous aurions un moyen d'y accéder comme suit:

func conv(x []int, xlen int, h []int, hlen int, y *[]int)

    for i := 0; i<xlen; i++ {
        for j := 0; j<hlen; j++ {
            *y[i+j] += x[i]*h[j]
        }
    }
 }

Mais le compilateur Go n'aime pas ceci:

sean@spray:~/dev$ 8g broke.go
broke.go:8: invalid operation: y[i + j] (index of type *[]int)

Assez juste - c'était juste une supposition. J'ai une solution de contournement assez simple:

func conv(x []int, xlen int, h []int, hlen int, y_ *[]int) {
    y := *y_

    for i := 0; i<xlen; i++ {
        for j := 0; j<hlen; j++ {
            y[i+j] += x[i]*h[j]
        }
    }
}

Mais il y a sûrement une meilleure façon. Ce qui est ennuyeux, c'est que la recherche d'informations sur Go n'est pas très utile car toutes sortes de résultats C/C++/sans rapport apparaissent pour la plupart des termes de recherche.

32
Sean

Les types avec [] Vide, comme []int Sont en fait des tranches, pas des tableaux. Dans Go, la taille d'un tableau fait partie du type, donc pour avoir réellement un tableau, vous devez avoir quelque chose comme [16]int, Et le pointeur vers cela serait *[16]int. Donc, ce que vous faites déjà, c'est utiliser des tranches, et le pointeur vers une tranche, *[]int, Est inutile car les tranches sont déjà passées par référence.

Souvenez-vous également que vous pouvez facilement passer une tranche se référant à l'ensemble du tableau avec &array (Tant que le type d'élément de la tranche correspond à celui du tableau). (Plus maintenant.)

Exemple:

package main
import "fmt"

func sumPointerToArray(a *[8]int) (sum int) {
    for _, value := range *a { sum += value }
    return
}
func sumSlice (a []int) (sum int) {
    for _, value := range a { sum += value }
    return
}
func main() {
    array := [...]int{ 1, 2, 3, 4, 5, 6, 7, 8 }
    slice := []int{ 1, 2, 3, 4 }
    fmt.Printf("sum arrray via pointer: %d\n", sumPointerToArray(&array))
    fmt.Printf("sum slice: %d\n", sumSlice(slice))
    slice = array[0:]
    fmt.Printf("sum array as slice: %d\n", sumSlice(slice))
}

Modifier : mis à jour pour refléter les changements dans Go depuis la première publication.

15
Arkku

le point-virgule et l'astérisque sont ajoutés et supprimés.

* y [i + j] + = x [i] * h [j]
->
(* y) [i + j] + = x [i] * h [j];

5
Behrooz

Voici un programme Go fonctionnel.

package main

import "fmt"

func conv(x, h []int) []int {
    y := make([]int, len(x)+len(h)-1)
    for i := 0; i < len(x); i++ {
        for j := 0; j < len(h); j++ {
            y[i+j] += x[i] * h[j]
        }
    }
    return y
}

func main() {
    x := []int{1, 2}
    h := []int{7, 8, 9}
    y := conv(x, h)
    fmt.Println(len(y), y)
}

Pour éviter les suppositions erronées, lisez la documentation Go: The Go Programming Language.

2
peterSO

La longueur fait partie du type du tableau, vous pouvez obtenir la longueur d'un tableau par la fonction intégrée len (). Vous n'avez donc pas besoin de passer les arguments xlen, hlen.

Dans Go, vous pouvez presque toujours utiliser slice lors du passage d'un tableau à une fonction. Dans ce cas, vous n'avez pas besoin de pointeurs. En fait, vous n'avez pas besoin de passer l'argument y. C'est la manière du C de produire un tableau.

Dans le style Go:

func conv(x, h []int) []int {
    y := make([]int, len(x)+len(h))
    for i, v := range x { 
        for j, u := range h { 
            y[i+j] = v * u 
        }   
    }   
    return y
}

Appelez la fonction:

conv(x[0:], h[0:])
2
Stephen Hsu