⚡ TechVani: AI, Technology, Apps, Coding & Digital World
TechVaniAI • Technology • Apps • Coding • Digital World
HomeAI & TechAppsCodingFree AI ToolsStudent TechSecurityAboutContactPrivacy
TECHVANI // LEARN. BUILD. TEST.

Learn the tech. Build the idea.

Clear study notes, tested lab files and practical guides for coding, AI and digital safety.

Explore Latest →
šŸ¤– AI & TechAI news, tools & guides šŸ“± Apps & ToolsUseful apps & websites šŸ’» CodingProgramming & web development šŸŽ“ Student TechStudy & career technology šŸ” Cyber SecuritySafety & awareness

Latest Posts

Circuit Notebook theme

Exam Notes

šŸ“š BTech CSE Exam Notes

Find Semester 1-8 subjects in one place. Choose a semester and open the notes you need. This is a general study guide, not an official syllabus.

Open Exam Notes →🧪 Open Lab Files →

Exam Numericals & Study Series

Practice CPU scheduling and explore OS and DBMS topics in separate, easy-to-follow parts. New topics will appear in the hub as they are published.

Open Numericals Hub →

Start here and stay in touch

New to TechVani? Start with our free AI tools guide for students. It covers which tools to try and what to check before relying on an answer.

For step-by-step videos, visit SiteSudhar on YouTube.

Join TechVani on WhatsApp

Get new AI tools and coding guides in your WhatsApp Updates tab.

Browse Topics

Popular Posts

TechVani

Programming for Problem Solving in C | Semester 1 Core Notes

Semester 1 - Page 3: Programming for Problem Solving in C. General first-year notes with 20 numbered topics, answered exam questions and six complete tested C17 programs. Semester placement and lab tasks vary; match your own outline. These are original study examples, not official syllabus claims or copied past papers.

Core habit: write the contract, trace the algorithm, compile with warnings, then test normal, boundary and invalid cases. Never use a successful run to justify undefined behaviour.

Topic map

  1. Computer basics and problem specification
  2. Algorithms, pseudocode, flowcharts and dry runs
  3. C program structure, build stages and error types
  4. Tokens, identifiers, variables, constants and data types
  5. Operators, conversions, precedence and undefined behaviour
  6. Formatted input, output and validation
  7. Decision statements and switch
  8. Loops, break, continue and loop invariants
  9. Functions, prototypes, parameters and scope
  10. Storage duration, linkage and recursion
  11. One-dimensional arrays and array contracts
  12. Two-dimensional arrays and matrix operations
  13. Strings, line input and library functions
  14. Pointers, pointer arithmetic and indirection
  15. Dynamic memory and resource ownership
  16. Structures, unions, enums and typedef
  17. File I/O, modes, errors and command-line arguments
  18. Preprocessor, macros and standard libraries
  19. Searching, sorting and efficiency
  20. Numerical algorithms, safety and testing
StartRead 3 marksAll valid?0..100, finitesum / 3.0Print averageRejectYesNo
Validate before calculating. A failed read does not supply usable marks.

1. Computer basics and problem specification

A computer receives input, processes instructions and stores or outputs results. CPU, primary memory and secondary storage have different jobs. RAM normally holds active program data; persistent storage keeps files across ordinary shutdowns. A bit is a binary digit; a byte in C has CHAR_BIT bits, commonly eight. Hardware is physical equipment; software supplies instructions. Before coding, specify inputs, valid ranges, output and failure behaviour.

Worked explanation: For an average-of-marks problem, accept three finite values from 0 through 100. Return their average only after all three pass validation. A malformed token is a different test from an out-of-range number.
Exam Q: Why write an input-output contract first?
Answer: It makes success and failure testable and avoids writing code for an unclear problem.

2. Algorithms, pseudocode, flowcharts and dry runs

An algorithm is a finite sequence of precise steps for a stated problem. Pseudocode expresses the logic without compiler syntax. A flowchart uses arrows for control, rectangles for processing and diamonds for decisions. A dry run traces state after each step. Correctness needs more than one successful example: test normal, boundary and invalid inputs. Decomposition splits a large task into smaller functions with clear contracts.

