chapter 2 — operators & arithmetic

← back to C index · V:\KNOWLEDGE\NOTES\C

Final log

Operators turn stored values into new ones. The arithmetic is the easy part; the trap is type. The type of the operands decides the type of the result — and the machine resolves the whole expression before it ever reaches the variable on the left of the =.


code logs

code 1 — declaration & copy semantics

Objective: declare a variable; initialize one variable from another; declare several variables of the same type on a single line, separated by commas instead of semicolons.

#include <stdio.h>
int main() {
  int i = 10;
  int j = i;                  // copies the VALUE of i at this moment
  int a = 1, b = 2, c = 3, d = 4;  // four ints, one line, comma-separated
  printf("i = %d\n", i);
  printf("j = %d\n", j);
  printf("a=%d b=%d c=%d d=%d\n", a, b, c, d);
  return 0;
}

Output:

i = 10
j = 10
a=1 b=2 c=3 d=4

Walkthrough:

  • int j = i copies the value of i at the moment of assignment. Change i afterwards and j does not follow — they are two independent containers.
  • Multiple variables of the same type can be declared on one line, comma-separated. The compiler reads them left to right.
Key insight

Assignment in C is a copy, not a link. j = i duplicates the byte pattern; it does not bind the two names together.

code 1 (variation) — arithmetic across same-type variables

Objective: print the result of an arithmetic operation that uses several declared variables of the same datatype in one statement.

#include <stdio.h>
int main() {
  float price = 9.99;
  float discount = 2.50;
  float total = price - discount;   // resolved before assignment
  printf("total = %f\n", total);
  printf("price=%f discount=%f\n", price, discount);
  return 0;
}

Output:

total = 7.490000
price=9.990000 discount=2.500000

Walkthrough:

  • The subtraction is resolved at compile/runtime before the result is stored in total.
  • In GDB the variables are first reserved on the stack, then the reserved space is overwritten with the values we gave them.
  • Variables can be combined in one statement only when they share a datatype.

code 02 — sum, integer division & modulus

Objective: print the result of a sum, an integer division, and the remainder via the modulus operator.

#include <stdio.h>
int main() {
  int a = 17;
  int b = 5;
  int sum = a + b;             // solved at compile/runtime
  printf("a=%d b=%d\n", a, b);
  printf("sum = %d\n", sum);
  printf("quotient  = %d\n", a / b);   // integer division -> 3
  printf("remainder = %d\n", a % b);   // modulus          -> 2
  return 0;
}

Output:

a=17 b=5
sum = 22
quotient  = 3
remainder = 2

Walkthrough:

  • % (modulus) gives the amount left over after dividing one integer by another.
  • It cannot be applied to float — modulus is integers only.
  • With two int operands, both / and % produce int results.
Key insight

a / b on two ints throws away the fraction (integer division). a % b keeps only that thrown-away part. Together they fully describe the division.

code 02 (variation) — quotient & remainder, newline injected via a variable

Objective: print the quotient and remainder of a division without hardcoding the results — compute them with operators only — and inject a newline through a char variable rather than typing \n in the format string.

#include <stdio.h>
int main() {
  int dividend = 20;
  int divisor  = 6;
  char separator = '\n';
  printf("quotient  = %d%c", dividend / divisor, separator);
  printf("remainder = %d\n", dividend % divisor);
  return 0;
}

Output:

quotient  = 3
remainder = 2

Walkthrough:

  • dividend / divisor and dividend % divisor are computed by the machine — no literal answer is written into the code.
  • separator holds '\n'; the %c prints it, executing the line break exactly as a hardcoded \n would.

code 03 — type conversions

Objective: show how types convert inside an arithmetic operation. int with int stays int. The moment a float is involved, the whole result becomes float. Storing a float value into an int drops the fraction.

#include <stdio.h>
int main() {
  int   a = 7;
  float b = 2.0;
  float result1 = a / b;   // int / float -> float
  int   result2 = 3.9;     // float value into an int -> truncated
  printf("result1 = %f\n", result1);   // 3.500000
  printf("result2 = %d\n", result2);   // 3
  return 0;
}

Output:

result1 = 3.500000
result2 = 3

Walkthrough:

  • Print 1 — promotion: a / b is int / float. Any operand that is a float promotes the whole expression to float, so the result is 3.500000 instead of the integer 3.
  • Print 2 — truncation: 3.9 is a float literal, but result2 is an int. Converting float → int truncates toward zero — it chops the fraction off, it does not round. 3.9 becomes 3, not 4.
Truncation is not rounding

int x = 3.9; gives 3. C discards the decimal part; it never rounds to the nearest whole number. If you need rounding, that's a separate, deliberate step.

code 03 (variation) — Celsius → Fahrenheit, integer promotion & the division trap

Objective: read the user's initial (a char) and a Celsius temperature (an int); compute Fahrenheit as a float using the conversion formula — never hardcoding the result; print byte sizes; and demonstrate that a char is just a number by doing arithmetic on its ASCII value and printing it as both int and char. The newline is injected through a variable.

#include <stdio.h>
int main() {
  char  separator = '\n';
  char  initial;
  int   celsius;

  scanf("%c", &initial);   // user types a letter
  scanf("%d", &celsius);   // user types a whole number

  int bump   = 2;
  int shifted = initial + bump;   // integer promotion: ASCII value + 2

  float faren = celsius * (9.0 / 5.0) + 32;   // 9.0 forces float division

  printf("Initial: %c (value %d, %zu byte)%c",
         initial, initial, sizeof(char), separator);
  printf("Celsius: %d  ->  Fahrenheit: %f%c", celsius, faren, separator);
  printf("initial + 2 = %d as number, %c as char%c",
         shifted, shifted, separator);
  printf("Me llaman el mas piola%c", separator);
  return 0;
}

Input:

L
25

Output:

Initial: L (value 76, 1 byte)
Celsius: 25  ->  Fahrenheit: 77.000000
initial + 2 = 78 as number, N as char
Me llaman el mas piola

Walkthrough:

  • scanf order: the %c reads the letter first; %d then skips the leftover newline and reads the number. &initial and &celsius give scanf the addresses to write into.
  • Integer promotion: initial + bump works because the compiler takes the char's value in memory ('L' = 76), adds 2, and produces 78. Printed with %d it's 78; with %c it's 'N'. The machine stores everything as numbers — the format specifier just chooses the window.
  • The division trap: 9 / 5 with two ints would be 1 (integer division), giving a wrong temperature. Writing 9.0 makes one operand a float, so the division promotes to float and yields 1.8 — the decimal survives. Any int × float produces a float.
  • Association: parentheses around (9.0 / 5.0) force that division to happen first; the machine otherwise reads left to right. Group explicitly when order matters.
  • float is a different representation: an int like 78 can print as both a number and the char 'N'. A float like 78.0 cannot be printed with %c — floating point is a distinct encoding, not an ASCII code. To go from float to a character you must first convert it to an int.

concepts covered

conceptkey point
copy semanticsj = i copies the value, not a link. Independent containers.
multiple declarationSame-type variables on one line, comma-separated, read left to right.
modulus %Remainder of integer division. Integers only — never float.
operand → resultThe operand types decide the result type. Resolved before assignment.
integer promotionA char is a number; arithmetic on its ASCII value is legal.
float contaminationAny float in an expression promotes the whole result to float.
the 9.0/5 trap9/5 (int) = 1; 9.0/5 (float) = 1.8. Force one operand float.
truncationfloat → int chops the fraction toward zero. It does not round.
associationParentheses force evaluation order; otherwise left to right.

← prev: chapter 1 — variables, data types & IO

Built with LogoFlowershow