it-swarm-tr.com

C dizisine birden çok değer atama

Bunu yoğunlaştırılmış bir şekilde yapmanın bir yolu var mı?

GLfloat coordinates[8];
...
coordinates[0] = 1.0f;
coordinates[1] = 0.0f;
coordinates[2] = 1.0f;
coordinates[3] = 1.0f;
coordinates[4] = 0.0f;
coordinates[5] = 1.0f;
coordinates[6] = 0.0f;
coordinates[7] = 0.0f;
return coordinates;

coordinates = {1.0f, ...}; gibi bir şey?

27
UnstableFractal

Gerçektendeğerlerini ( initialize yerine) atadıysanız, şöyle yapabilirsiniz:

 GLfloat coordinates[8]; 
 static const GLfloat coordinates_defaults[8] = {1.0f, 0.0f, 1.0f ....};
 ... 
 memcpy(coordinates, coordinates_defaults, sizeof(coordinates_defaults));

 return coordinates; 
23
James Curran

Eski okul yolu:

GLfloat coordinates[8];
...

GLfloat *p = coordinates;
*p++ = 1.0f; *p++ = 0.0f; *p++ = 1.0f; *p++ = 1.0f;
*p++ = 0.0f; *p++ = 1.0f; *p++ = 0.0f; *p++ = 0.0f;

return coordinates;
10
Pavel Minaev

Diziyi bir yapıya sarmak için bir hile var (bildirimden sonra başlatılabilir).

yani.

struct foo {
  GLfloat arr[10];
};
...
struct foo foo;
foo = (struct foo) { .arr = {1.0, ... } };
6
domen

Kesinlikle, neredeyse aldın:

GLfloat coordinates[8] = {1.0f, ..., 0.0f};
3
Felix Kling

Kullanabilirsiniz:

GLfloat coordinates[8] = {1.0f, ..., 0.0f};

ancak bu bir derleme zamanı ilkesidir - bu yöntemi geçerli standartta yeniden başlatmak için kullanamazsınız (bununla birlikte, hemen size yardımcı olmayabilecek yaklaşan standartta yapmanın yolları olduğunu düşünüyorum).

Akla gelen diğer iki yol, eğer sabitse içeriği kırmaktır:

GLfloat base_coordinates[8] = {1.0f, ..., 0.0f};
GLfloat coordinates[8];
:
memcpy (coordinates, base_coordinates, sizeof (coordinates));

veya yine de başlangıç ​​kodunuz gibi görünen bir işlev sağlayın:

void setCoords (float *p0, float p1, ..., float p8) {
    p0[0] = p1; p0[1] = p2; p0[2] = p3; p0[3] = p4;
    p0[4] = p5; p0[5] = p6; p0[6] = p7; p0[7] = p8;
}
:
setCoords (coordinates, 1.0f, ..., 0.0f);

bu elipslerin (...) akılda tutulması, tam anlamıyla koda yazılacak şeyler değil, yer tutuculardır.

3
paxdiablo

Aynı ödevleri programınızda çok yapıyorsanız ve bir kısayol istiyorsanız, en basit çözüm yalnızca bir işlev eklemek olabilir.

static inline void set_coordinates(
        GLfloat coordinates[static 8],
        GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3,
        GLfloat c4, GLfloat c5, GLfloat c6, GLfloat c7)
{
    coordinates[0] = c0;
    coordinates[1] = c1;
    coordinates[2] = c2;
    coordinates[3] = c3;
    coordinates[4] = c4;
    coordinates[5] = c5;
    coordinates[6] = c6;
    coordinates[7] = c7;
}

ve sonra sadece ara

GLfloat coordinates[8];
// ...
set_coordinates(coordinates, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f);
0
dpi

Bunun gibi bir kodla:

const int node_ct = 8;
const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };

Ve configure.ac içinde

AC_PROG_CC_C99

Dev kutumdaki derleyici mutluydu. Sunucudaki derleyici şunlardan şikayetçi oldu:

error: variable-sized object may not be initialized
   const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };

ve

warning: excess elements in array initializer
   const int expected[node_ct] = { 1, 3, 4, 2, 5, 6, 7, 8 };

her eleman için

Mesela hiç şikayet etmiyor, örneğin:

int expected[] = { 1, 2, 3, 4, 5 };

ancak, büyüklüğü kontrol etmeyi sevdiğime karar verdim.

Savaşmak yerine, bir varargs başlatıcısıyla gittim:

#include <stdarg.h>

void int_array_init(int *a, const int ct, ...) {
  va_list args;
  va_start(args, ct);
  for(int i = 0; i < ct; ++i) {
    a[i] = va_arg(args, int);
  }
  va_end(args);
}

gibi denir

const int node_ct = 8;
int expected[node_ct];
int_array_init(expected, node_ct, 1, 3, 4, 2, 5, 6, 7, 8);

Bu nedenle, varargs desteği, dizi başlatıcının desteğinden daha sağlamdır.

Birisi bir makroda böyle bir şey yapabilir.

Örnek kodu içeren PR'ı https://github.com/wbreeze/davenport/pull/15/files adresinde bulabilirsiniz.

@Paxdiablo'dan https://stackoverflow.com/a/3535455/608359 ile ilgili olarak; ancak, başlangıç ​​işaretleyicisinin, diziye ayrılan elemanların sayısı ile senkronize edilme sayısının ne kadar ilerleme gösterdiği konusunda güvensiz hissettim. En kötü durumda, başlatıcı işaretçi, atanan uzunluktan daha fazla hareket eder. Gibi, PR içindeki fark,

  int expected[node_ct];
- int *p = expected;
- *p++ = 1; *p++ = 2; *p++ = 3; *p++ = 4;
+ int_array_init(expected, node_ct, 1, 2, 3, 4);

Bağımsız değişkenlerin sayısı node_ct'den azsa, int_array_init yöntemi güvenle önemsiz atar. Önemsiz atamanın yakalanması ve hata ayıklanması daha kolay olmalı.

0
Douglas Lovell