Worked explanation: Average algorithm: read three values, reject invalid input, compute sum/3, print. For 60,70,80, sum=210 and average=70. For 0,0,0, average=0. For input bad, do not compute from uninitialized variables.
Exam Q: What is the difference between an algorithm and a program?
Answer: The algorithm describes the method; the program implements it in a language with concrete types, syntax and input handling.

3. C program structure, build stages and error types

A hosted C program commonly starts at main. Header inclusion makes declarations available; it does not paste the full implementation of every library function into your code. Preprocessing, compilation, assembly and linking are conceptual build stages. Syntax/type errors are diagnosed during translation; unresolved external definitions can fail at linking; logic errors can survive a successful build. Use a named language mode and warnings. The examples here use C17, not nonstandard console headers.

Worked explanation: Compile with gcc -std=c17 -Wall -Wextra -Wpedantic -Werror input.c -o input. A misspelled keyword can fail compilation. A program printing the wrong average can compile cleanly, so run tests too.
Exam Q: Does successful compilation prove a correct program?
Answer: No. It does not prove the algorithm, bounds, resource handling or input assumptions are correct.

4. Tokens, identifiers, variables, constants and data types

C tokens include keywords, identifiers, constants, string literals, operators and punctuation. Identifiers are case-sensitive and cannot be keywords. A declaration names an object and its type; initialize it before reading its value. int is for integers, double for floating-point values, char for character-sized storage, and void can mean no return value. Exact widths vary by implementation: do not assume every int is 32 bits. sizeof measures bytes and returns size_t. const restricts modification through that declared access, not every possible alias.

Worked explanation: int count=3; double average=70.0; char grade='A'; are initialized declarations. Character literal 'A' differs from string literal "A", which contains a trailing null character. Print a size_t with %zu.
Exam Q: Why is an uninitialized automatic local variable unsafe to read?
Answer: Its value is indeterminate. Do not treat it as a predictable zero; initialize or assign it on every path before use.

5. Operators, conversions, precedence and undefined behaviour

Arithmetic, comparison, logical, assignment, conditional and bitwise operators solve different tasks. Integer division truncates toward zero: 7/2 is 3 and -7/2 is -3. A floating operand gives floating arithmetic. Parentheses clarify grouping; precedence does not in general decide operand evaluation order. Logical AND/OR short-circuit and yield truth values; bitwise AND/OR operate on bits. Signed integer overflow and out-of-bounds access are undefined behaviour, not portable wraparound or error messages. Avoid unsequenced modifications such as i++ + i++.

Worked explanation: 7/2.0 gives 3.5. For unsigned values, 5u & 3u is 1u. x != 0 && 10/x > 1 avoids the division when x is zero. Write (a+b)/3.0 rather than a+b/3.0 when the intended numerator is the sum.
Exam Q: Are = and == interchangeable?
Answer: No. = assigns a value, whereas == compares two values. A mistaken assignment in a condition can compile but change the logic.

6. Formatted input, output and validation

printf formats output; scanf attempts conversions into supplied objects. Format specifiers must match the expected argument types. For scanf, %d needs int*, %lf needs double*, and %f needs float*. In printf, %f accepts a promoted double. Check the number of successful conversions before using values. A conversion-count check alone does not validate ranges or reject trailing input. For robust general numeric text parsing, use line input and strtol/strtod with range and end-pointer checks. The short marks example handles malformed tokens, nonfinite values and 0..100 range but is not a strict whole-line parser.

Worked explanation: The tested complete input program below prints Average: 70.00 for 60 70 80, and Invalid marks for bad, 101 70 80, or nan 70 80. Division uses 3.0.
Exam Q: Why does scanf need an address for a scalar value?
Answer: It must write the converted value into the caller object. The address identifies that object; a mismatched pointer type is unsafe.

7. Decision statements and switch

