Types and variables in C — exercises with shapes, BMI, number bases and a scientific calculator (and the scanf without & that ends in a Segmentation fault)

The night before handing in my first C assignment, the program compiled, asked me for the grade, I typed a 7… and the terminal answered Segmentation fault (core dumped). Not a single clue about which line was failing. I went over the maths, the printf calls, the types. Half an hour later I saw it: one scanf was missing an &. A single character. And the worst part is that gcc had warned me when compiling, but the warning got lost in the rest of the text and I only checked whether the executable appeared. Since then I read every warning as if it were an error, and it’s the first thing I’ll ask of you in these exercises.

You’ve already seen the types and variables in C theory and the three programs in the practice. Now it’s your turn to write the code: four exercises on three levels, three “What’s wrong here?” snippets with real errors, the commented solutions and a cheat sheet to keep at hand in the IC2 labs.

How to use this article

  1. Read the statement and the expected output, and write your program in gedit (gedit shapes.c &).
  2. Compile with gcc -Wall -std=c11 shapes.c -o shapes and don’t move on until there are no warnings at all.
  3. If you’ve been stuck for more than 10 minutes, open the hint. If you’re still stuck, look only at the part of the solution you need.
  4. Type the same data as in the expected output and compare line by line. Then try others.

All the exercises use only what’s in this topic: types, operators, casts, printf and scanf. No if yet: when something needs classifying, we’ll use the trick from the theory, a comparison that is 1 or 0.

Basic level

Exercise 1: area and perimeter calculator for geometric shapes

Write a program that asks for the side of a square, the base and height of a rectangle and the radius of a circle (all with decimals), and shows the area and perimeter of the three shapes with 2 decimals. Formulas: square, area = side² and perimeter = 4 × side; rectangle, area = base × height and perimeter = 2 × (base + height); circle, area = π × radius² and perimeter = 2 × π × radius, with π = 3.14159.

Expected output (typing 4, 6, 3 and 5):

=== SHAPES CALCULATOR ===
Square side: 4
Rectangle base: 6
Rectangle height: 3
Circle radius: 5

--- Square with side 4.00 ---
Area:      16.00
Perimeter: 16.00

--- Rectangle 6.00 x 3.00 ---
Area:      18.00
Perimeter: 18.00

--- Circle with radius 5.00 ---
Area:      78.54
Perimeter: 31.42

Define π once at the top with #define PI 3.14159f and use float for the measurements, read with %f and &. C has no **: the square is side * side. And in the rectangle’s perimeter, watch the brackets: 2 * base + height isn’t the same as 2 * (base + height).

Exercise 2: BMI calculator with classification

Write a program that asks for your first initial, your weight in kilos and your height in metres, works out the body mass index (BMI = weight / height²) and classifies it according to the WHO: underweight (below 18.5), normal (from 18.5 to below 25), overweight (from 25 to below 30) and obese (30 or more). Since we don’t have if yet, the program shows the four categories with a 1 in the right one and a 0 in the others, plus a check line that adds the four (it must give 1).

Expected output (typing S, 70.5 and 1.78):

Your first initial: S
Weight (kg): 70.5
Height (m): 1.78

--- BMI for S. ---
Weight: 70.50 kg
Height: 1.78 m
BMI:    22.25
Underweight: 0 | Normal: 1 | Overweight: 0 | Obese: 0
Check (must be 1): 1

Each category is a comparison stored in an int: int normal = bmi >= 18.5f && bmi < 25.0f;. For the initial use scanf(" %c", &initial), with the space. And put brackets in weight / (height * height): without them, C would divide the weight by the height and then multiply by the height.

Intermediate level

Exercise 3: number base converter

Write a program that asks for an integer and shows it in decimal, in hexadecimal (lowercase and uppercase) and in octal, without doing the conversion by hand. Then extract its hundreds, tens and units using only / and % and add them up. Finally, show whether it’s even (1 or 0), how many bytes an int takes and the maximum value of an int.

Expected output (typing 255):

Enter an integer: 255

--- Conversions of 255 ---
Decimal:     255
Hexadecimal: ff
Hexadecimal: FF
Octal:       377

--- Digits (base 10) ---
Hundreds: 2, tens: 5, units: 5
Sum of digits: 12

