Tür Güvenliği Kaygıları
Değişken bağımsız değişkenlerin riskleri
Tür Güvenliği Kaygıları, CoddyKit'te ücretsiz bir C Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C Academy kursu toplamda 4 dersten oluşur.
Değişken sayıda bağımsız değişken tür denetimini atlar
Normal C işlevleri, bağımsız değişkenlerin parametre türleriyle eşleşip eşleşmediğini denetler. Değişken sayıda bağımsız değişken bu denetimi tamamen atlar.
Derleyici, ... sonrasında ne geçirdiğinizi doğrulayamaz; bu da hataları kolayca yapılır ve tehlikeli hâle getirir.
#include <stdio.h>
#include <stdarg.h>
int add(int n, ...) {
va_list a; va_start(a, n);
int s = 0;
for (int i = 0; i < n; i++) s += va_arg(a, int);
va_end(a);
return s;
}
int main(void) {
printf("%d\n", add(2, 3, 4));
return 0;
}va_arg içinde yanlış tür
Bir bağımsız değişkeni yanlış türle okursanız sonuç tanımsız davranış olur.
Bir int geçirip bunu double olarak okumak, ilgisiz baytları yeniden yorumlar ve anlamsız bir değer veya çökme üretir.
#include <stdio.h>
#include <stdarg.h>
int read_int(int n, ...) {
va_list a; va_start(a, n);
int v = va_arg(a, int);
va_end(a);
return v;
}
int main(void) {
printf("%d\n", read_int(1, 100));
return 0;
}Biçim dizisi uyumsuzlukları
printf tarzı işlevlerde yanlış belirteç, klasik bir hatadır. printf("%d", 3.14), bir double değeri int değer gibi okur.
Modern derleyiciler sabit değerlerdeki uyumsuzluklar konusunda uyarır; ancak çalışma zamanında oluşturulan biçim dizilerini yakalayamaz.
#include <stdio.h>
int main(void) {
double pi = 3.14;
printf("%f\n", pi);
return 0;
}Tam sayı yükseltmelerinin şaşırtıcı sonuçları
Küçük türler, değişken sayıda bağımsız değişken bölümünde int türüne yükseltilir. Bu nedenle bir char geçirseniz bile onu int olarak geri okumalısınız.
va_arg(a, char) ile char olarak okumak tanımsızdır.
#include <stdio.h>
#include <stdarg.h>
void show(int n, ...) {
va_list a; va_start(a, n);
int c = va_arg(a, int);
printf("char is %c\n", c);
va_end(a);
}
int main(void) {
show(1, 'A');
return 0;
}Float türü double olur
Bir float bağımsız değişkeni, değişken sayıda bağımsız değişkenlerde her zaman double türüne yükseltilir. Onu double olarak okumalı, hiçbir zaman float olarak okumamalısınız.
Bu, değişken sayıda bağımsız değişkenlerle ilgili en yaygın hatalardan biridir.
#include <stdio.h>
#include <stdarg.h>
void show(int n, ...) {
va_list a; va_start(a, n);
double d = va_arg(a, double);
printf("%.2f\n", d);
va_end(a);
}
int main(void) {
float f = 1.5f;
show(1, f);
return 0;
}Gereğinden fazla bağımsız değişken okumak
Kodunuz, çağıranın sağladığından daha fazla kez va_arg çağırırsa yığından anlamsız veriler okursunuz.
Doğru bir sayı veya sentinel kullanmak bu nedenle zorunludur.
#include <stdio.h>
#include <stdarg.h>
int sum(int n, ...) {
va_list a; va_start(a, n);
int s = 0;
for (int i = 0; i < n; i++) s += va_arg(a, int);
va_end(a);
return s;
}
int main(void) {
printf("%d\n", sum(3, 1, 2, 3));
return 0;
}NULL işaretçisi sentinel'ları dikkat gerektirir
Sentinel olarak NULL kullanmak risklidir: bazı platformlarda NULL, işaretçiden farklı boyuta sahip bir int olan 0 değeridir.
Doğru türün geçirildiğinden emin olmak için (char *)NULL gibi açıkça tür dönüşümü uygulayın.
#include <stdio.h>
#include <stdarg.h>
void print_all(const char *first, ...) {
va_list a; va_start(a, first);
const char *s = first;
while (s) { printf("%s\n", s); s = va_arg(a, const char *); }
va_end(a);
}
int main(void) {
print_all("a", "b", (char *)NULL);
return 0;
}Derleyici biçim öznitelikleri
GCC ve Clang, işlevinizin printf tarzı biçimlendirme kullandığını derleyiciye bildirmek için __attribute__((format(printf, 1, 2))) sunar.
Derleyici daha sonra biçim dizilerinizi derleme zamanında denetleyerek birçok hatayı yakalar.
#include <stdio.h>
#include <stdarg.h>
void logf(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
void logf(const char *fmt, ...) {
va_list a; va_start(a, fmt);
vprintf(fmt, a);
va_end(a);
}
int main(void) {
logf("%d items\n", 3);
return 0;
}Daha güvenli seçenekleri tercih edin
Değişken sayıda bağımsız değişken hataya açık olduğundan mümkün olduğunda tür güvenli tasarımları tercih edin: açık bir dizi, bir yapı veya sabit parametreler geçirin.
Değişken sayıda bağımsız değişken kullanımını gerçek printf benzeri gereksinimlerle sınırlayın.
#include <stdio.h>
int sum_array(const int *a, int n) {
int s = 0;
for (int i = 0; i < n; i++) s += a[i];
return s;
}
int main(void) {
int nums[] = {1, 2, 3, 4};
printf("%d\n", sum_array(nums, 4));
return 0;
}Sözleşmeyi belgeleyin
Derleyici değişken sayıda bağımsız değişkenin türlerini zorlayamadığından açık belgeler güvenlik ağınızdır.
Çağıranın tam olarak hangi türleri, kaç bağımsız değişkeni sağlaması gerektiğini ve listenin nasıl sona erdiğini belirtin.
#include <stdio.h>
#include <stdarg.h>
/* sum_ints(n, ...): pass exactly n int values */
int sum_ints(int n, ...) {
va_list a; va_start(a, n);
int s = 0;
for (int i = 0; i < n; i++) s += va_arg(a, int);
va_end(a);
return s;
}
int main(void) {
printf("%d\n", sum_ints(2, 5, 5));
return 0;
}Kapsamlı test yapmak
Hatalar sessizce gizlenebildiğinden değişken sayıda bağımsız değişken alan işlevleri birçok bağımsız değişken adedi ve türüyle test edin.
Sıfır bağımsız değişken veya en yüksek adet gibi sınır durumları çoğu zaman hataları ortaya çıkarır.
#include <stdio.h>
#include <stdarg.h>
int sum(int n, ...) {
va_list a; va_start(a, n);
int s = 0;
for (int i = 0; i < n; i++) s += va_arg(a, int);
va_end(a);
return s;
}
int main(void) {
printf("%d\n", sum(0));
printf("%d\n", sum(1, 9));
return 0;
}Hızlı kontrol
Değişken sayıda bağımsız değişken türlerinin risklerini ne kadar anladığınızı test edin.
Özet
Değişken sayıda bağımsız değişken alan işlevlerin tehlikelerini öğrendiniz:
- Derleyici, değişken sayıda bağımsız değişkenleri tür açısından denetlemez.
- Yanlış türler, yanlış adetler ve hatalı sentinel'lar tanımsız davranışa neden olur.
- Yükseltmeleri hatırlayın: küçük tam sayılar
inttürüne,floatisedoubletürüne dönüşür. - Derleyici biçim özniteliklerini kullanın, sözleşmeyi belgeleyin ve mümkün olduğunda tür güvenli seçenekleri tercih edin.
Yapay zeka eğitmeniyle C öğren — ücretsiz
Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.
- Kurslar
- 39
- Dersler
- 144
Sıkça Sorulan Sorular
“Tür Güvenliği Kaygıları” dersi ücretsiz mi?
Evet — “Tür Güvenliği Kaygıları” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C Academy kursu toplamda 4 dersten oluşur.
“Tür Güvenliği Kaygıları” dersinde ne öğreneceğim?
Değişken bağımsız değişkenlerin riskleri C Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Tür Güvenliği Kaygıları” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- stdarg Makroları
- printf Benzeri İşlevler Yazma
- Tür Güvenliği Kaygıları
- Pratik Örnekler