if selects a statement based on a scalar condition; an else belongs to the nearest unmatched if, so braces prevent confusion. An else-if chain handles several exclusive cases in order. switch selects by an integer-type expression and constant case labels; ordinary cases can fall through without break. A default handles unmatched values. The conditional operator chooses an expression value, not a whole menu of statements.

Worked explanation: For marks, first reject values outside 0..100, then check >=80, >=60 and the remaining category. If you check >=60 before >=80, a mark of 85 can enter the earlier branch. A switch menu uses break after each completed operation unless fallthrough is deliberate.
Exam Q: When should nested if statements use braces?
Answer: Use them consistently, especially with else branches, to make the intended grouping visible and resistant to later edits.

8. Loops, break, continue and loop invariants

for is useful when initialization, condition and update form a clear progression. while tests before the body; do-while tests after it, so its body runs at least once. break exits the nearest loop or switch. continue advances to the next iteration; in a for loop its update still executes. An invariant is a statement true at a chosen point on every iteration. Also prove progress toward termination. A loop with incorrect bounds can read past an array or run forever.

Worked explanation: To sum 1..5, initialize sum=0 and add i for i=1 through 5. After processing i, sum equals 1+...+i. The result is 15. Traversing n array elements uses i<n, not i<=n. In a while loop, a continue placed before a required update can prevent progress.
Exam Q: Why is do-while different from while?
Answer: The condition is checked after the do-while body, so even an initially false condition allows one execution.

9. Functions, prototypes, parameters and scope

A function declaration states the interface; a definition supplies the body. C passes arguments by value, including pointer values. Passing a pointer lets a function access a caller object, but does not turn the language into true reference-parameter passing. A prototype enables argument checking. Variables declared in a block have block scope. Keep contracts explicit: accepted ranges, valid pointers, ownership and returned status. C does not allow ordinary nested function definitions.

Worked explanation: swap(&a,&b) passes copies of two addresses. Dereferencing them changes the original ints. A function that only receives int a,int b and swaps those locals does not change the caller variables. For no parameters use f(void) in C17.
Exam Q: Does passing an array give the callee its length automatically?
Answer: No. An array parameter is adjusted to a pointer type; pass the element count separately or establish another explicit contract.

10. Storage duration, linkage and recursion

Scope is where a name is visible; storage duration is how long the object exists; linkage determines whether declarations refer to the same entity. An automatic local usually lives for its block execution. A static local persists between calls. File-scope static gives internal linkage. extern commonly declares an object defined elsewhere. Recursion solves a smaller subproblem using a base case, but consumes call resources. Do not return a pointer to an expired automatic local.

Worked explanation: recursive_sum(5) evaluates 5+4+3+2+1+0=15. Its teaching contract limits n to 100; it is not suitable for arbitrarily large input. A static call counter starts at zero and keeps its updated value across calls, unlike a freshly initialized automatic local.
Exam Q: What are the two basic requirements for terminating recursion?
Answer: A reachable base case and a recursive step that moves toward it. Also consider resource depth and arithmetic overflow.

11. One-dimensional arrays and array contracts

An array holds a fixed number of elements of one type contiguously. For n elements, valid indices are 0 through n-1. Most array expressions convert to a pointer to the first element, but arrays are not pointer variables. sizeof a/sizeof a[0] finds the length only where a is the actual array, not an adjusted function parameter. A maximum function must decide empty-input behaviour and initialize from a valid element, not zero when all values may be negative.

Worked explanation: For [4,9,2,7,5], the maximum is 9. The tested max_of function returns success through its return value and writes through out. For n=0 it returns failure without reading a[0]. For n>0, a must reference n valid ints and out a valid writable int.
Exam Q: What is wrong with reading a[5] in int a[5]?
Answer: Index 5 is outside the valid range 0..4. The behaviour is undefined; a compiler is not required to diagnose every such access.

12. Two-dimensional arrays and matrix operations

A two-dimensional array is an array of row arrays. In int a[2][3], there are two rows of three ints. Row-major storage places the row elements together. Matrix addition requires equal dimensions; multiplication requires the left column count to equal the right row count. Each output cell is a dot product. Initialize every result accumulator before adding products. The column dimension matters when passing a rectangular array to a function.