--- Extra information ---
Is it even? (1 = yes): 0
Size of int: 4 bytes
Maximum int value: 2147483647

Printf converts on its own with %x, %X and %o. For the digits: number % 10 is the last one; number / 10 drops the last one, so number / 10 % 10 is the tens digit. The size comes from sizeof(int) (printed with %zu) and the maximum from the INT_MAX constant in <limits.h>.

Final challenge

Exercise 4: basic scientific calculator

This exercise brings the whole topic together. Write a calculator that asks for two integers A and B and shows in one go the basic operations (including both divisions and the remainder), the powers A², B² and A³, A written as an int, as a float, in hexadecimal and in octal, the size of int and float, and three comparisons (A > B, A == B and A != B) as 1 or 0. The columns have to line up as in the output.

Expected output (typing 15 and 4):

=== SCIENTIFIC CALCULATOR ===
Number A: 15
Number B: 4

--- Basic operations ---
A + B  = 19
A - B  = 11
A * B  = 60
A / B  = 3      (integer division)
A / B  = 3.7500 (real division)
A % B  = 3      (modulo/remainder)

--- Powers ---
A²     = 225
B²     = 16
A³     = 3375

--- Type information ---
A as int:      15
A as float:    15.000000
A as hex:      f
A as octal:    17
sizeof(int):   4 bytes
sizeof(float): 4 bytes

--- Comparisons ---
A > B:  1
A == B: 0
A != B: 1

To keep “3” and “(integer division)” in a column with the real division line, use a fixed, left-aligned width: %-6d. The % of the remainder is written %% inside printf. To show A as a float, convert it with (float)a: if you pass an int to %f, you get garbage.

What’s wrong here?

Three short snippets with one error each. Before reading the explanation, predict what will happen when you compile and run them.

Snippet 1: the grade that never arrives

#include <stdio.h>

int main(void) {
    int grade;
    printf("Exam grade: ");
    scanf("%d", grade);          /* the & is missing */
    printf("You got a %d\n", grade);
    return 0;
}

What do you think happens when you type a 7?

When compiling, gcc warns twice about the same thing:

no_ampersand.c: In function 'main':
no_ampersand.c:6: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Wformat=]
no_ampersand.c:6: warning: 'grade' is used uninitialized [-Wuninitialized]
no_ampersand.c:4: note: 'grade' was declared here

And when running it, typing 7:

Exam grade: 7
Segmentation fault (core dumped)

scanf("%d", grade) passes scanf the value of grade, which is still garbage, instead of its address. scanf takes that garbage as if it were a memory address and tries to write the 7 there. That address doesn’t belong to the program, and the system cuts it off with a Segmentation fault. It’s my story from the start, with its real output.

Only checking whether gcc creates the executable. The two warnings say exactly what’s going on: scanf expected an int * (an address) and got an int, and grade is used uninitialised.

The fix is the &:

#include <stdio.h>

int main(void) {
    int grade;
    printf("Exam grade: ");
    scanf("%d", &grade);         /* the address of grade */
    printf("You got a %d\n", grade);
    return 0;
}

Output, typing 7:

Exam grade: 7
You got a 7

When you write a scanf, read the line out loud: “store an integer at the address of grade”. If you can’t say “the address of”, the & is missing.

Snippet 2: the weight that comes out as zero

#include <stdio.h>

int main(void) {
    double weight;
    printf("Weight (kg): ");
    scanf("%f", &weight);         /* weight is a double */
    printf("Weight read: %.2f kg\n", weight);
    return 0;
}

What will it print when you type 70.5?

gcc’s warning:

weight_double.c: In function 'main':
weight_double.c:6: warning: format '%f' expects argument of type 'float *', but argument 2 has type 'double *' [-Wformat=]

And the run:

Weight (kg): 70.5
Weight read: 0.00 kg

No crash and no error: the program calmly says you weigh 0.00 kg. %f tells scanf to store a float (4 bytes), but weight is a double (8 bytes). scanf doesn’t know the variable’s real type: it writes 70.5 in float format into the first 4 bytes and leaves the other 4 as they were. The drawing shows it byte by byte:

