C varsayılan bağımsız değişkenleri


279

C'deki bir işleve varsayılan bağımsız değişkenler belirtmenin bir yolu var mı?


6
sadece biraz daha iyi bir C istiyorum, C ++ değil. düşünmek C +. C ++ 'dan kaldırılan çeşitli küçük iyileştirmelerle, ancak büyük karışıklık değil. Ve lütfen, farklı bir bağlantı yükleyici yok. sadece önişlemci benzeri başka bir adım olmalıdır. standardize. her yerde ...
ivo Welch

Yan çubukta listelemediğim ilgili soru .
Shelby Moore III

Barbar olmayı bırak ve C ++ (11, ...) kullanmayı öğren - jk! / ben alevler söndürürüm ... ama ... onu sevmeye geleceksin ... hahaha kendime yardım edemiyorum, üzgünüm.
moodboom

Yanıtlar:


147

Pek sayılmaz. Tek yol bir varargs işlevi yazmak ve arayanın geçmediği argümanlar için varsayılan değerleri manuel olarak doldurmaktır.


22
Varargs kullanırken kontrol eksikliği nefret ediyorum.
dmckee --- eski moderatör kedi yavrusu

16
Ayrıca yapmalısınız; Aslında bunu tavsiye etmiyorum; Sadece bunun mümkün olduğunu anlatmak istedim.
Eli Courtwright

4
Ancak, arayan kişinin argümanı geçip geçmediğini nasıl kontrol etmek istersiniz? Bunun işe yaradığını düşünüyorum, arayanın geçmediğini söyleyecek arayan yok mu? Bunun tüm yaklaşımı biraz daha az kullanılabilir hale getirdiğini düşünüyorum - arayan başka bir isimle bir işlevi de arayabilir.
Johannes Schaub - litb

3
open(2)Sistem çağrısı gerekli argümanlar bağlı mevcut olabilir isteğe bağlı bir argüman için bu kullanır ve printf(3)kaç argüman belirtir olacağı bir biçim dizesi okur. Her ikisi de varargs'ı oldukça güvenli ve etkili bir şekilde kullanıyor ve kesinlikle onları vidalayabilseniz de, printf()özellikle oldukça popüler görünüyor.
Chris Lutz

4
@Eli: Tüm C derleyicileri gcc değildir. Printf () argümanlarınız biçim dizenizle eşleşmediğinde uyarması için bazı gelişmiş derleyici sihri vardır. Ve kendi değişken fonksiyonlarınız için benzer uyarılar almanın mümkün olduğunu düşünmüyorum (aynı biçim dizesini kullanmadığı sürece).
tomlogic

280

Vay canına, buralarda herkes çok kötümser. Cevap Evet.

Bu önemsiz değil: sonunda, çekirdek fonksiyona, destekleyici bir yapıya, bir sarmalayıcı fonksiyonuna ve sarmalayıcı fonksiyonunun etrafında bir makroya sahip olacağız. Çalışmamda bütün bunları otomatikleştirmek için bir dizi makro var; akışı anladıktan sonra, aynı şeyi yapmanız kolay olacaktır.

Bunu başka bir yerde yazdım, işte burada özeti tamamlamak için ayrıntılı bir dış bağlantı: http://modelingwithdata.org/arch/00000022.htm

Dönmek istiyoruz

double f(int i, double x)

varsayılanları alan bir işleve (i = 8, x = 3.14). Tamamlayıcı bir yapı tanımlayın:

typedef struct {
    int i;
    double x;
} f_args;

İşlevinizi yeniden adlandırın f_baseve varsayılanları ayarlayan ve tabanı çağıran bir sarmalayıcı işlevi tanımlayın:

double var_f(f_args in){
    int i_out = in.i ? in.i : 8;
    double x_out = in.x ? in.x : 3.14;
    return f_base(i_out, x_out);
}

Şimdi C'nin değişken makrolarını kullanarak bir makro ekleyin. Bu şekilde, kullanıcıların aslında bir f_argsyapı doldurduklarını bilmeleri ve her zamanki gibi yaptıklarını düşünmeleri gerekmez :

#define f(...) var_f((f_args){__VA_ARGS__});

Tamam, şimdi aşağıdakilerin hepsi işe yarayacak:

f(3, 8);      //i=3, x=8
f(.i=1, 2.3); //i=1, x=2.3
f(2);         //i=2, x=3.14
f(.x=9.2);    //i=8, x=9.2

Bileşik başlatıcıların kesin kurallar için varsayılanları nasıl ayarladığına ilişkin kuralları kontrol edin.

İşe yaramayacak bir şey: f(0)çünkü eksik bir değer ile sıfır arasında ayrım yapamayız. Deneyimlerime göre, bu dikkat edilmesi gereken bir şey, ancak ihtiyaç ortaya çıktığında halledilebilir --- varsayılanınızın yarısı gerçekten sıfırdır.

Bunu yazma zahmetinden geçtim, çünkü adlandırılmış argümanlar ve varsayılanların gerçekten C'deki kodlamayı daha kolay ve daha eğlenceli hale getirdiğini düşünüyorum. Ve C, bu kadar basit ve hala tüm bunları mümkün kılmak için yeterince sahip olduğu için harika.


16
+1 reklam öğesi! Sınırlamaları vardır, ancak adlandırılmış parametreleri tabloya getirir. {}(Boş başlatıcı) bir C99 hatası olduğunu unutmayın .
u0b34a0f6ae

28
Ancak, işte sizin için harika bir şey: Standart, adlandırılmış üyeleri birden çok kez belirtmeye izin verir, daha sonra geçersiz kılar. Yani adlandırılmış parametreler için sadece varsayılan sorunu çözebilir ve boş bir aramaya izin verebilirsiniz. #define vrange(...) CALL(range,(param){.from=1, .to=100, .step=1, __VA_ARGS__})
u0b34a0f6ae

3
Umarım derleyici hataları okunabilir, ancak bu harika bir tekniktir! Neredeyse python kwargs'a benziyor.
totowtwo

6
@ RunHolt Kesinlikle daha basit olsa da, objektif olarak daha iyi değil; adlandırılmış parametreler, çağrıların okunabilirliğinin kolaylığı (kaynak kodun okunabilirliği pahasına) gibi avantajlarla birlikte gelir. Biri kaynağın geliştiricileri için daha iyidir, diğeri fonksiyonun kullanıcıları için daha iyidir. "Bu daha iyi!"
Alice

3
@DawidPi: C11 6.7.9 (19), toplamaların başlatılmasında: "açıkça başlatılmayan tüm alt nesneler, statik depolama süresine sahip nesnelerle aynı şekilde başlatılmalıdır" Ve bildiğiniz gibi, statik süre öğeleri sıfıra sıfırlanır | NULL | \ 0. [Bu da c99'daydı.]
bk.

161

Evet. :-) Ama beklediğiniz bir şekilde değil.

int f1(int arg1, double arg2, char* name, char *opt);

int f2(int arg1, double arg2, char* name)
{
  return f1(arg1, arg2, name, "Some option");
}

Ne yazık ki, C, yöntemleri aşırı yüklemenize izin vermez, bu nedenle iki farklı işlevle sonuçlanırsınız. Yine de, f2'yi çağırarak, aslında varsayılan bir değerle f1'i çağırırsınız. Bu, mevcut kodu kopyalamak / yapıştırmaktan kaçınmanıza yardımcı olan bir "Kendinizi Tekrarlama" çözümüdür.


24
FWIW, işlevin sonundaki sayıyı, alacağı bağımsız değişken sayısını belirtmek için kullanmayı tercih ederim. Herhangi bir rasgele sayı kullanmaktan daha kolay hale getirir. :)
Macke

4
Bu, en iyi cevaptır, çünkü aynı hedefe ulaşmak için basit bir yol gösterir. Değiştirmek istemediğim sabit bir API'nin bir parçası olan bir fonksiyonum var, ancak yeni bir param alması gerekiyor. Tabii ki, o kadar körü körüne açık ki kaçırdım (varsayılan param düşünmeye takılıp var!)
RunHolt

4
f2 ayrıca bir önişlemci makrosu olabilir
osvein

41

Varsayılan değerler için adlandırılmış parametreler (yalnızca) kullanan işlevler oluşturabiliriz. Bu, bk.'nin cevabının devamıdır.

#include <stdio.h>                                                               

struct range { int from; int to; int step; };
#define range(...) range((struct range){.from=1,.to=10,.step=1, __VA_ARGS__})   