Worked explanation: For [[1,2],[3,4]], diagonal sum is 1+4=5. Multiplying [[1,2],[3,4]] by [[1,0],[0,1]] gives the original matrix. For a 2x3 matrix times a 3x4 matrix, the result is 2x4.
Exam Q: Why cannot an arbitrary int** be treated as int[2][3]?
Answer: A pointer-to-pointer layout can refer to separately allocated rows. A true rectangular array has contiguous row arrays and a different type.

13. Strings, line input and library functions

A C string is a character sequence terminated by a null character. char word[]="code" creates a writable array including that terminator; a string literal must not be modified. strlen counts characters before the terminator, not the allocated capacity. strcmp compares lexicographically and returns a value less than, equal to or greater than zero, not necessarily -1 or 1. fgets limits input and can retain the newline. Check its return and possible truncation. strcpy and strcat require enough destination space. Never use removed gets or assume strrev is standard C.

Worked explanation: The tested line program reads hello world and prints length=11 after removing its newline. An empty input line becomes a string of length 0. Changing word[0] to 'C' in the array char word[]="code" prints Code.
Exam Q: Why does char name[20] hold at most 19 single-byte characters as a C string?
Answer: One element is reserved for the null terminator. Filling all 20 with non-null characters does not produce a terminated string.

14. Pointers, pointer arithmetic and indirection

A pointer value identifies an object or function, or can be null. & obtains an address and * accesses the pointed-to object when valid. Pointer arithmetic is defined within an array and its one-past position; that one-past pointer must not be dereferenced. Adding one advances by one element, not necessarily one byte. Null, uninitialized, dangling and wrong-type pointers must not be dereferenced. const int* prevents modifying the int through that pointer; int* const prevents reseating the pointer itself.

Worked explanation: For int a[]={2,4,6}, a+1 points to a[1] and *(a+1) is 4. a+3 is a permitted one-past pointer but *(a+3) is invalid. The swap example changes caller values only because its two pointers identify valid writable ints.
Exam Q: What causes a dangling pointer?
Answer: The object it pointed to no longer exists, for example after free or after returning from the block that owned an automatic object.

15. Dynamic memory and resource ownership

malloc allocates storage with uninitialized contents; calloc allocates and sets bytes to zero. Check allocation failure before access and initialize the values you need. Guard size multiplication against overflow. free releases an allocation once; freeing null is allowed. Use-after-free and double-free are invalid. For realloc, keep the original pointer until success: overwriting it directly on failure can lose the allocation. A resized allocation can move and invalidate previous pointers into it. Specify who owns and frees memory.

Worked explanation: The complete memory example allocates four ints, stores 1..4, sums to 10 and frees the block. It checks n>SIZE_MAX/sizeof *a before multiplying. Set a=NULL afterward to reduce accidental reuse through that variable; this does not repair other aliases.
Exam Q: Why should realloc commonly use a temporary pointer?
Answer: If it fails for a nonzero request, the original allocation remains valid. A temporary preserves the original pointer so it can still be used or freed.

16. Structures, unions, enums and typedef

A struct groups separate named members; each member has its own storage. A union lets different members share storage, so do not treat it as several independent stored values. Size includes implementation padding and is not always the sum of member sizes. An enum names integer constants; typedef supplies a type alias, not a new object. Use dot with a struct object and arrow through a pointer. Self-referential structures use pointers to their own type rather than containing an endless instance of themselves.

Worked explanation: struct Student {char name[20]; int mark;}; can hold Ada and 85 together. For struct Student *p=&s, p->mark accesses the same member as s.mark. A linked-list node can contain struct Node *next.
Exam Q: Why can a struct be larger than the sum of its members?
Answer: The implementation can insert padding to meet alignment requirements. Do not serialize raw layout as if it were a universal file format.

17. File I/O, modes, errors and command-line arguments