Reading a double with %fThe 8 bytes of weight: scanf with %f writes only the first 4 (00 00 8d 42, which is 70.5 as a float) and the other 4 stay at zero, so the double is 5.5164e-315 and printf shows 0.00.scanf(“%f”, &weight) with a double weight: 4 bytes out of 8weight (double, 8 bytes)00008d4200000000scanf writes a float: 70.5it leaves these 4 aloneprintf reads all 8 bytes as a double:5.5164e-315 → “0.00”With %lf, scanf writes all 8 bytes of the double and you get 70.50.
scanf does not know weight’s type: it trusts the specifier and writes half of it.

Reading the 8 bytes as a double gives a tiny number (5.5 × 10⁻³¹⁵) which with 2 decimals is 0.00. On your computer you may get another value if those 4 bytes weren’t zero.

Copying printf’s specifier into scanf. In printf, %f works for float and double; in scanf, double is %lf, no exceptions.

The fix:

#include <stdio.h>

int main(void) {
    double weight;
    printf("Weight (kg): ");
    scanf("%lf", &weight);        /* double -> %lf in scanf */
    printf("Weight read: %.2f kg\n", weight);
    return 0;
}

Output, typing 70.5:

Weight (kg): 70.5
Weight read: 70.50 kg

Snippet 3: the triangle with no area

#include <stdio.h>

int main(void) {
    float base = 3.0f, height = 4.0f;
    float area = 1 / 2 * base * height;     /* area = base * height / 2 */
    printf("Triangle area: %.2f\n", area);
    return 0;
}

The formula is straight from the textbook, base times height over two. What does it print?

Triangle area: 0.00

0.00, and gcc says nothing, because there’s no type error: it’s all legal. C evaluates from left to right: first 1 / 2, which are two int, so it’s an integer division and gives 0. Then 0 × 3.0 × 4.0 = 0. It doesn’t matter that base and height are float: by the time they arrive, the damage is done.

Writing fractions like 1 / 2 or 4 / 3 in a formula. Between integers they’re 0 and 1. Write them as 1.0f / 2 or reorder so you divide at the end.

The fix is to divide at the end, when there’s already a float in front:

#include <stdio.h>

int main(void) {
    float base = 3.0f, height = 4.0f;
    float area = base * height / 2;         /* float / int: real division */
    printf("Triangle area: %.2f\n", area);
    return 0;
}

Output:

Triangle area: 6.00

3 × 4 = 12 and 12 / 2 = 6. Whenever you can, check a formula by hand with easy numbers before trusting the output.

Commented solutions

Solution to exercise 1

#include <stdio.h>
#define PI 3.14159f             /* constant: change it once and it works everywhere */

int main(void) {
    float side, base, height, radius;

    printf("=== SHAPES CALCULATOR ===\n");
    printf("Square side: ");
    scanf("%f", &side);                 /* & is required: scanf needs the address */
    printf("Rectangle base: ");
    scanf("%f", &base);
    printf("Rectangle height: ");
    scanf("%f", &height);
    printf("Circle radius: ");
    scanf("%f", &radius);

    printf("\n--- Square with side %.2f ---\n", side);
    printf("Area:      %.2f\n", side * side);          /* side² = side * side (there is no **) */
    printf("Perimeter: %.2f\n", 4 * side);             /* int * float = float */
    printf("\n--- Rectangle %.2f x %.2f ---\n", base, height);
    printf("Area:      %.2f\n", base * height);
    printf("Perimeter: %.2f\n", 2 * (base + height));  /* brackets: the sum goes first */
    printf("\n--- Circle with radius %.2f ---\n", radius);
    printf("Area:      %.2f\n", PI * radius * radius);
    printf("Perimeter: %.2f\n", 2 * PI * radius);
    return 0;
}

Output, typing 4, 6 and 3, and 5:

=== SHAPES CALCULATOR ===
Square side: 4
Rectangle base: 6
Rectangle height: 3
Circle radius: 5

--- Square with side 4.00 ---
Area:      16.00
Perimeter: 16.00

--- Rectangle 6.00 x 3.00 ---
Area:      18.00
Perimeter: 18.00

--- Circle with radius 5.00 ---
Area:      78.54
Perimeter: 31.42

Why it’s done this way:

  • #define PI 3.14159f puts π in a single place. If tomorrow you want more precision, you change one line. The f makes it a float, like the measurements.
  • All measurements are float because a side can be 2.5. If they were int, scanf with %d wouldn’t read the decimals.
  • 4 * side mixes an int and a float: C converts the 4 to float and the multiplication is decimal. There’s no division here, so there’s no trap.
  • 2 * (base + height) needs brackets because * comes before +: without them you’d get 2 × 6 + 3 = 15 instead of 18.

