Bästa svaret
Först en grepp: C och C ++ är två olika språk. Svaret nedan gäller råkar för båda, men ibland skiljer sig svaret mellan språken. Och på båda språken har uttrycket c/c++
odefinierat beteende.
Detta är ett fånigt sätt att få en typkampanj. Observera att exemplet i detaljerna formuleras tydligare:
int a, b;
long long l = a * 1ll * b;
Som OP noterar förklarar 1ll
ett long long
bokstavligt heltal.
Dess närvaro här i koden främjar hela multiplikationen till long long
genom vanliga aritmetiska omvandlingar, särskilt heltalskampanjer.
Uttrycket tolkas som ((a * 1ll) * b)
. Den första multiplikationen returnerar bara värdet av a
som long long
. Den andra multiplikationen uppgraderas sedan till long long
.
Du kunde ha fått samma effekt med en uttrycklig rollbesättning:
int a, b;
long long l = (long long)a * b;
Det skriver lite mer, men bara lite. Den andra formuleringen är verkligen tydligare, åtminstone för mig.
Du kan också göra något som:
long long l = a;
l *= b;
Men det börjar bli fånigt igen.
Varför måste du marknadsföra? Om du har tillräckligt stora värden kan multiplikationen rinna över. Genom att marknadsföra till long long
garanterar du att du inte gör det.
Låt oss anta att 32-bitars int
och 64- bit long long
och 2: s komplementrepresentation. Den största produkten du kan få är -2 ^ {31} \ times -2 ^ {31} = 2 ^ {62}. Det är under det största positiva värdet du kan representera, 2 ^ {63} – 1, så du är garanterad att du inte kommer att rinna över.
Svar
a och b är int int * int -> int (allt inom intervallet 32 bitars int ie -2147483648 int 2147483647) . ”. 2147483647 * 2 = -2 och inte 4294967294 tilldelningsoperatören har associativitet höger till vänster dvs. i uttrycket: lång lång l = a * b; a * b beräknas först int * int-> int om a = 2147483647 och b = 2 a * b -> – 2 och inte 4294967294 nu l = -2 -2 konverteras till lång lång och lagras i l