Eleven problems, from beginner to advanced, that use structures. In most of them the structure definitions and part of the main function are already written, and you write the requested part. Press "Check" to run your code with real gcc on several inputs and see whether the output is correct.
Note: Run and Check send your code to Wandbox, a free external compiler service, and run it with gcc.
struct point representing coordinates (members x and y) is defined. Read integers x and y (each between −10000 and 10000) into the members of the structure variable p, print them in the form "(x, y)", and on the next line print the squared distance from the origin (x² + y²)."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
.), as in p.x. Pass &p.x to scanf, just as with an ordinary variable (. binds more tightly than &, so it means &(p.x)).#include <stdio.h> struct point { int x; int y; }; int main(void) { struct point p; scanf("%d %d", &p.x, &p.y); printf("(%d, %d)\n", p.x, p.y); printf("Squared distance from origin: %d\n", p.x * p.x + p.y * p.y); return 0; }
struct point, so you cannot leave out struct when declaring a variable (use typedef if you want to omit it). Watch out for the semicolon in }; at the end of a structure definition, which is easy to forget.struct student with a name and a score is defined. Read a name (letters without spaces, 1–19 characters) and a score (0–100) into the structure variable s, and print the name, the score and the result ("Pass" if the score is 60 or more, "Fail" otherwise)."Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
& in front of it, as in scanf("%19s", s.name) (the array name itself is the address of its first element). The score is &s.score.#include <stdio.h> struct student { char name[20]; int score; }; int main(void) { struct student s; scanf("%19s %d", s.name, &s.score); printf("Name: %s\n", s.name); printf("Score: %d\n", s.score); if (s.score >= 60) { printf("Result: Pass\n"); } else { printf("Result: Fail\n"); } return 0; }
%19s means "read at most 19 characters", leaving room for '\0' so the array (20 elements) does not overflow. Also note that you cannot assign to a string member, as in s.name = "sato"; (outside of initialization, use strcpy).int to_seconds(struct time t) that receives a structure struct time with hours, minutes and seconds by value and returns the total number of seconds since 00:00:00. The main function is complete (it reads hours (0–23), minutes (0–59) and seconds (0–59) and prints them in the form "hh:mm:ss = N seconds")."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
t.h, t.m and t.s.#include <stdio.h> struct time { int h; int m; int s; }; int to_seconds(struct time t) { return t.h * 3600 + t.m * 60 + t.s; } int main(void) { struct time t; scanf("%d %d %d", &t.h, &t.m, &t.s); printf("%02d:%02d:%02d = %d seconds\n", t.h, t.m, t.s, to_seconds(t)); return 0; }
t.h = 0; inside the function, t in main does not change. For a function that only reads, pass by value is enough. %02d means "width 2, padded with 0 if shorter".Student (name and score), named with typedef (the first half of main is complete). Write the rest: print the average score to one decimal place, and on the next line print the name and score of the student with the highest score. If several students share the highest score, print the one who was entered first."Run" executes your code with the input above. "Check" tests it against 5 prepared inputs.
best rather than by score, you can get the name too. Start with best = 0 and update only when s[i].score > s[best].score (with >=, a later student would replace them).#include <stdio.h> typedef struct { char name[20]; int score; } Student; int main(void) { int n; Student s[50]; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%19s %d", s[i].name, &s[i].score); } int sum = 0, best = 0; for (int i = 0; i < n; i++) { sum += s[i].score; if (s[i].score > s[best].score) { best = i; } } printf("Average: %.1f\n", (double)sum / n); printf("Top: %s (%d pts)\n", s[best].name, s[best].score); return 0; }
typedef struct { ... } Student;, you can use just Student as the type name without writing struct. A member of an element of an array of structures is written "array index, then dot", as in s[i].score. For the average, unless you make one side a double as in (double)sum / n, integer division cuts off the decimals.Account (holder name and balance) and modify it.void deposit(Account *a, int amount): increases the balance by amountint withdraw(Account *a, int amount): if the balance is sufficient, decreases it by amount and returns 1; otherwise does nothing and returns 0+ amount" (deposit) or "- amount" (withdrawal), and prints the result after each operation). Amounts and the initial balance are between 0 and 100000, and Q is between 1 and 20."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
a points to is written a->balance (same meaning as (*a).balance). For withdrawal, it is easier to handle the insufficient case first with if (a->balance < amount) return 0;.#include <stdio.h> typedef struct { char name[20]; int balance; } Account; void deposit(Account *a, int amount) { a->balance += amount; } int withdraw(Account *a, int amount) { if (a->balance < amount) { return 0; } a->balance -= amount; return 1; } int main(void) { Account acc; int q; scanf("%19s %d", acc.name, &acc.balance); scanf("%d", &q); for (int i = 0; i < q; i++) { char op; int amount; scanf(" %c %d", &op, &amount); if (op == '+') { deposit(&acc, amount); } else if (!withdraw(&acc, amount)) { printf("Insufficient funds\n"); } printf("%s: balance %d\n", acc.name, acc.balance); } return 0; }
void deposit(Account a, int amount)), only the copy is modified and the balance in main does not increase. To modify it, pass a pointer, and use . for a structure variable and -> for a pointer to a structure. Writing a.balance is a compile error, and *a.balance is interpreted as *(a.balance), so use (*a).balance with parentheses, or a->balance.Point midpoint(Point a, Point b) that takes two coordinate structures Point (double members x and y) and returns their midpoint as a structure. The main function is complete (it reads the coordinates of two points x1 y1 x2 y2 (integers between −1000 and 1000) and prints the midpoint to one decimal place)."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
m.x = (a.x + b.x) / 2;, store it in m, and return it with return m;.#include <stdio.h> typedef struct { double x; double y; } Point; Point midpoint(Point a, Point b) { Point m = {0.0, 0.0}; m.x = (a.x + b.x) / 2; m.y = (a.y + b.y) / 2; return m; } int main(void) { Point a, b; scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y); Point m = midpoint(a, b); printf("Midpoint: (%.1f, %.1f)\n", m.x, m.y); return 0; }
return, but a structure lets you return several members together. The returned structure is copied to the caller, so returning the local variable m is fine (this is different from returning the address of a local variable). If the members were int, (0 + 3) / 2 would become 1, so they are double here. To read a double with scanf, use %lf.Student with a name and an array of scores for three subjects. Write a function void print_report(const Student *s) that prints one student's total and average. The output is one line per student: "name total average" (average to one decimal place). The main function is complete (it reads N (1 ≤ N ≤ 20) and N lines of "name score1 score2 score3" (scores 0–100), and calls print_report for each student)."Run" executes your code with the input above. "Check" tests it against 3 prepared inputs.
s->score[j]. Compute the total with for (int j = 0; j < 3; j++), and the average with total / 3.0.#include <stdio.h> typedef struct { char name[20]; int score[3]; } Student; void print_report(const Student *s) { int total = 0; for (int j = 0; j < 3; j++) { total += s->score[j]; } printf("%s %d %.1f\n", s->name, total, total / 3.0); } int main(void) { int n; Student st[20]; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%19s", st[i].name); for (int j = 0; j < 3; j++) { scanf("%d", &st[i].score[j]); } } for (int i = 0; i < n; i++) { print_report(&st[i]); } return 0; }
const Student * means an accidental modification is caught as a compile error. Dividing by an integer, as in total / 3, cuts off the decimals, and you would also be passing an int to %.1f, so the output would be wrong.Point (int x, y) and a rectangle Rect with a bottom-left corner corner (of type Point), width w and height h are defined (a structure inside a structure). Write a function int contains(const Rect *r, Point p) that returns 1 if point p is inside the rectangle (including its edges) and 0 otherwise. Inside means x is at least corner.x and at most corner.x + w, and y is at least corner.y and at most corner.y + h. The main function is complete (it reads the rectangle's x y w h, the number of points Q and Q points, and prints "inside" or "outside" for each point). Coordinates are between −1000 and 1000, and w and h are between 1 and 1000."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
r, it is r->corner.x (-> because r is a pointer, . because corner is a structure itself). Join the four conditions with &&.#include <stdio.h> typedef struct { int x; int y; } Point; typedef struct { Point corner; int w; int h; } Rect; int contains(const Rect *r, Point p) { return r->corner.x <= p.x && p.x <= r->corner.x + r->w && r->corner.y <= p.y && p.y <= r->corner.y + r->h; } int main(void) { Rect r; int q; scanf("%d %d %d %d", &r.corner.x, &r.corner.y, &r.w, &r.h); scanf("%d", &q); for (int i = 0; i < q; i++) { Point p; scanf("%d %d", &p.x, &p.y); printf("(%d, %d): %s\n", p.x, p.y, contains(&r, p) ? "inside" : "outside"); } return 0; }
-> and . is decided by "-> if the left side is a pointer, . if it is a structure". r->corner is a structure of type Point, so what follows is .x. Writing r->corner->x is an error. The result of the comparisons (0 or 1) can be returned directly with return. Edges count as inside, so use <=.void sort_by_score(Student *s, int n) that sorts the names and scores of N students (1 ≤ N ≤ 50) from highest score to lowest. Students with the same score must stay in input order. The main function is complete (it reads the data, and after sorting prints "rank name score" one per line; the rank simply counts from 1)."Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
s[j].score < s[j + 1].score. Structures can be assigned as a whole, as in Student tmp = s[j]; s[j] = s[j + 1]; s[j + 1] = tmp;.#include <stdio.h> typedef struct { char name[20]; int score; } Student; void sort_by_score(Student *s, int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (s[j].score < s[j + 1].score) { Student tmp = s[j]; s[j] = s[j + 1]; s[j + 1] = tmp; } } } } int main(void) { int n; Student s[50]; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%19s %d", s[i].name, &s[i].score); } sort_by_score(s, n); for (int i = 0; i < n; i++) { printf("%d %s %d\n", i + 1, s[i].name, s[i].score); } return 0; }
= copies all the members (including the character array name inside). If you swap only the scores, names and scores no longer match up, so swap whole structures. If the comparison is <=, students with equal scores are also swapped, and their order is no longer the input order (test 4). A bubble sort that swaps neighbours "only when strictly smaller" is a stable sort, which keeps equal values in their original order.Fraction with a numerator num and a denominator den. Write the following two functions (the greatest common divisor function gcd is provided).Fraction reduce(Fraction f): returns the reduced fraction. Make the denominator positive, and if the numerator is 0, make it 0/1Fraction add(Fraction a, Fraction b): returns a + b, reduceda/b + c/d = result"; the input fractions are printed as they are, without reducing). Numerators are between −1000 and 1000, and denominators between 1 and 1000. Even if the denominator of the result is 1, print it in the form "2/1"."Run" executes your code with the input above. "Check" tests it against 6 prepared inputs.
a/b + c/d = (a×d + c×b) / (b×d). In add, put this in c and return reduce(c);. In reduce, compute g = gcd(f.num, f.den) and divide the numerator and denominator by g (if the numerator is 0, the gcd is the denominator itself and the result is 0/1).#include <stdio.h> typedef struct { int num; int den; } Fraction; int gcd(int a, int b) { if (a < 0) a = -a; if (b < 0) b = -b; while (b != 0) { int r = a % b; a = b; b = r; } return a; } Fraction reduce(Fraction f) { if (f.den < 0) { f.num = -f.num; f.den = -f.den; } int g = gcd(f.num, f.den); f.num /= g; f.den /= g; return f; } Fraction add(Fraction a, Fraction b) { Fraction c = {0, 1}; c.num = a.num * b.den + b.num * a.den; c.den = a.den * b.den; return reduce(c); } int main(void) { Fraction a, b; scanf("%d %d %d %d", &a.num, &a.den, &b.num, &b.den); Fraction c = add(a, b); printf("%d/%d + %d/%d = %d/%d\n", a.num, a.den, b.num, b.den, c.num, c.den); return 0; }
reduce receives a structure by value and returns a corrected version. The f it receives is a copy, so modifying it does not affect the caller; only the value returned with return f; is used. That is why calling just reduce(c); without using the return value does not reduce anything (write c = reduce(c); or return reduce(c);). With this problem's input the denominators are positive, so the sign adjustment is just a precaution, but when handling negative fractions, deciding to "always keep the denominator positive" keeps the output consistent.Item structures (name, unit price, stock), write two functions that process orders.Item *find_item(Item *items, int n, const char *name): returns a pointer to the item whose name matches name, or NULL if there is noneint order(Item *items, int n, const char *name, int qty): processes one order and returns the sales amount. If the item does not exist, print "name: no such item" and return 0. If the stock is less than qty, print "name: insufficient stock (k left)" and return 0. If there is enough stock, reduce it, print "name: qty pcs x price yen = amount yen", and return the amount"Run" executes your code with the input above. "Check" tests it against 4 prepared inputs.
strcmp(items[i].name, name) == 0, not ==. In find_item, return &items[i] (same as items + i) when it matches. In order, receive it with Item *it = find_item(items, n, name); and use it->stock and it->price.#include <stdio.h> #include <string.h> typedef struct { char name[20]; int price; int stock; } Item; Item *find_item(Item *items, int n, const char *name) { for (int i = 0; i < n; i++) { if (strcmp(items[i].name, name) == 0) { return &items[i]; } } return NULL; } int order(Item *items, int n, const char *name, int qty) { Item *it = find_item(items, n, name); if (it == NULL) { printf("%s: no such item\n", name); return 0; } if (it->stock < qty) { printf("%s: insufficient stock (%d left)\n", name, it->stock); return 0; } it->stock -= qty; int amount = it->price * qty; printf("%s: %d pcs x %d yen = %d yen\n", name, qty, it->price, amount); return amount; } int main(void) { int n, q; Item items[20]; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%19s %d %d", items[i].name, &items[i].price, &items[i].stock); } int total = 0; scanf("%d", &q); for (int i = 0; i < q; i++) { char name[20]; int qty; scanf("%19s %d", name, &qty); total += order(items, n, name, qty); } printf("Total sales: %d yen\n", total); for (int i = 0; i < n; i++) { printf("%s: %d left\n", items[i].name, items[i].stock); } return 0; }
find_item returns is a pointer to an element of the array in main, so it->stock -= qty; reduces the real stock. If you copy the structure with Item it = items[i]; and reduce its stock, only the copy changes and the stock in the array stays the same. Reading it->stock when NULL was returned can crash the program, so always check first. items[i].name == name compares addresses, so it does not match even when the strings are the same.