C'nin dizilere yönelik yaklaşımı Java'lardan çok farklıdır ve düşüncenizi buna göre ayarlamanız gerekir. C'deki diziler birinci sınıf nesneler değildir (yani, bir dizi ifadesi çoğu bağlamda "dizi-niteliğini" korumaz). C'de, "N elemanlı dizi T
" türündeki bir ifade T
, dizi ifadesinin sizeof
veya tekli &
operatörlerin bir işleneni olması veya dizi ifadesi, bir bildirimde başka bir diziyi başlatmak için kullanılan bir dizedir.
Diğer şeylerin yanı sıra, bu, bir dizi ifadesini bir işleve aktaramayacağınız ve onu bir dizi türü olarak alamayacağınız anlamına gelir ; işlev aslında bir işaretçi türü alır:
void foo(char *a, size_t asize)
{
}
int bar(void)
{
char str[6] = "Hello";
foo(str, sizeof str);
}
Görüşmede için foo
, ifade str
tipine dönüştürülmüştür char [6]
için char *
ilk parametresi, bu yüzden de foo
ilan edilir char *a
yerine char a[6]
. İçinde sizeof str
, dizi ifadesi sizeof
operatörün bir işleneni olduğundan, bir işaretçi türüne dönüştürülmez, dolayısıyla dizideki bayt sayısını alırsınız (6).
Eğer ediyorsanız gerçekten ilgilenen, Dennis Ritchie'nin okuyabilir C Dili The Geliştirme bu tedavi nereden geldiğini anlamak için.
Sonuç, işlevlerin dizi türlerini döndürememesidir, bu sorun değildir, çünkü dizi ifadeleri de bir atamanın hedefi olamaz.
En güvenli yöntem, arayanın diziyi tanımlaması ve adresini ve boyutunu kendisine yazması gereken işleve iletmesidir:
void returnArray(const char *srcArray, size_t srcSize, char *dstArray, char dstSize)
{
...
dstArray[i] = some_value_derived_from(srcArray[i]);
...
}
int main(void)
{
char src[] = "This is a test";
char dst[sizeof src];
...
returnArray(src, sizeof src, dst, sizeof dst);
...
}
Diğer bir yöntem, işlevin diziyi dinamik olarak tahsis etmesi ve işaretçiyi ve boyutu döndürmesidir:
char *returnArray(const char *srcArray, size_t srcSize, size_t *dstSize)
{
char *dstArray = malloc(srcSize);
if (dstArray)
{
*dstSize = srcSize;
...
}
return dstArray;
}
int main(void)
{
char src[] = "This is a test";
char *dst;
size_t dstSize;
dst = returnArray(src, sizeof src, &dstSize);
...
free(dst);
...
}
Bu durumda, arayıcı, free
kütüphane işlevi ile dizinin serbest bırakılmasından sorumludur .
Not bu dst
yukarıdaki kodu için basit bir gösterici char
, bir dizi için bir işaretçi char
. C'nin işaretçi ve dizi semantiği, indis operatörünü []
dizi tipi veya işaretçi tipinin bir ifadesine uygulayabileceğiniz şekildedir ; her ikisi de src[i]
ve dizinin 'inci öğesine dst[i]
erişir i
(yalnızca src
dizi türüne sahip olsa bile ).
Sen edebilir bir N elemanlı diziye gösterici beyan T
ve benzeri bir şey yapmak:
char (*returnArray(const char *srcArr, size_t srcSize))[SOME_SIZE]
{
char (*dstArr)[SOME_SIZE] = malloc(sizeof *dstArr);
if (dstArr)
{
...
(*dstArr)[i] = ...;
...
}
return dstArr;
}
int main(void)
{
char src[] = "This is a test";
char (*dst)[SOME_SIZE];
...
dst = returnArray(src, sizeof src);
...
printf("%c", (*dst)[j]);
...
}
Yukarıdakilerle ilgili birkaç dezavantaj. Her şeyden önce, C'nin eski sürümleri SOME_SIZE
bir derleme zamanı sabiti olmayı bekler , yani işlev sadece tek bir dizi boyutuyla çalışacaktır. İkinci olarak, alt simgeyi uygulamadan önce işaretçinin referansını kaldırmanız gerekir, bu da kodu karıştırır. Dizilere işaretçiler, çok boyutlu dizilerle uğraşırken daha iyi çalışır.