/* use parentheses to avoid macro subst */             
void (range)(struct range r) {                                                     
    for (int i = r.from; i <= r.to; i += r.step)                                 
        printf("%d ", i);                                                        
    puts("");                                                                    
}                                                                                

int main() {                                                                     
    range();                                                                    
    range(.from=2, .to=4);                                                      
    range(.step=2);                                                             
}    

C99 standardı, başlatma işlemindeki sonraki adların önceki öğeleri geçersiz kıldığını tanımlar. Bazı standart konumsal parametrelerimiz de olabilir, sadece makro ve fonksiyon imzasını buna göre değiştirin. Varsayılan değer parametreleri yalnızca adlandırılmış parametre stilinde kullanılabilir.

Program çıktısı:

1 2 3 4 5 6 7 8 9 10 
2 3 4 
1 3 5 7 9

2
Bu, Wim ten Brink veya BK çözümünden daha kolay ve daha basit bir uygulama gibi görünüyor. Bu uygulamanın diğerlerinin de sahip olmadığı bir dezavantajı var mı?
stephenmm

24

OpenCV şöyle bir şey kullanır:

/* in the header file */

#ifdef __cplusplus
    /* in case the compiler is a C++ compiler */
    #define DEFAULT_VALUE(value) = value
#else
    /* otherwise, C compiler, do nothing */
    #define DEFAULT_VALUE(value)
#endif

void window_set_size(unsigned int width  DEFAULT_VALUE(640),
                     unsigned int height DEFAULT_VALUE(400));

Kullanıcı ne yazması gerektiğini bilmiyorsa, bu hile yardımcı olabilir:

kullanım örneği


19

Hayır.

En yeni C99 standardı bile bunu desteklemiyor.


basit bir hayır daha iyi olurdu;)
KevinDTimm

21
@kevindtimm: Bu mümkün değil, SO cevaplar için minimum bir süre gerektiriyor. Denedim. :)
gevşeyin

2
Lütfen cevabıma bakın. :)
kaos


14

Kısa cevap: Hayır.

Biraz daha uzun cevap: İsteğe bağlı bağımsız değişkenler için ayrıştırdığınız bir dizeyi ilettiğiniz eski, eski bir geçici çözüm vardır :

int f(int arg1, double arg2, char* name, char *opt);

Burada opt, "name = value" çifti veya başka bir şey içerebilir ve buna şöyle diyebilirsiniz

n = f(2,3.0,"foo","plot=yes save=no");

Açıkçası bu sadece zaman zaman yararlıdır. Genellikle işlevsellik ailesine tek bir arayüz istediğinizde.


Bu yaklaşımı hala c ++ 'da profesyonel programlar tarafından yazılan parçacık fiziği kodlarında bulabilirsiniz (örneğin ROOT gibi) ) . Ana avantajı, geri uyumluluğu korurken neredeyse süresiz olarak genişletilebilmesidir.


2
Bunu varargs ile birleştirin ve her türlü eğlenceye sahip olun!
David Thornley

5
Ben bir özel kullanmak structve arayan biri yapmak, farklı seçenekler için alanları doldurmak ve sonra adrese göre geçmek veya NULLvarsayılan seçenekler için geçmek istiyorum .
Chris Lutz

Kod kalıplarını KÖK'den kopyalamak korkunç bir fikir!
innisfree

13

Muhtemelen bunu yapmanın en iyi yolu (durumunuza bağlı olarak sizin durumunuzda mümkün olabilir veya olmayabilir) C ++ 'a geçmek ve' daha iyi bir C 'olarak kullanmaktır. Sınıfları, şablonları, operatör aşırı yüklemesini veya diğer gelişmiş özellikleri kullanmadan C ++ kullanabilirsiniz.

Bu, fonksiyon aşırı yüklenmesi ve varsayılan parametrelerle (ve kullanmayı seçtiğiniz diğer özelliklerle) C değişkenini verecektir. Sadece sınırlı bir C ++ alt kümesi kullanma konusunda gerçekten ciddiyseniz, biraz disiplinli olmanız gerekir.