Checking by hand: 4 × 4 = 16 and 4 × 4 = 16 (the square with side 4 is the only one whose area and perimeter are equal); 6 × 3 = 18 and 2 × (6 + 3) = 18; 3.14159 × 25 = 78.54 and 2 × 3.14159 × 5 = 31.42.

Solution to exercise 2

#include <stdio.h>

int main(void) {
    char initial;
    float weight, height;

    printf("Your first initial: ");
    scanf(" %c", &initial);             /* space + & with %c too */
    printf("Weight (kg): ");
    scanf("%f", &weight);
    printf("Height (m): ");
    scanf("%f", &height);

    float bmi = weight / (height * height);     /* brackets: height² before dividing */
    /* each comparison is 1 or 0: only one of the four can be 1 */
    int under = bmi < 18.5f;
    int normal = bmi >= 18.5f && bmi < 25.0f;
    int over = bmi >= 25.0f && bmi < 30.0f;
    int obese = bmi >= 30.0f;

    printf("\n--- BMI for %c. ---\n", initial);
    printf("Weight: %.2f kg\n", weight);
    printf("Height: %.2f m\n", height);
    printf("BMI:    %.2f\n", bmi);
    printf("Underweight: %d | Normal: %d | Overweight: %d | Obese: %d\n",
           under, normal, over, obese);
    printf("Check (must be 1): %d\n", under + normal + over + obese);
    return 0;
}

Output, typing S, 70.5 and 1.78:

Your first initial: S
Weight (kg): 70.5
Height (m): 1.78

--- BMI for S. ---
Weight: 70.50 kg
Height: 1.78 m
BMI:    22.25
Underweight: 0 | Normal: 1 | Overweight: 0 | Obese: 0
Check (must be 1): 1

Why it’s done this way:

  • scanf(" %c", &initial) has the space even though it’s the first read: it does no harm and protects the program if one day you add another read before it.
  • weight / (height * height): without brackets, weight / height * height would be (70.5 / 1.78) × 1.78 = 70.5, the weight again.
  • The four categories are comparisons stored in int. The limits are written so they don’t overlap: normal starts at >= 18.5f exactly where under (< 18.5f) ends.
  • The check line adds the four: if the ranges are right, it always gives 1. If one day you see a 0 or a 2, there’s a gap or an overlap in the conditions.

Checking by hand: 1.78 × 1.78 = 3.1684 and 70.5 / 3.1684 = 22.25, between 18.5 and 25: normal.

ComparisonValue with BMI = 22.25
bmi < 18.5f0
bmi >= 18.5f && bmi < 25.0f1
bmi >= 25.0f && bmi < 30.0f0
bmi >= 30.0f0
Sum1

Solution to exercise 3

#include <stdio.h>
#include <limits.h>     /* INT_MAX */

int main(void) {
    int number;

    printf("Enter an integer: ");
    scanf("%d", &number);

    printf("\n--- Conversions of %d ---\n", number);
    printf("Decimal:     %d\n", number);
    printf("Hexadecimal: %x\n", number);    /* printf converts on its own */
    printf("Hexadecimal: %X\n", number);    /* capital X: capital letters */
    printf("Octal:       %o\n", number);

    int units = number % 10;                /* the last digit */
    int tens = number / 10 % 10;            /* drop one digit and take the last */
    int hundreds = number / 100 % 10;
    printf("\n--- Digits (base 10) ---\n");
    printf("Hundreds: %d, tens: %d, units: %d\n", hundreds, tens, units);
    printf("Sum of digits: %d\n", hundreds + tens + units);

    printf("\n--- Extra information ---\n");
    printf("Is it even? (1 = yes): %d\n", number % 2 == 0);
    printf("Size of int: %zu bytes\n", sizeof(int));
    printf("Maximum int value: %d\n", INT_MAX);
    return 0;
}

Output, typing 255:

Enter an integer: 255

--- Conversions of 255 ---
Decimal:     255
Hexadecimal: ff
Hexadecimal: FF
Octal:       377

--- Digits (base 10) ---
Hundreds: 2, tens: 5, units: 5
Sum of digits: 12