fopen returns a stream pointer or null on failure. Text mode r reads an existing file; w creates or truncates; a appends. Binary mode adds b where meaningful. Check reads/writes and close errors. EOF is a result indicator, not a character to store in char; fgetc returns int so it can represent all unsigned-char values plus EOF. Read using the operation result, not while(!feof(f)). argc and argv supply command-line arguments; strings still need parsing and validation. Portable text-file seeking has restrictions; do not assume any byte offset is valid.

Worked explanation: The tested file program writes Ada 85 to a temporary stream, flushes it, rewinds and reads the record with %19s %d. It closes the stream and checks results. The width 19 fits a 20-element string array. tmpfile is used for the demonstration so it does not overwrite a named user file.
Exam Q: Why is while(!feof(f)) a poor read loop?
Answer: The end flag is set only after a read reaches the end. Test the read result and distinguish end-of-file from an actual I/O error.

18. Preprocessor, macros and standard libraries

#include, #define and conditional compilation run before ordinary compilation. An object-like macro substitutes tokens. Function-like macros need parentheses around parameters and the whole expression, and can evaluate an argument more than once. Prefer a function when side effects or type checking matter. Standard headers include stdio.h, stdlib.h, string.h, math.h, ctype.h and assert.h; conio.h is not part of standard C. Library availability and linking flags depend on the environment.

Worked explanation: A macro #define SQUARE(x) ((x)*(x)) groups arithmetic correctly but SQUARE(i++) still modifies i more than once in an unsafe expression. A function square(int x) evaluates the caller argument once before its body. For ctype functions, supply EOF or a value representable as unsigned char.
Exam Q: Do parentheses make every macro safe?
Answer: No. They fix many grouping problems but do not prevent repeated evaluation, unsuitable types or other context problems.

19. Searching, sorting and efficiency

Linear search scans elements and works on unsorted data, with O(n) worst-case comparisons. Binary search requires the correct sort order and repeatedly halves the range, using O(log n) comparisons. Selection sort chooses the smallest remaining item on each pass, using O(n squared) comparisons and O(1) extra array space. Big-O describes growth, not the exact elapsed time on every machine. State whether an algorithm changes the input and whether its equal-value order is stable.

Worked explanation: The tested algorithms program sorts [4,9,2,7,5] into [2,4,5,7,9]. Binary search finds 7 at zero-based index 3 and returns -1 for 8. It uses the half-open interval [lo,hi), so an empty range stops immediately.
Exam Q: Can binary search reliably find a key in unsorted input?
Answer: No. Its elimination step relies on the ordering. Sort appropriately first or use a method that does not require sorting.

20. Numerical algorithms, safety and testing

Translate the mathematical rule into a bounded machine algorithm. A primality test rejects n<2 and checks possible divisors up to sqrt(n). Use d<=n/d for positive n rather than d*d<=n when the product could overflow. Factorial grows rapidly, so check before multiplication. Euclid GCD repeatedly replaces (a,b) by (b,a%b). Floating-point arithmetic has rounding error; a result can need tolerance rather than exact equality. Debug with warnings, boundary tests and optional runtime checking, not by trusting a single printed output.

Worked explanation: The tested prime function returns primes 2,3,5,7 in 0..10 and accepts 2147483647 on the test compiler. Checked factorial gives 5!=120 and 0!=1, rejecting 100! before overflow. GCD(48,18)=6. The complete tests compile with C17 warnings treated as errors.
Exam Q: Why not publish a predicted output for undefined behaviour?
Answer: Undefined behaviour has no required portable result. Explain and remove the defect rather than presenting a lucky compiler run as the language rule.

Difference table

PairFirstSecondExam warning
Array / pointerSequence of elementsValue identifying an object/functionArray expressions often convert, but types are not identical
while / do-whilePre-testPost-testdo-while runs at least once
struct / unionSeparate member storageShared member storagePadding and representation are implementation details
Automatic / static localLifetime of block executionLifetime of programScope and lifetime are different concepts
malloc / callocUninitialized allocated storageAllocated bytes zeroedCheck failure; byte-zero is not every type value guarantee
Linear / binary searchUnsorted data allowedOrder requiredWorst-case O(n) versus O(log n) comparisons