Birçok insan C ++ 'ı bu şekilde kullanmanın korkunç bir fikir olduğunu söyleyebilir ve bir anlamı olabilir. Ama bu sadece bir fikir; Ben her şeyi satın almak zorunda kalmadan rahat C ++ özelliklerini kullanmak için geçerli olduğunu düşünüyorum. C ++ 'ın başarısının nedeninin önemli bir kısmının, ilk günlerinde çok fazla programcı tarafından tam olarak bu şekilde kullanılmasıdır.


13

Yine başka bir seçenek structs kullanır :

struct func_opts {
  int    arg1;
  char * arg2;
  int    arg3;
};

void func(int arg, struct func_opts *opts)
{
    int arg1 = 0, arg3 = 0;
    char *arg2 = "Default";
    if(opts)
      {
        if(opts->arg1)
            arg1 = opts->arg1;
        if(opts->arg2)
            arg2 = opts->arg2;
        if(opts->arg3)
            arg3 = opts->arg3;
      }
    // do stuff
}

// call with defaults
func(3, NULL);

// also call with defaults
struct func_opts opts = {0};
func(3, &opts);

// set some arguments
opts.arg3 = 3;
opts.arg2 = "Yes";
func(3, &opts);

9

Hayır.


2
geçici çözüm nedir? 20202020Onaltılı olduğunu görebiliyorum , ama nasıl yazarım?
Lazer

5

Makro kullanan başka bir numara:

#include <stdio.h>

#define func(...) FUNC(__VA_ARGS__, 15, 0)
#define FUNC(a, b, ...) func(a, b)

int (func)(int a, int b)
{
    return a + b;
}

int main(void)
{
    printf("%d\n", func(1));
    printf("%d\n", func(1, 2));
    return 0;
}

Yalnızca bir bağımsız değişken iletilirse, bvarsayılan değeri alır (bu durumda 15)


4

Hayır, ancak varsayılan bağımsız değişkenleri kullanarak yaklaşık değerlere erişmek için bir dizi işlev (veya makro) kullanmayı düşünebilirsiniz :

// No default args
int foo3(int a, int b, int c)
{
    return ...;
}

// Default 3rd arg
int foo2(int a, int b)
{
    return foo3(a, b, 0);  // default c
}

// Default 2nd and 3rd args
int foo1(int a)
{
    return foo3(a, 1, 0);  // default b and c
}


3

Genellikle hayır, ancak gcc funcA () parametresinin son parametresini bir makro ile isteğe bağlı yapabilirsiniz.

FuncB () 'de' b 'parametresi için varsayılan değere ihtiyacım olduğunu belirtmek için özel bir değer (-1) kullanıyorum.

#include <stdio.h> 

int funcA( int a, int b, ... ){ return a+b; }
#define funcA( a, ... ) funcA( a, ##__VA_ARGS__, 8 ) 


int funcB( int a, int b ){
  if( b == -1 ) b = 8;
  return a+b;
}

int main(void){
  printf("funcA(1,2): %i\n", funcA(1,2) );
  printf("funcA(1):   %i\n", funcA(1)   );

  printf("funcB(1, 2): %i\n", funcB(1, 2) );
  printf("funcB(1,-1): %i\n", funcB(1,-1) );
}

1

Jens Gustedt'ın cevabını geliştirdim ki:

  1. satır içi işlevler kullanılmaz
  2. önişleme sırasında varsayılanlar hesaplanır
  3. modüler tekrar kullanılabilir makrolar
  4. izin verilen varsayılanlar için yetersiz argümanlar durumunda anlamlı şekilde eşleşen derleyici hatası ayarlamak mümkündür
  5. bağımsız değişken türleri açık kalacaksa, parametre listesinin kuyruğunu oluşturmak için varsayılanlar gerekli değildir
  6. C11 _Generic ile birlikte çalışma
  7. işlev adını bağımsız değişken sayısına göre değiştirin!

variadic.h:

#ifndef VARIADIC