--- Extra information ---
Is it even? (1 = yes): 0
Size of int: 4 bytes
Maximum int value: 2147483647

Why it’s done this way:

  • printf doesn’t change the number: %d, %x and %o only change how it’s written. The value stored in number is the same on all four lines. The drawing shows it with the 8 bits of 255:
255 in binary, decimal, hexadecimal and octalEight bits set to 1 with weights 128 to 1 add up to 255; printf writes it as 255 with %d, ff with %x and 377 with %o; the digits come out with / and %.The same number, four ways to write it112816413211618141211binary: 1111 1111128+64+…+1 = 255%d255= 2·100 + 5·10 + 5 = 255%x / %Xff / FF= 15·16 + 15 = 255%o377= 3·64 + 7·8 + 7 = 255Digits with / and %: 255 % 10 = 5, 255 / 10 % 10 = 5, 255 / 100 % 10 = 2
printf does not change the number: only how it writes it.
  • The digits come out with integer division and remainder, from right to left. Trace with 255:
ExpressionStepResult
number % 10255 = 25 × 10 + 55 (units)
number / 10 % 10255 / 10 = 25; 25 % 105 (tens)
number / 100 % 10255 / 100 = 2; 2 % 102 (hundreds)
sum2 + 5 + 512
  • number % 2 == 0 is 1 if it’s even. 255 is odd: it prints 0.
  • sizeof(int) returns a size_t, and its specifier is %zu. With %d gcc warns, and with %lu (as in the first version of this article) it works on Linux but not on every system.

There’s no binary specifier in C11. The C23 standard adds %b, but with -std=c11, as in IC2, it isn’t available: if you need it, you get it bit by bit with % and / by 2.

Solution to exercise 4

#include <stdio.h>

int main(void) {
    int a, b;

    printf("=== SCIENTIFIC CALCULATOR ===\n");
    printf("Number A: ");
    scanf("%d", &a);            /* & on both: if one is missing, the program can crash */
    printf("Number B: ");
    scanf("%d", &b);

    printf("\n--- Basic operations ---\n");
    printf("A + B  = %d\n", a + b);
    printf("A - B  = %d\n", a - b);
    printf("A * B  = %d\n", a * b);
    printf("A / B  = %-6d (integer division)\n", a / b);   /* %-6d: 6 wide, left-aligned */
    printf("A / B  = %.4f (real division)\n", (float)a / b);
    printf("A %% B  = %-6d (modulo/remainder)\n", a % b);      /* %% prints a % */

    printf("\n--- Powers ---\n");
    printf("A²     = %d\n", a * a);
    printf("B²     = %d\n", b * b);
    printf("A³     = %d\n", a * a * a);

    printf("\n--- Type information ---\n");
    printf("A as int:      %d\n", a);
    printf("A as float:    %f\n", (float)a);     /* the cast makes %f get a float */
    printf("A as hex:      %x\n", a);
    printf("A as octal:    %o\n", a);
    printf("sizeof(int):   %zu bytes\n", sizeof(int));
    printf("sizeof(float): %zu bytes\n", sizeof(float));

    printf("\n--- Comparisons ---\n");
    printf("A > B:  %d\n", a > b);
    printf("A == B: %d\n", a == b);
    printf("A != B: %d\n", a != b);
    return 0;
}

Output, typing 15 and 4:

=== SCIENTIFIC CALCULATOR ===
Number A: 15
Number B: 4

--- Basic operations ---
A + B  = 19
A - B  = 11
A * B  = 60
A / B  = 3      (integer division)
A / B  = 3.7500 (real division)
A % B  = 3      (modulo/remainder)

--- Powers ---
A²     = 225
B²     = 16
A³     = 3375

--- Type information ---
A as int:      15
A as float:    15.000000
A as hex:      f
A as octal:    17
sizeof(int):   4 bytes
sizeof(float): 4 bytes

--- Comparisons ---
A > B:  1
A == B: 0
A != B: 1

