7
votes

DÉCLARATION DU TRAY SIMPLET C

Dans les langues de niveau supérieur, je serais capable quelque chose de similaire à cet exemple en C et ce irait bien. Cependant, lorsque je compile cet exemple C, il se plaint amèrement. Comment puis-je attribuer de nouveaux tableaux à la matrice que j'ai déclarée? XXX

Merci.


1 commentaires

Voyez ici pour quelques idées: Stackoverflow.com/Questtions/1223736/...


9 Réponses :


12
votes

Vous ne pouvez effectuer que plusieurs affectations de la matrice, lorsque vous déclarez le tableau:

if (1)
{
  for (i = 0 ; i < 3 ; i++)
  { 
    values[i] = i+1;
  }
}


3 commentaires

Cela fonctionne pour 3 valeurs, mais si j'avais un tableau avec 50 valeurs?


Ensuite, vous utiliseriez une boucle, ou vous seriez MEMMOVE / MEMCY comme @hacker suggère dans une autre réponse.


memcpy semble être soigné. Merci de votre aide.



3
votes

Vous pouvez déclarer une matrice statique avec des données pour initialiser à partir de: xxx


6 commentaires

Puis-je ne pas faire Memmove (valeurs, {1,2,3}, taille de (valeurs)); ?


Non, vous ne pouvez pas le faire comme ça.


Je pense que vous pourriez: Memmove (valeurs, (int [3]) {1,2,3}, Tailleof (int [3])); Voir ma réponse ci-dessous.


Il n'est pas nécessaire d'utiliser memmove sur memcpy ici - les tableaux ne se chevauchent certainement pas.


Pourquoi pensez-vous que j'ai utilisé Memmove "sur Memcpy"? Je viens d'utiliser Memmove. ;-)


@Michael: Qu'est-ce que @CAF signifiait, c'est que dans le scénario donné, il n'est pas nécessaire de déplacer la mémoire car la source et le dest ne se chevauchent pas. De cette façon, Memcpy peut être légèrement plus rapide. Voir ce Stackoverflow. com / questions / 1201319 / ...



4
votes
 //compile time initialization
 int values[3] = {1,2,3};

//run time assignment
 value[0] = 1;
 value[1] = 2;
 value[2] = 3;

0 commentaires

8
votes

en C99, en utilisant littéraux composés , vous pouvez faire:

int* values = (int[3]){1, 2, 3};


7 commentaires

+1; N'oubliez pas que dans ce dernier cas, la matrice aura une durée de stockage automatique, c'est-à-dire que le renvoyer à partir d'une fonction vous permettra de manger par une grue.


Christoph, cela signifierait-il que Memmove d'un tel tableau impliquerait d'abord l'initialiser en stockage automatique, puis de la copier?


@hacker: En principe, oui, dans la pratique, le compilateur l'optimisera (pour GCC, -O1 suffit)


D'autre part, êtes-vous sûr qu'il est vraiment de stockage automatique? N'est-ce pas si semblable aux littéraux strings? Ou utiliserait un mot-clé const .


@hacker: oui, const Les littéraux composés peuvent être partagés de la même manière que les chaînes sont (il s'agit d'un détail de mise en œuvre et n'a aucune incidence sur la sémantique du langage); Les littéraux non-Conscons sont garantis pour être distincts à chaque entrée du bloc joint


Oui, mais maintenant que je pense à cela, je ne pense pas avoir jamais vu des littéraux non-constants en C avant ...


N'oubliez pas non plus à l'esprit que le répondeur a dit que ceci est C99, pas plus populaire ISO C90.



0
votes

Il est également possible de masquer le memcpy en utilisant la copie en bloc du compilateur des structures. Cela rend le code laids à cause de tous les .Je et moi: mais cela résout peut-être votre problème spécifique.

typedef struct {
    int i[3];
} inta;

int main()
{
    inta d = {i:{1, 2, 3}};

    if (1)
        d = (inta){i:{4, 5, 6}};

    printf("%d %d %d\n", d.i[0], d.i[1], d.i[2]);

    return 0;
}


0 commentaires

-1
votes

Ceci fonctionne et optimise mieux sous GCC avec -O3 (le compilateur supprime complètement le code), tandis que le memcpy oblige la mémoire à copier dans tous les cas.

template <typename Array>
struct inner
{
    Array x;
};


template <typename Array>
void assign(Array& lhs, const Array& rhs)
{
    inner<Array>& l( (inner<Array>&)(lhs));
    const inner<Array>& r( (inner<Array>&)(rhs));
    l = r;
}

int main()
{
    int x[100];
    int y[100];

    assign(x, y);
}


1 commentaires

La question est étiquetée C, pas C ++. Cette réponse est C ++ et complètement invalide dans C.



0
votes

Il y a aussi ceci ... :) xxx