#define _NARG2(_0, _1, _2, ...) _2
#define NUMARG2(...) _NARG2(__VA_ARGS__, 2, 1, 0)
#define _NARG3(_0, _1, _2, _3, ...) _3
#define NUMARG3(...) _NARG3(__VA_ARGS__, 3, 2, 1, 0)
#define _NARG4(_0, _1, _2, _3, _4, ...) _4
#define NUMARG4(...) _NARG4(__VA_ARGS__, 4, 3, 2, 1, 0)
#define _NARG5(_0, _1, _2, _3, _4, _5, ...) _5
#define NUMARG5(...) _NARG5(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
#define _NARG6(_0, _1, _2, _3, _4, _5, _6, ...) _6
#define NUMARG6(...) _NARG6(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
#define _NARG7(_0, _1, _2, _3, _4, _5, _6, _7, ...) _7
#define NUMARG7(...) _NARG7(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
#define _NARG8(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) _8
#define NUMARG8(...) _NARG8(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define _NARG9(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) _9
#define NUMARG9(...) _NARG9(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define __VARIADIC(name, num_args, ...) name ## _ ## num_args (__VA_ARGS__)
#define _VARIADIC(name, num_args, ...) name (__VARIADIC(name, num_args, __VA_ARGS__))
#define VARIADIC(name, num_args, ...) _VARIADIC(name, num_args, __VA_ARGS__)
#define VARIADIC2(name, num_args, ...) __VARIADIC(name, num_args, __VA_ARGS__)

// Vary function name by number of arguments supplied
#define VARIADIC_NAME(name, num_args) name ## _ ## num_args ## _name ()
#define NVARIADIC(name, num_args, ...) _VARIADIC(VARIADIC_NAME(name, num_args), num_args, __VA_ARGS__)

#endif

Basitleştirilmiş kullanım senaryosu:

const uint32*
uint32_frombytes(uint32* out, const uint8* in, size_t bytes);

/*
The output buffer defaults to NULL if not provided.
*/

#include "variadic.h"

#define uint32_frombytes_2(   b, c) NULL, b, c
#define uint32_frombytes_3(a, b, c)    a, b, c
#define uint32_frombytes(...) VARIADIC(uint32_frombytes, NUMARG3(__VA_ARGS__), __VA_ARGS__)

Ve _Generic ile:

const uint8*
uint16_tobytes(const uint16* in, uint8* out, size_t bytes);

const uint16*
uint16_frombytes(uint16* out, const uint8* in, size_t bytes);

const uint8*
uint32_tobytes(const uint32* in, uint8* out, size_t bytes);

const uint32*
uint32_frombytes(uint32* out, const uint8* in, size_t bytes);

/*
The output buffer defaults to NULL if not provided.
Generic function name supported on the non-uint8 type, except where said type
is unavailable because the argument for output buffer was not provided.
*/

#include "variadic.h"

#define   uint16_tobytes_2(a,    c) a, NULL, c
#define   uint16_tobytes_3(a, b, c) a,    b, c
#define   uint16_tobytes(...) VARIADIC(  uint16_tobytes, NUMARG3(__VA_ARGS__), __VA_ARGS__)

#define uint16_frombytes_2(   b, c) NULL, b, c
#define uint16_frombytes_3(a, b, c)    a, b, c
#define uint16_frombytes(...) VARIADIC(uint16_frombytes, NUMARG3(__VA_ARGS__), __VA_ARGS__)

#define   uint32_tobytes_2(a,    c) a, NULL, c
#define   uint32_tobytes_3(a, b, c) a,    b, c
#define   uint32_tobytes(...) VARIADIC(  uint32_tobytes, NUMARG3(__VA_ARGS__), __VA_ARGS__)

#define uint32_frombytes_2(   b, c) NULL, b, c
#define uint32_frombytes_3(a, b, c)    a, b, c
#define uint32_frombytes(...) VARIADIC(uint32_frombytes, NUMARG3(__VA_ARGS__), __VA_ARGS__)

#define   tobytes(a, ...) _Generic((a),                                                                                                 \
                                   const uint16*: uint16_tobytes,                                                                       \
                                   const uint32*: uint32_tobytes)  (VARIADIC2(  uint32_tobytes, NUMARG3(a, __VA_ARGS__), a, __VA_ARGS__))

#define frombytes(a, ...) _Generic((a),                                                                                                 \
                                         uint16*: uint16_frombytes,                                                                     \
                                         uint32*: uint32_frombytes)(VARIADIC2(uint32_frombytes, NUMARG3(a, __VA_ARGS__), a, __VA_ARGS__))

Ve _Generic ile birleştirilemeyen değişken fonksiyon adı seçimi ile:

// winternitz() with 5 arguments is replaced with merkle_lamport() on those 5 arguments.