Why it’s done this way:

  • %-6d reserves 6 spaces aligned to the left: the 3 takes 1 and is followed by 5 spaces, so “(integer division)” starts in the same column as “(real division)” after 3.7500, which takes 6.
  • A %% B prints A % B. Notice that in the code that line has one more character than the others, but in the output it lines up.
  • (float)a / b does the real division: 15 / 4 = 3.75. And (float)a with %f shows 15.000000: without the cast, %f would get an int and print garbage, as in the theory.
  • a * a * a is the cube: 15 × 15 × 15 = 3375. With big numbers it would overflow an int (with A = 1300, A³ already goes past 2147483647).
  • The comparisons are printed directly with %d: they’re 1 or 0.

Checking by hand: 15 + 4 = 19, 15 − 4 = 11, 15 × 4 = 60, 15 = 4 × 3 + 3 (division 3, remainder 3); 15 in hexadecimal is f and in octal 17 (1 × 8 + 7).

Watch it step by step in Python Tutor

Python Tutor (pythontutor.com) runs C step by step. Choose C (gcc) in the menu and paste snippet 3, extended, to watch the triangle with no area live:

#include <stdio.h>

int main(void) {
    float base = 3.0f, height = 4.0f;
    int half = 1 / 2;                        /* 1 / 2 between integers: 0 */
    float area_wrong = 1 / 2 * base * height; /* 0 * 3.0 * 4.0 = 0.0 */
    float area_right = base * height / 2;    /* 12.0 / 2 = 6.0 */
    float area_right2 = 1.0f / 2 * base * height;
    printf("%d %.2f %.2f %.2f\n", half, area_wrong, area_right, area_right2);
    return 0;
}

Its output:

0 0.00 6.00 6.00

Watch for this:

  1. When the half line runs, its box shows 0: 1 / 2 between integers.
  2. area_wrong also stays at 0: the 0 arrives before base and height.
  3. area_right is 6: base * height is already a float (12.0) when it’s divided by 2.
  4. area_right2 is 6 too: with 1.0f the first division is already real (0.5).

Cheat sheet: types and variables in C

The essentials in 30 seconds: declare every variable with its type and an initial value; int / int gives int; the printf and scanf specifier has to match the type; in scanf, & in front of each variable, %lf for double and " %c" for char; always compile with -Wall and don’t ignore a single warning.

I want…CodeResult
To see how much a type takesprintf("%zu", sizeof(int))4
A constant#define PI 3.14159freplaced before compiling
To divide with decimals(float)a / b7 / 3 → 2.3333
The remaindera % b7 % 3 → 1
To chop decimals / round(int)x / (int)(x + 0.5f)7.75 → 7 / 8
A 1 or a 0 from a conditionint ok = grade >= 5.0f;1
The next letter / lowercasec + 1 / c + 32'S' → 'T' / 's'
To turn '7' into 7c - '0'7
2 decimals / fixed width%.2f / %5d, %-6d, %05d7.75 / 6
Hexadecimal / octal%x, %X / %off, FF / 377
A % in printf%%%
To read…scanfPrint with printf
intscanf("%d", &x)%d
floatscanf("%f", &x)%f, %.2f
doublescanf("%lf", &x)%f, %.2f
charscanf(" %c", &c)%c (or %d for the code)

Templates from the exercises:

ExerciseThe key lineWith the sample data
ShapesPI * radius * radius78.54
BMIweight / (height * height)22.25
Basesnumber / 10 % 105
Scientificprintf("A / B = %-6d (…)\n", a / b)3 (…)
SymptomLikely cause
Segmentation fault after typingA missing & in scanf
0.00 or an absurd number when reading a decimal%f in scanf for a double (use %lf)
The average or the area comes out without decimals or as 0Division between integers (30 / 4, 1 / 2)
scanf doesn’t wait when reading a charThe space is missing: " %c"
A huge negative number or a value that keeps changingUninitialised variable or mismatched specifier
Floating point exceptionInteger division by 0
A weird value like 8 where you wrote 010A leading 0 means octal

Before handing in, ask yourself:

  1. Does it compile with gcc -Wall -std=c11 with no warnings?
  2. Does every scanf have its & and the right specifier for its type (%lf for double)?
  3. Is there any division between two integers where you expect decimals?
  4. Do all variables have a value before they’re used?

With this you close the first C block. The next topic starts where these exercises end: instead of showing a 1 or a 0, the program will decide what to do with them. It’s waiting for you in conditionals in C.

Keep goingAll C articles

Did this article help you? Here is how you can support SergioLearns →

Sigue aprendiendo

Leave a Reply

Your email address will not be published. Required fields are marked *