Six complete programs and checked output

Each file below was compiled independently with gcc -std=c17 -Wall -Wextra -Wpedantic -Werror file.c -o program. Run one file at a time. Function contracts are part of correctness. The displayed outputs are actual test runs; optional failure paths depend on resources and input.

Validated marks average

#include <stdio.h>
#include <math.h>
int main(void) {
    double a, b, c;
    if (scanf("%lf %lf %lf", &a, &b, &c) != 3 ||
        !isfinite(a) || !isfinite(b) || !isfinite(c) ||
        a < 0 || a > 100 || b < 0 || b > 100 || c < 0 || c > 100) {
        puts("Invalid marks");
        return 1;
    }
    printf("Average: %.2f\n", (a + b + c) / 3.0);
    return 0;
}

Checked run:

Average: 70.00

Input for that run: 60 70 80. Tests 0 0 0 and 100 100 100 printed 0.00 and 100.00. Tests bad, 101 70 80 and nan 70 80 printed Invalid marks and exited with failure.

Maximum, selection sort, binary search and prime

#include <stdio.h>
#include <stddef.h>
int is_prime(int n) {
    if (n < 2) return 0;
    for (int d = 2; d <= n / d; ++d)
        if (n % d == 0) return 0;
    return 1;
}
int max_of(const int a[], size_t n, int *out) {
    if (n == 0) return 0;
    int m = a[0];
    for (size_t i = 1; i < n; ++i)
        if (a[i] > m) m = a[i];
    *out = m;
    return 1;
}
void selection_sort(int a[], size_t n) {
    for (size_t i = 0; i < n; ++i) {
        size_t m = i;
        for (size_t j = i + 1; j < n; ++j)
            if (a[j] < a[m]) m = j;
        int t = a[i]; a[i] = a[m]; a[m] = t;
    }
}
int binary_find(const int a[], size_t n, int key) {
    size_t lo = 0, hi = n;
    while (lo < hi) {
        size_t mid = lo + (hi - lo) / 2;
        if (a[mid] == key) return (int)mid;
        if (a[mid] < key) lo = mid + 1;
        else hi = mid;
    }
    return -1;
}
int main(void) {
    int a[] = {4, 9, 2, 7, 5}, m;
    size_t n = sizeof a / sizeof a[0];
    if (max_of(a, n, &m)) printf("max=%d\n", m);
    selection_sort(a, n);
    for (size_t i = 0; i < n; ++i) printf("%d%c", a[i], i + 1 == n ? '\n' : ' ');
    printf("find7=%d find8=%d\n", binary_find(a,n,7), binary_find(a,n,8));
    printf("empty=%d\n", max_of(a,0,&m));
    for (int i = 0; i <= 10; ++i)
        if (is_prime(i)) printf("%d ", i);
    puts("");
    printf("largeprime=%d\n", is_prime(2147483647));
    return 0;
}

Checked run:

max=9
2 4 5 7 9
find7=3 find8=-1
empty=0
2 3 5 7 
largeprime=1

The binary-search return is an int index for these small teaching arrays; a general API for arrays larger than INT_MAX needs a different result type. The primality loop avoids the old i*i overflow defect. Empty maximum input is explicitly rejected.

Pointer swap, GCD, checked factorial and recursion

#include <stdio.h>
#include <limits.h>
void swap(int *a, int *b) {
    int t = *a; *a = *b; *b = t;
}
unsigned gcd(unsigned a, unsigned b) {
    while (b != 0) {
        unsigned r = a % b; a = b; b = r;
    }
    return a;
}
int factorial(unsigned n, unsigned long long *out) {
    unsigned long long result = 1;
    for (unsigned i = 2; i <= n; ++i) {
        if (result > ULLONG_MAX / i) return 0;
        result *= i;
    }
    *out = result;
    return 1;
}
unsigned recursive_sum(unsigned n) {
    /* Teaching contract: n <= 100, not unbounded recursion. */
    return n == 0 ? 0 : n + recursive_sum(n - 1);
}
int main(void) {
    int a = 3, b = 8; swap(&a, &b);
    printf("swap=%d,%d gcd=%u sum=%u\n", a,b,gcd(48,18),recursive_sum(5));
    unsigned long long f;
    if (factorial(5,&f)) printf("5!=%llu\n",f);
    if (factorial(0,&f)) printf("0!=%llu\n",f);
    printf("overflow_rejected=%d\n", !factorial(100,&f));
    return 0;
}