Test Que ce qui se passe si vous déclarez S [8] ou S [32], de voir pourquoi cela est si efficace.

J'ai écrit mes propres fonctions de chaîne basées sur la logique de Strlcpy de OpenBSD, visant à garantir que l'octet de terminaison doit exister en cas de débordement et Standard Strncpy ne le fera pas, vous devez donc regarder attentivement comment vous l'utilisez. .

La méthode ci-dessus est efficace car le = "" à la déclaration garantit 0 octets tout au long de l'ensemble, et Tailleof (s) -1 assure que si vous Overiller la chaîne citée passée à Strncpy, vous obtenez de la troncature et aucune violation de la dernière octet 0. Il est donc sûr contre le débordement maintenant et d'accéder à la chaîne plus tard. Je vis cela à l'ANSI C afin que cela devrait être sûr n'importe où.


2 commentaires

Je me rends compte que ceci est une chaîne, pas un éventail d'entiers, mais il peut y avoir un moyen de traduire la méthode en conséquence, sans avoir à écrire votre propre code d'itération.


Strncpy est de les matrices de caractères ___ est des tableaux entier?



0
votes

Je poste ceci comme un commentaire, mais je n'ai pas assez de réputation. Une autre voie (peut-être sale) d'initialisation d'un tableau consiste à envelopper dans une structure.

#include <stdio.h>

struct wrapper { int array[3]; };

int main(){
    struct wrapper a;
    struct wrapper b = {{1, 2, 3}};

    a = b;

    printf("%i %i %i", a.array[0], a.array[1], a.array[2]);

    return 0;
}


0 commentaires

1
votes
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

int *setarray(int *ar,char *str)
{
    int offset,n,i=0;
    while (sscanf(str, " %d%n", &n, &offset)==1)
    {
        ar[i]=n;
        str+=offset;
        i+=1;
    }
    return ar;
}

int *setarray2(int *ar,int num,...)
{
   va_list valist;
   int i;
   va_start(valist, num);

   for (i = 0; i < num; i++) 
        ar[i] = va_arg(valist, int);
   va_end(valist);
   return ar;
}

int main()
{
    int *size=malloc(3*sizeof(int*)),i;
    setarray(size,"1 2 3");

    for(i=0;i<3;i++)
        printf("%d\n",size[i]);

    setarray2(size,3 ,4,5,6);
    for(i=0;i<3;i++)
        printf("%d\n",size[i]);

    return 0;
}

3 commentaires

Vous pouvez également boucler SSCANF à partir d'une fonction puis renvoyer le tableau


Bienvenue dans le débordement de pile. Veuillez lire le sur page bientôt. Lorsque vous répondez à une question de plus de 6 ans après sa demande (et que vous avez des réponses à la hausse et acceptées), vous devez avoir quelque chose de distinctif pour ajouter - une nouvelle approche, ou peut-être que le produit a changé depuis que les réponses originales ont été données. Heureusement pour vous, aucune des autres réponses ne suggère d'analyser une représentation de chaîne des valeurs de matrice - de sorte que beaucoup d'ok. Je ne suis pas sûr que ce soit un bon mécanisme, mais c'est différent. Votre appel à MALLOC () n'est pas suffisamment d'espace sur n'importe quelle machine où tailleOf (char)! = Tailleof (int) .


MALLOC modifié, si vous utilisez des chaînes ne fonctionne pas, vous pouvez également utiliser les fonctions de STDARG.H