高水準言語では、Cでのこの例に似たものが可能であり、それで問題ありません。しかし、このCの例をコンパイルすると、ひどく文句を言います。宣言した配列に新しい配列を割り当てるにはどうすればよいですか?
int values[3];
if(1)
values = {1,2,3};
printf("%i", values[0]);
ありがとう。
高水準言語では、Cでのこの例に似たものが可能であり、それで問題ありません。しかし、このCの例をコンパイルすると、ひどく文句を言います。宣言した配列に新しい配列を割り当てるにはどうすればよいですか?
int values[3];
if(1)
values = {1,2,3};
printf("%i", values[0]);
ありがとう。
配列を宣言する場合、配列の複数の割り当てのみを実行できます。
int values[3] = {1,2,3};
宣言後、各値を個別に割り当てる必要があります。
if (1)
{
values[0] = 1;
values[1] = 2;
values[2] = 3;
}
または、使用する値に応じて、ループを使用することもできます。
if (1)
{
for (i = 0 ; i < 3 ; i++)
{
values[i] = i+1;
}
}
C99では、複合リテラルを使用して、次のことができます。
memcpy(values, (int[3]){1, 2, 3}, sizeof(int[3]));
また
int* values = (int[3]){1, 2, 3};
//compile time initialization
int values[3] = {1,2,3};
//run time assignment
value[0] = 1;
value[1] = 2;
value[2] = 3;
初期化するデータを使用して静的配列を宣言できます。
static int initvalues[3] = {1,2,3};
…
if(1)
memmove(values,initvalues,sizeof(values));
#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;
}
コンパイラの構造体のブロックコピーを使用して、memcpyを非表示にすることもできます。それはすべての.iとiのためにコードを醜くします:しかし多分それはあなたの特定の問題を解決します。
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;
}
これもあります...:)
char S[16]="";
strncpy(S,"Zoodlewurdle...",sizeof(S)-1);
S[8]またはS[32]を宣言した場合に何が起こるかをテストして、これが非常に効果的である理由を確認します。
私はOpenBSDのstrlcpyのロジックに基づいて独自の文字列関数を作成しました。これは、オーバーフローが発生した場合にターミネータバイトが存在する必要があることを確認することを目的としています。標準のstrncpyはこれを行わないため、使用方法を注意深く監視する必要があります。
上記の方法は、=""
at宣言が全体で0バイトをsizeof(S)-1
保証し、strncpyに渡された引用符で囲まれた文字列をやり過ぎた場合に切り捨てられ、最後の0バイトの違反がないことを保証するため、効果的です。したがって、これはオーバーフローに対して安全であり、アクセス時に安全です。後で文字列。私はこれをANSICに向けたので、どこでも安全であるはずです。
これをコメントとして投稿しますが、評判がよくありません。配列を初期化する別の(おそらくダーティな)方法は、それを構造体でラップすることです。
#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;
}
これは、-O3を指定したgcc(コンパイラーはコードを完全に削除します)で機能し、最適化されますが、memcpyはすべての場合にメモリーを強制的にコピーします。
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);
}