#define   merkle_lamport_5(a, b, c, d, e) a, b, c, d, e
#define   winternitz_7(a, b, c, d, e, f, g) a, b, c, d, e, f, g
#define   winternitz_5_name() merkle_lamport
#define   winternitz_7_name() winternitz
#define   winternitz(...) NVARIADIC(winternitz, NUMARG7(__VA_ARGS__), __VA_ARGS__)

1

EVET

Makrolar aracılığıyla

3 Parametreler:

#define my_func2(...) my_func3(__VA_ARGS__, 0.5)
#define my_func1(...) my_func2(__VA_ARGS__, 10)
#define VAR_FUNC(_1, _2, _3, NAME, ...) NAME
#define my_func(...) VAR_FUNC(__VA_ARGS__, my_func3, my_func2, my_func1)(__VA_ARGS__)

void my_func3(char a, int b, float c) // b=10, c=0.5
{
    printf("a=%c; b=%d; c=%f\n", a, b, c);
}

4. bağımsız değişken istiyorsanız, fazladan bir my_func3 eklenmelidir. VAR_FUNC, my_func2 ve my_func'daki değişikliklere dikkat edin

4 Parametreler:

#define my_func3(...) my_func4(__VA_ARGS__, "default") // <== New function added
#define my_func2(...) my_func3(__VA_ARGS__, (float)1/2)
#define my_func1(...) my_func2(__VA_ARGS__, 10)
#define VAR_FUNC(_1, _2, _3, _4, NAME, ...) NAME
#define my_func(...) VAR_FUNC(__VA_ARGS__, my_func4, my_func3, my_func2, my_func1)(__VA_ARGS__)

void my_func4(char a, int b, float c, const char* d) // b=10, c=0.5, d="default"
{
    printf("a=%c; b=%d; c=%f; d=%s\n", a, b, c, d);
}

Sadece yüzer istisna değişkenleri (varsayılan değerler verilemez o 3 parametre olduğu gibi son argüman ise olmadıkça ) onlar dönemini gerektiğinden, ( ''), makro argümanlarla kabul edilmez hangi. Ancak my_func2 makrosunda görüldüğü gibi bir çözüm bulabilir ( 4 parametreli büyük / küçük harf durumu) )

program

int main(void)
{
    my_func('a');
    my_func('b', 20);
    my_func('c', 200, 10.5);
    my_func('d', 2000, 100.5, "hello");

    return 0;
}

Çıktı:

a=a; b=10; c=0.500000; d=default                                                                                                                                                  
a=b; b=20; c=0.500000; d=default                                                                                                                                                  
a=c; b=200; c=10.500000; d=default                                                                                                                                                
a=d; b=2000; c=100.500000; d=hello  

0

Evet, bir şeyler simulair yapabilirsiniz, burada alabileceğiniz farklı argüman listelerini bilmelisiniz, ancak hepsini işlemek için aynı işleve sahipsiniz.

typedef enum { my_input_set1 = 0, my_input_set2, my_input_set3} INPUT_SET;

typedef struct{
    INPUT_SET type;
    char* text;
} input_set1;

typedef struct{
    INPUT_SET type;
    char* text;
    int var;
} input_set2;

typedef struct{
    INPUT_SET type;
    int text;
} input_set3;

typedef union
{
    INPUT_SET type;
    input_set1 set1;
    input_set2 set2;
    input_set3 set3;
} MY_INPUT;

void my_func(MY_INPUT input)
{
    switch(input.type)
    {
        case my_input_set1:
        break;
        case my_input_set2:
        break;
        case my_input_set3:
        break;
        default:
        // unknown input
        break;
    }
}

-6

Bunu neden yapamıyoruz?

İsteğe bağlı bağımsız değişkene varsayılan bir değer verin. Bu şekilde, işlevin arayanının bağımsız değişkenin değerini iletmesi gerekmez. Bağımsız değişken varsayılan değeri alır. Ve bu argüman kolayca müşteri için isteğe bağlı hale gelir.

Örneğin;

void foo (int a, int b = 0);

Burada b isteğe bağlı bir argüman.


10
Çarpıcı bir fikir, sorun, C'nin isteğe bağlı argümanları veya aşırı yüklenmiş işlevleri desteklememesi, bu nedenle doğrudan çözüm derlenmiyor.
Thomas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.