2016-03-14 15 views
30

Herbert Schildt mówi:Co to jest analiza argumentów?

W niektórych sytuacjach prawdziwa funkcja powinna być używana zamiast funkcji-Like-makro, na przykład: gdzie rozmiar kodu ma zostać zminimalizowane lub gdy argument nie może być oceniany więcej niż pewnego razu.

Co ma na myśli przez "argument nie może być oceniany więcej niż jeden raz?"

+8

Schildt jest [przez niektórych sceptycznie postrzegany] (https://en.wikipedia.org/wiki/Herbert_Schildt#Reception). Tylko mówię'. – DevSolar

+3

@DevSolar: Nie znam tej książki, ale jeśli cytowane stwierdzenie jest typowe dla tego stylu, w pełni zgadzam się ze sceptykami. – Olaf

+0

@DevSolar Masz na myśli [sceptyczny] (https://www.google.com/search?q=define%3Askceptical), prawda? A może pisałeś to z [C] (https://pl.wikipedia.org/wiki/C_ (programming_language)), ponieważ to pytanie zostało otagowane [tag: c], a nie [tag: k]? : P – cat

Odpowiedz

50

Weźmy makro obliczyć maksymalnie dwóch wartości:

#define MAX(a, b) ((a) < (b) ? (a) : (b)) 

Następnie używamy go tak:

int x = 5; 
int y = 10; 
int max = MAX(x++, y++); 

Wtedy makro jest rozszerzona do

int max = ((x++) < (y++) ? (x++) : (y++)); 

Jak widać, operacja inkrementacji na x lub y stanie się dwa razy, a nie to, co by się stało, gdybyś miał funkcję, w której każdy argument, który zdałeś, jest oceniany tylko raz.


Innym ważnym punktem jest użycie nawiasów w makrze. Weźmy inny prostego makra:

#define MUL(a, b) a * b 

Teraz, jeśli wywołać makro jak

int sum = MUL(x + 3, y - 2); 

następnie ekspansja staje

int sum = x + 3 * y - 2; 

które ze względu na operator precedence jest równa

int sum = x + (3 * y) - 2; 

Często nie do końca oczekiwano, jeśli ktoś oczekuje (x + 3) * (y - 2).

Ten problem jest również "rozwiązywany" za pomocą funkcji.

+0

Myślę, że to, co powiedziałeś, jest odwrotne. Aby wywołać funkcję 'max (x, x ++)', 'x' jest dwukrotnie oceniane, więc w tym przypadku użycie makra będzie w porządku. W wywołaniu makr "MAX (x ++, y ++);" żaden z argumentów nie był oceniany więcej niż jeden raz. – haccks

+5

@haccks To jest nieprawidłowe. Jak mówi Joachim w swojej odpowiedzi 'MAX (x ++, y ++)' jest rozszerzony do '((x ++) <(y ++)? (X ++): (y ++));' i dlatego jest oceniany dwa razy. Odpowiednia funkcja 'max (x ++, y ++)', każdy argument jest oceniany tylko raz – vu1p3n0x

+3

@haccks Oba wyrażenia 'x ++' i 'y ++' są oceniane jako część warunku. Następnie jeden z "x ++" lub "y ++" jest ponownie oceniany w zależności od warunku w wyrażeniu potrójnym. –

4

Czasami argumenty mają efekty uboczne .

Na przykład, wartość i++ jest i, ale i jest zwiększona o 1. W rezultacie, wartość następnego i++ będzie i + 1.

W makrze argumenty są obliczane za każdym razem, gdy są wywoływane, co powoduje powstanie wartości; W funkcji argumenty (rzeczywiste) są obliczane i kopiowane do (formalnych) argumentów wewnątrz funkcji, odrzucając efekty uboczne.

Podczas wykonywania funkcji nie musisz przejmować się efektami ubocznymi. Jednak niejawna promocja i rzutowanie może być podatne na błędy.