Checked run:

swap=8,3 gcd=6 sum=15
5!=120
0!=1
overflow_rejected=1

Dynamic array, structure, matrix and string

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
struct Student { char name[20]; int mark; };
int main(void) {
    const size_t n = 4;
    int *a = NULL;
    if (n > SIZE_MAX / sizeof *a) return 1;
    a = malloc(n * sizeof *a);
    if (a == NULL) return 1;
    for (size_t i = 0; i < n; ++i) a[i] = (int)(i + 1);
    int sum = 0;
    for (size_t i = 0; i < n; ++i) sum += a[i];
    printf("sum=%d\n", sum);
    free(a); a = NULL;
    struct Student s = {"Ada", 85};
    struct Student *p = &s;
    printf("%s %d length=%zu\n", p->name,p->mark,strlen(p->name));
    int matrix[2][2] = {{1,2},{3,4}};
    printf("diagonal=%d\n",matrix[0][0]+matrix[1][1]);
    char word[] = "code";
    word[0] = 'C';
    printf("%s\n", word);
    return 0;
}

Checked run:

sum=10
Ada 85 length=3
diagonal=5
Code

Temporary text-file round trip

#include <stdio.h>
int main(void) {
    FILE *f = tmpfile();
    if (f == NULL) { perror("tmpfile"); return 1; }
    if (fprintf(f,"Ada 85\n") < 0 || fflush(f) == EOF) {
        fclose(f); return 1;
    }
    rewind(f);
    char name[20]; int mark;
    if (fscanf(f,"%19s %d",name,&mark) != 2) {
        fclose(f); return 1;
    }
    printf("%s %d\n",name,mark);
    if (fclose(f) == EOF) return 1;
    return 0;
}

Checked run:

Ada 85

Bounded line input

#include <stdio.h>
#include <string.h>
int main(void) {
    char line[32];
    if (fgets(line,sizeof line,stdin) == NULL) return 1;
    size_t len = strlen(line);
    if (len > 0 && line[len-1] == '\n') line[--len] = '\0';
    else if (!feof(stdin)) {
        puts("No newline: check truncation or final input line");
    }
    printf("text=%s length=%zu\n",line,len);
    return 0;
}

Checked run:

text=hello world length=11

Input for that run: hello world followed by Enter. An empty line printed length=0. A final line short without a newline printed length=5. For a long line, the notice asks you to check truncation; a production parser should consume/reject the remaining data according to its contract.

Practice and short answers

  1. Integer 7/2? 3.
  2. Last index of 4 elements? 3.
  3. Prime check for 1? False.
  4. Does sizeof an array parameter reveal array length? No, the parameter is adjusted to a pointer.
  5. Two inputs for GCD: 48 and 18? 6.
  6. What must happen after successful allocation? Initialize before reading, use only valid bounds, then release owned memory once.
Five-minute revision: input contract; type-correct formats; assignment versus comparison; loop bound and progress; parameter passing by value; array length; string terminator; valid pointer lifetime; allocation failure; file-result checks; sort-order requirements; overflow-safe numeric algorithms.

Coverage, references and further practice

This guide expands the earlier syntax-and-array summary to computer basics, algorithms, operators, control flow, functions, scope/lifetime, arrays/matrices, strings, pointers, memory, records, files, macros and introductory searching/sorting. These explanations are a starting point for full lab work, not a promise to match every possible course subtopic.

Reference reading: C language, arrays, pointers, formatted input, line input, allocation and compiler warnings.

Continue with the C lab file, Lab Files index and Online Compiler. Preserve indentation when copying code.

Comments