Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

This repository is an invaluable resource for students pursuing a BCT at TU, providing solutions to every lab question. With meticulous attention to detail, each solution includes code, lab reports in both PDF and DOCX formats, and step-by-step guides.

jrTilak/C-Lab-Report

Folders and files.

NameName
40 Commits

Repository files navigation

Comprehensive c programming lab report repository - by jrtilak, description.

Welcome to the Comprehensive C Programming Lab Report Repository, curated by jrTilak. This repository is designed to provide a comprehensive collection of solutions for the C Programming lab assignments, covering various topics and concepts. Whether you are a student studying at Tribhuvan University's Institute of Engineering or an aspiring programmer, this repository is a valuable resource for enhancing your understanding and practical skills in C programming.

Each lab sheet is meticulously prepared and includes a range of exercises and problems for you to solve. The solutions provided in this repository encompass the complete set of requirements, including code samples, lab reports in PDF and DOCX formats with flowchart and algorithm, guides, and detailed explanations. With these resources, you can gain a deeper understanding of each topic and hone your programming skills.

All questions covered in this repo.

The repository follows a structured approach, covering a wide range of topics, including:

  • C Programming Fundamentals
  • Data Types, Constants, Operators, and Expressions
  • Selective Structures (Branching)
  • Unformatted and Formatted Input/Output
  • File Handling

Whether you are starting from scratch or looking to strengthen your knowledge in specific areas, this repository is an invaluable asset. Each lab sheet includes a cover page, title, objectives, algorithm, flowchart, code snippets, program outputs, and a comprehensive discussion and conclusion section. The provided lab sheets adhere to the standards set by the Department of Electronics and Computer Engineering.

If you have any questions, suggestions, or feedback, feel free to reach out to jrTilak, the creator of this repository, at [email protected] . jrTilak is dedicated to ensuring the quality and usefulness of the solutions, and your input is highly valued.

By utilizing this repository, you can enhance your understanding of C programming concepts, improve your problem-solving abilities, and prepare for your final examinations. Explore the lab sheets, delve into the code samples, and unravel the intricacies of C programming with this comprehensive repository.

Note: This repository is not affiliated with Tribhuvan University or the Institute of Engineering. It is an independent initiative by jrTilak to support C programming learners.

List of all questions covered in this repo.

LAB SHEET NO.1 [To be familiar with C- Programming]

  • WAP to display hello world.
  • WAP to display your name, roll number and address.
  • WAP to add two integer variables and print sum.
  • WAP to multiply two integer variables and print product.
  • WAP to calculate and display the simple interest.
  • WAP to calculate the area of the circle.

LAB SHEET NO.2 [To be familiar Data types, Constants, Operators and Expressions]

  • WAP to declare integer, float and character variable. Initialize them with certain value and print those values. Also display the size of variables.
  • WAP to swap the values of the variable with and without using third variable.
  • WAP to calculate the area and volume of a cylinder using pre-processor directive for value of PI.
  • WAP to input two numbers from user and display the minimum using conditional operator.
  • WAP to display whether a number is even or odd using conditional operator
  • What are the output of the following programs: #include <stdio.h> int main () { int a = 5 , b = 9 ; printf ( "a = %d, b = %d\n" , a , b ); printf ( "a&b = %d\n" , a & b ); printf ( "a|b = %d\n" , a | b ); printf ( "a^b = %d\n" , a ^ b ); printf ( "~a = %d\n" , ~ a ); printf ( "(b<<2)+(a<<1) = %d\n" ,( b << 2 ) + ( a << 1 )); printf ( "(b>>1)+(a>>1) = %d\n" ,( b >> 1 ) + ( a >> 1 )); return 0 ; }

LAB SHEET NO.3 [To be familiar with selective structure (branching)]

  • WAP to check whether a number is negative, positive or zero.
  • WAP to find maximum between three numbers entered by the user.
  • WAP to input a character from the user and check whether the character is vowel or consonant.
  • WAP to input a character from the user and check whether the character is Alphabet or not. If the character is Alphabet then show whether it is uppercase or lowercase.
  • WAP to check whether the year entered by the user is leap year or not.
  • WAP to check whether the number entered by the user is divisible by 5 and 11 or not.
  • WAP to find the all the roots of a quadratic equation.
  • WAP to input two numbers and operator among [ + , - ,* , / ]. If user enters + then the program should perform the addition of the number and display the sum. If user enters – then the program should perform subtraction of number and display the difference and so on for * and /.
  • WAP in C to input marks of five subjects C-programming, Physics, Maths, Applied Mechanics and Basic electrical. Display whether the student passed or failed. Take F.M=100 and P.M.=40 For passed students calculate percentage and grade according to following:Percentage >= 90% : A Percentage >=80% : B Percentage >= 70% : C Percentage >= 60% : D Percentage >= 40% : E
  • WAP to input a number from user. If user enters a number less than or equal to zero then program should just display the number. If user enters 1 the program should display output as neither prime nor composite, if user enters 2 the program should display output as smallest and only even prime number. If user enters any number greater than 2 the program should check whether the number is prime or not, also if the number is not prime the program should display whether it is even or odd.

LAB SHEET NO.4 [To be familiar with Unformatted and Formatted I/0]

  • WAP to get your name, address and display using unformatted I/O.
  • WAP to get a character form the user using unformatted I/O and display the ASCII value of the entered character.
  • WAP to display the output as (take a=15, b=20.43, c=35): A = 15|15 | 15|15 | 15|15 | 15|15 | 15|15 | B = 20.43|20.43 | 20.43|20.43 | 20.43|20.43 | 20.43|20.43 | 20.43|20.43 | C = 35|35 | 35|35 | 35|35 | 35|35 | 35|35 |
  • WAP to display the output as below using formatted I/O [take char a[]=”I Love Nepal”]. I I L I Lo I Lov I Love I Love N I Love Ne I Love Nep I Love Nepa I Love Nepal

LAB SHEET NO.5 [To be familiar with LOOPS]

  • WAP to read 10 numbers from user and find their sum and average.
  • WAP to display the multiplication table of integer given by the user.
  • WAP to input two integer values from the user and print the even number between the range of integers. Also count the even number and display the count as well [Hint: if user enters 10 and 100. The program should print and count even numbers between 10 and 100].
  • WAP to display sum of series: 1 + 1/2 + 1/3 + 1/4 + 1/5 ... 1/n
  • WAP to display sum of series: 1 + 1/2! + 1/3! + 1/4! + 1/5! ... 1/n!
  • WAP to display sum of series: x + x2/2! + x3/3! + x4/4! + x5/5! ... xn/n!
  • WAP to find the value cos(x) without using cos(x) library function.
  • WAP to display weather a number is Armstrong or not.
  • WAP to display the first n terms of Fibonacci series.
  • WAP to display the number in reverse order.
  • WAP to check whether a number is a palindrome or not.
  • WAP to find HCF and LCM of two numbers.
  • WAP to print the following patterns
  • C Programming Home
  • ▼C Programming Exercises
  • Basic Declarations and Expressions
  • Basic Part-II
  • Basic Algorithm
  • Variable Type
  • Input - Output
  • Conditional Statements
  • Do-While Loop
  • Linked List
  • Callback function
  • Variadic function
  • Inline Function
  • File Handling
  • Searching and Sorting

C Programming Exercises, Practice, Solution : Function

C function [12 exercises with solution].

[ An editor is available at the bottom of the page to write and execute the scripts.   Go to the editor ]

1. Write a program in C to show the simple structure of a function. Expected Output :

Click me to see the solution

2. Write a program in C to find the square of any number using the function. Test Data : Input any number for square : 20 Expected Output :

3. Write a program in C to swap two numbers using a function. Test Data : Input 1st number : 2 Input 2nd number : 4 Expected Output :

4. Write a program in C to check if a given number is even or odd using the function. Test Data : Input any number : 5 Expected Output :

5. Write a program in C to find the sum of the series 1!/1+2!/2+3!/3+4!/4+5!/5 using the function. Expected Output :

6. Write a program in C to convert a decimal number to a binary number using the function. Test Data : Input any decimal number : 65 Expected Output :

7. Write a program in C to check whether a number is a prime number or not using the function. Test Data : Input a positive number : 5 Expected Output :

8. Write a program in C to get the largest element of an array using the function. Test Data : Input the number of elements to be stored in the array :5 Input 5 elements in the array : element - 0 : 1 element - 1 : 2 element - 2 : 3 element - 3 : 4 element - 4 : 5 Expected Output :

9. Write a program in C to check Armstrong and Perfect numbers using the function. Test Data : Input any number: 371 Expected Output :

10. Write a program in C to print all perfect numbers in a given range using the function. Test Data : Input lowest search limit of perfect numbers : 1 Input lowest search limit of perfect numbers : 100 Expected Output :

11. Write a program in C to check whether two given strings are an anagram. Test Data : Input the first String : spare Input the second String : pears Expected Output :

12. Write a C program to find the maximum and minimum of some values using a function that returns an array. Test Data : Input 5 values 25 11 35 65 20 Expected Output :

C Programming Code Editor:

More to Come !

Do not submit any solution of the above exercises at here, if you want to contribute go to the appropriate exercise page.

Follow us on Facebook and Twitter for latest update.

  • Weekly Trends and Language Statistics

Learn C practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn c interactively, learn c programming.

C is one of the foundational programming languages used in the development of compilers, operating systems, and embedded systems where speed and efficiency matter.

It is considered the best language to start because it provides a strong understanding of fundamental coding concepts like data types, variables, loops, and functions.

With a competitive base salary, there is a significant demand for C developers in high-stake fields where high performance is essential.

In this guide, we will cover:

Beginner's Guide to C

Is c for you, best way to learn c, how to run c.

If you are simply looking to learn C step-by-step, you can follow our free tutorials in the next section.

These tutorials will provide you with a solid foundation in C and prepare you for the next step in your career.

Getting Started with C

Your First C Program

C Variables, Constants and Literals

C Data Types

C Input Output (I/O)

C Programming Operators

C if...else Statement

C while and do...while Loop

C break and continue

C switch Statement

C goto Statement

C Functions

C User-defined functions

Types of User-defined Functions in C Programming

C Recursion

C Storage Class

C Multidimensional Arrays

Pass arrays to a function in C

Relationship Between Arrays and Pointers

C Pass Addresses and Pointers

C Dynamic Memory Allocation

C Array and Pointer Examples

C Programming Strings

String Manipulations In C Programming Using Library Functions

String Examples in C Programming

C structs and Pointers

C Structure and Function

C File Handling

C Files Examples

C Keywords and Identifiers

C Precedence And Associativity Of Operators

C Bitwise Operators

C Preprocessor and Macros

C Standard Library Functions

Whether C is the right choice depends on what you want to accomplish and your career goals.

C from a Learning Perspective

If you are new to coding, learning C can help you build a strong programming foundation. However, when we compare the code of C with other modern languages like Python, C might seem a bit complex.

For example, the following programs perform the addition of two numbers in both C and Python.

As you can see, C code includes a lot of syntaxes to perform the same task.

That being said, programming languages like C++, Python, and Java are based on C, so it's relatively easier to switch to these languages once you have a good grasp of C.

You typically learn multiple languages throughout your career, so it's beneficial to have a thorough understanding of how everything works right from the start.

C as Career Choice

C is mainly used in high-performance modern applications like:

  • Embedded Systems Design
  • Operating Systems Development
  • Firmware Development
  • Kernel Design

Learning C offers significant benefits for your career opportunities if you are interested in building complex systems with high performance.

However, there are certain fields where choosing C might not be your best option. For example, if you are interested in web development, data science, machine learning, or mobile development, then C might not be the right answer.

In these cases, alternatives such as JavaScript for web development, Python for data science and machine learning, and Kotlin, Swift, or Java for mobile app development will be more suitable.

Ultimately, your career choice is important in deciding whether C is right for you.

There is no right or wrong way to learn C. It all depends on your learning style and pace.

In this section, we have included the best C learning resources tailored to your learning preferences, be it text-based, video-based, or interactive courses.

Text-based Tutorial

Best: if you are committed to learning C but do not want to spend on it

If you want to learn C for free with a well-organized, step-by-step tutorial, you can use our free C tutorials .

Our tutorials will guide you through C programming one step at a time, using practical examples to strengthen your foundation.

Interactive Course

Best: if you want hands-on learning, get your progress tracked, and maintain a learning streak

Learning to code is tough. It requires dedication and consistency, and you need to write tons of code yourself.

While videos and tutorials provide you with a step-by-step guide, they lack hands-on experience and structure.

Recognizing all these challenges, Programiz offers a premium Learn C Course that allows you to gain hands-on learning experience by solving challenges, building real-world projects, and tracking your progress.

Remember, there is no easy shortcut to learning coding!

Online Video

Best: if you are an audio-visual learner and learn by watching others code and following along

If you're more of a visual learner, we have created a C programming playlist for beginners that will guide you on your journey to C programming.

Additionally, you can also follow the C course from Freecodecamp .

Best: if you are a casual and hobby learner who wants to just get to know C

While it's possible to learn C from mobile apps, it's not the ideal way because writing code can be challenging. Additionally, it's difficult to build real-world projects with multiple files on mobile devices.

Nevertheless, you can use these apps to try things out.

Important: You cannot learn to code without developing the habit of writing code yourself. Therefore, whatever method you choose, always write code.

While writing code, you will encounter errors. Don't worry about them, try to understand them and find solutions. Remember, programming is all about solving problems, and errors are part of the process.

1. Run C in your browser.

We have created an online editor to run C directly on your browser. You don't have to go through a tedious installation process. It's completely free, and you can start coding directly.

how-to-install-c

2. Install C on Your computer.

Once you start writing complex programs and creating projects, you should definitely install C on your computer. It's needed especially when you are creating projects with multiple files and folders.

To install C on your device, you can use this guide.

how-to-install-c-2

Learn how you can install and use C on your own computer.

Search this site

Powered by Google

Lab 1: Introduction to C

Explore the basics of the C programming language

In this week’s lab, you will:

  • Learn about the C programming toolchain we use in the rest of the course
  • Learn to write simple C programs
  • Practice using getchar , putchar and printf for terminal I/O, as well as command line program arguments
  • Learn about C pointers, and how to implement pass by reference using them
  • Learn to manipulate and handle strings/character arrays

Preparation #

Log in with your uni ID/password and open the lab template on GitLab here.

Fork the repository by clicking on the fork button. This will create your own copy of the lab repository.

Check the URL bar and make sure it contains your uid (eg. gitlab.cecs.anu.edu.au/*your-uid-here*/comp2310-2024-lab-pack-1 ). This means you are looking at your copy of the lab, and not the template. Once you’ve done this, click Clone and copy the address next to “Clone with HTTPS”.

Type in your uid and password when requested.

  • You should now have a local copy of the repo on your computer.

Congratulations! If you’ve got to this point unscathed, you’ve successfully forked and cloned.

If you completed COMP2300, you should be familiar with terminal commands as well as using Git from the terminal. You will be using the terminal even more in this course! See here for a refresher on basic terminal and Git commands, and here for some videos about using Git.

Before we begin, the first step is to set up the software we use in this course.

  • If you are using a lab machine, then congratulations - most of the work has been done already!
  • If you are working on your own computer, there are a few different things to install. You can continue reading the lab while the software installs itself. The instructions are on a separate page here.

The C programming language is designed to target a variety of computing hardware and architectures. In almost all desktop computers and laptops, the architecture is x86 1 . We will be teaching the x86 ISA in the first few lectures in this course. As you will be compiling C code to run on either lab machines or your device, the resulting machine code will be for an x86 processor.

Most of the exercises in this lab do not involve writing any substantial code but rather figuring out how things work . We advise that you note down insights and observations as you do the exercises below, as the resulting knowledge will be helpful in later assessments.

GitLab CI #

The lab repositories for COMP2310 will include a CI pipeline. While the lab content for COMP2310 is not directly assessed, we have provided these tests to help you test your lab solutions and get used to the system by which your checkpoints and assignments will be marked.

The pipeline is run every time you push your work to GitLab.

View Pipeline Results

You can view the results of all jobs in a specific pipeline by clicking on the CI icon in your fork of the lab pack.

Status of all CI Jobs for a specific pipeline

If you click on the failing job, you will be able to view the output that will explain why your test is failing. In the example below, the job is failing because the expected output does not match the actual output.

Job Log for a failing test

The CI will not test every exercise in these labs, as many are open ended and/or left to you to also write test cases for.

It is important to remember that the test cases we provide are not exhaustive . You should always run and test your code locally.

Exercise 1: The Toolchain #

Since you are writing high-level C programs that run on a real CPU, we require a standard system for compiling code: a toolchain . The name is derived from the multiple tools used to get from your program to machine code. For our simple projects, the toolchain consists of three main components:

  • The compiler is responsible for converting each C file into a machine code file known as an object .
  • The linker is responsible for collecting together all of the compiled objects and linking them together into a single executable program.
  • The build system is responsible for ‘gluing’ together the individual components to provide a simple interface for compiling your program.

Let us see the toolchain in action. To use the toolchain, first open the C file src/hello_world.c .

Have a quick read of the file contents. What do you think this program will do?

Open up a new terminal in VS Code (Menu Bar -> Terminal -> New Terminal) and run the command,

If you see either

Then reopen VS Code with the lab1 folder specifically.

If you see another error, go back and complete the software setup steps or look over the troubleshooting tips. If you are on Windows, make sure to enter WSL (either through a WSL window in VSCode, or typing wsl in the terminal to open a WSL terminal) before compiling.

The above make command will invoke the compiler, building the program. If it worked then you should see a new file hello_world in the root lab1 directory.

After that run:

This will remove the output of the previous compilation.

Open the file Makefile in your lab1 directory and have a look through. We do not expect you to be able to write a makefile! However, you should be able to identify a few components. A few lines of interest include:

  • CC specifies the C compiler to use. We’re using the GNU Compiler Collection (GCC), which will automatically use the linker ld as needed.
  • -Wall ( w arnings all ) enables many of the compiler’s warning messages (though not all of them, despite the name).
  • -Wconversion enables a type conversion warning (see the Types section).
  • -g tells the compiler to generate debug symbols . This is extra information bundled into the executable file that is used by a debugger to correlate the machine code to your program files. Quite handy when you are trying to find out where your code is wrong!

once again to compile your program. The command creates an executable file called hello_world .

This time, run your compiled code (a.k.a. the executable) in the terminal with,

The ./ tells the terminal that you want to run an executable file in the current working directory (i.e., the lab1 directory).

If everything has worked correctly, the following message should appear in your terminal:

To speed up the process, you can combine the commands in to one:

Exercise 2: C Introduction #

The C programming language was developed at Bell Labs by Dennis Ritchie in 1970s. It entered the scene when AT&T was developing the Unix operating system. It quickly rose to prominence as one of the most popular programming languages, a crown that it still holds today. C is notably the first choice for writing low-level software (called systems software), e.g., the Linux operating system.

Systems software interacts closely with the underlying hardware, e.g., for controlling the CPU and memory-resources. High-level user applications (e.g., Spotify) are typically written today in Python and Java. The focus of (user) applications is to provide specific functionality to the user and not to control and manage hardware resources.

Nevertheless, there remains a high demand for C, particularly in embedded systems and IoT and other highly resource constrained environments.

A defining feature of C is that it is closely tied to the underlying hardware. C statements map efficiently to machine instructions. Furthermore, the language is small and simple, leading to efficient code that runs fast and has a small footprint (e.g., the number of instructions).

Therefore, C programs are lightweight compared to other programming languages, such as Java and Python, but are still written at a higher level of abstraction than assembly programs. We will learn in coming labs that C programmers still have low-level access to hardware resources and memory in particular. This last aspect of C is both a blessing and a bane. (You will find out!)

In this half of the course, we intend to teach you how programs written in C interact with CPU and memory at the microarchitectural level. We do not intend to teach programming practices in general and every tiny detail about C’s syntax. We advise you to use the recommended textbook and numerous external online resources for help (when needed).

Every programming language has certain elements critical to writing programs of decent complexity. This tutorial will go through the ones most relevant to the future labs and the second assessment.

Most students in this course have previous programming experience with Java. C’s basic syntax is quite similar to Java, but C has many features of its own!

Variables and basic types #

Declaring variables in C is almost identical to Java, where you have a “type” and then a variable name, and optionally an initial value. Then you can use and modify those variables later in the program as usual.

Also notice how lines of code have to be separated by semicolons, again same as Java. C is not whitespace sensitive so any kind of indenting works as long as the semicolons are there to separate lines. But good code style demands that you indent with caution!

Note that in Java, the compiler will stop you from using a variable without initialising it. An important thing to note about C is that although it may raise a warning, C actually doesn’t stop you from doing this ! However, it is undefined behaviour and the variable can contain any random value before you use it. So best not.

C’s primitive types mostly mirror Java’s primitive types, and include:

Type Meaning
8 bit signed integer
16 bit signed integer
32 bit signed integer
64 bit signed integer
single-precision real number
double-precision real number

You might notice the lack of booleans and strings. C deals with the same sort of objects that most computers do, namely characters, numbers, and memory addresses. Booleans in particular are represented by int s where 0 means false and any non-zero number means true. This will be elaborated on later. The string type will also be discussed later, though you’ve already seen the use of a string literal; the "Hello, world!" text in src/hello_world.c defines a C string.

If you are interested in what ‘single-precision’ and ‘double-precision’ refer to, then look at the IEEE 754 floating-point number specification .

All of the integer types above can have unsigned prepended to them to make them unsigned integers. For example

The floating-point types are always signed.

The C compiler uses types to know how much space in memory to use for a value and how operations on that value work. For example, we can add two int s fine

But we get possibly unexpected results when adding integer and floating-point types

In the above example, we add x and f in two different contexts: one assigns the result to an int variable, and the other assigns the result to a double variable. The resulting values from the two operations are different.

In this case, the result is being implicitly converted to the result variable’s type (an “implicit cast”). The C standard defines the rules these conversions follow, so correct programs are allowed to do this. However, it is easy to do this accidentally and not realise it, with the mistake causing errors later on in your program. We have added the -Wconversion flag to our compiler flags to make the compiler show a warning when an expression like the one above may result in lost information. In this case, the compiler would show something like

As a general rule, it is safe to add values and store the result to the ‘larger’ type. For example,

Alternatively, if you do an explicit cast using the cast operator like below, then the compiler knows the cast is intentional and does not warn you. You must know what you’re doing though!

Read and predict what compiler warnings related to type conversion will be raised by src/types.c . Also, add any other type combinations that you find interesting.

Next, compile the program and compare the outcome against your predictions.

There are more C types, which we will discuss later.

There is also a special operator in C which we would like you to know. The sizeof() operator gives the size of a variable in bytes, and returns a long . It is used as follows:

What will s be in the above code fragment?

Functions #

We can also define functions with syntax identical to Java, including a function signature with the return type, function name and function arguments with types, and then the function body in curly braces:

A function that returns nothing has return type void .

All executable C programs have a main function which is the entry point of the program. C files need not contain one if they just define library functions which will be used in other programs (see upcoming discussion of Header files), but generally they do. One possible signature for main is:

The “int” that is returned is the exit code of the program. “0”, the standard code, means the program exited normally. Other exit codes may indicate that an error has occurred, and typically the specific number is used to describe specifically what caused the termination so the programmer can debug problems. Some more status codes are described here .

We will see an alternative signature for the main function and talk about its interface in detail later.

Calling a function is done in the same way as Java as well:

The C library provides several useful functions for programmers. The printf function prints its arguments on the standard output, which by default is the screen. Unlike most functions you will come across in C, the printf function takes a variable number of arguments. The first argument is always the message to print (such as "Hello, world!" ). The remaining arguments are data to be substituted into the message. These arguments can be of any type with a corresponding format specifier . The name printf itself is a combination of print and f ormatted.

A format specifier begins with % . For example, %i is the ‘integer format specifier’. If you use this format specifier, then the printf call must have an integer value passed as the next argument. Format specifiers are matched with printf arguments in order from left to right:

  • the first format specifier is expanded to the value of the second printf argument,
  • the second format specifier is expanded to the value of the third printf argument,

A message does not require format specifiers. You can see this in the src/hello_world.c source file, where only the message to be printed is passed. You will see examples of using format specifiers in the following exercises.

Common format specifiers are as follows

Format Meaning
Print a single literal . Necessary to print, e.g., literally instead of as a format specifier. All literal signs should be written like in a format string for safety. Note this does not get matched with an argument.
Print a value in
or Print value in decimal
Print an value in decimal
Print value in hexadecimal
Print value in decimal
Print floating-point value
Print the contents of a string (see )
Print pointer value (see )

You will also notice that the message often ends with \n . The compiler turns \n into the newline character. If we forget to put a \n at the end, then whatever is printed next will be put on the same line. So if you see things like

you might be forgetting to add newlines

src/format_strings.c shows some examples of using printf to print different types of variables. The last two lines with strings and pointers have not been introduced to you yet, but you can see them here in any case.

Build and run the program:

Does it print what you expect? Are there any differences?

Other format specifiers and even modifiers can be applied to the given format specifiers. This reference page shows you all the possible values, with examples. The %li format specifier in the table above is an example of a modifier: the l modifies the i format to accept long (64-bit) values instead of 32-bit.

Some programs become very large and unmanageable in a single source file. Furthermore, some programs are written to be reused across multiple projects. Copy/pasting code across projects makes it hard to keep code up to date, and thus reusing code inevitably leads to multiple source code files. We need a way to ‘link’ these independent program files together during compilation.

The canonical way to support multiple files in C is with header files . These files are given the .h extension, and they define the signatures of all functions exported from the corresponding .c source file.

You have already seen a .h file be used in the previous examples: stdio.h is a header file in the C standard library that defines the printf function signature ( stdio is short for st an d ard i nput / o utput). We write #include <stdio.h> to import these signatures into our program, allowing us to use them. Then, when we run the compiler, the linker includes the associated implementation of printf into our compiled program.

#include is called a preprocessor directive, which behaves as if you replaced it with the contents of the specified file at the exact same location. We will often include the <stdio.h> and <stdlib.h> headers to access the functions declared in those headers, which we can then call from our programs. The <stdio.h> contains the declarations for C standard I/O functions. I/O stands for Input/Output. The <stdlib.h> header contains utility functions we will use in future labs.

Anatomy of a C Program #

Return now to your src/hello_world.c file. You should now understand the whole file as written. This basic format will remain the same across your C projects. Line by line, the file contains:

Includes the stdio.h header that allows use of functions within the stdio (part of the C library). This is required for the printf function.

Is the declaration of the main function , the starting point of your program. int is the return type of the function.

This line calls the printf function, printing the argument to the standard output or stdout, which you see in the terminal.

This statement ends the function. Returning 0 is the usual way to signal that the program has terminated without error.

C uses {} braces for code bodies, () for function arguments, and ; for line terminations. Here we are closing the code body of the main function.

In the hello_world.c file, use the printf function to:

  • Print the result of 2 + 2
  • Print the sizes of an int and a double on your machine using the sizeof() operator Make sure to compile and run your program to test it.

Exercise 3: Control flow and simple I/O #

Bitwise and logical operators #.

You will perhaps remember the bit manipulation you had to do in COMP2300 using assembly instructions like and , orr , lsl and lsr . C similarly allows you to consider numbers in binary, and provides the following operators for bitwise manipulation. These can only be applied to integral operands.

Operator Meaning
Bitwise AND
Bitwise inclusive OR
Bitwise exclusive OR
Left shift
Right shift
One’s complement / bitwise NOT (unary)

You can also freely write numbers in hexadecimal (recall 0x means the following number is hexadecimal), and print numbers in hexadecimal using the %x format in printf .

Not all C compilers support 0b to write binary numbers (though yours might ). printf also doesn’t support printing in binary format. However, by now you should know how to convert hexadecimal to binary in your head; ask a tutor if not.

There are also “logical operations” that are used when treating numbers as booleans.

Operator Meaning
Logical OR; outputs 1 if either of its inputs are nonzero/true, and 0 otherwise
Logical AND; outputs 1 if both of its inputs are nonzero/true, and 0 otherwise
Logical NOT; outputs 1 if its input is 0, and 0 if input is nonzero

Traditionally, when using integers as booleans, people just use the numbers 0 (to mean false) and 1 (to mean true). However, there are many other numbers that integers can be (e.g. 2, or 40000, or -1). The C spec deals with this by treating ALL nonzero numbers as true. So something like 2 && 3 would be interpreted as TRUE && TRUE , and so output 1 which means TRUE .

Note that bitwise operations and logical operations are strictly different!

The constant Booleans FALSE and TRUE are implemented as 0 and 1 respectively.

As a warm-up exercise, predict what the results of the following statements will be:

Variable Value (Decimal) Value (Hexadecimal) Value (Binary)

Open the file src/bitwise-puzzles.c and write missing code for the functions in the file. Each function involves solving a puzzle with the provided constraints. Each function has a comment that includes the permitted operators, maximum number of operators to use and a rating difficulty.

Note that you are allowed to use constants like 0xFF , as well as intermediate variables (e.g. you may define an int mask variable to first compute the mask before applying it).

Write a main() function to test your code.

Relational Operators and Control Flow #

The relational operators include

Operator Meaning
Equal to
Not equal to
Less than
Greater than
Less than or equal to
Greater than or equal to

Each of these operators return 1 if the specified relationship is true, and 0 if it is false. The result type is int (but is intended to be interpreted as a Boolean).

C has the same standard imperative control flow constructs you’re familiar with from Java, in basically the same syntax. We’ll go over these quickly.

If/else statement example:

While loop example:

Recalling how integers represent Booleans, while (1) {} is how you would write an infinite loop.

For loop example:

Switch statement example (note this is equivalent to the if/else ladder above):

Remember that if a switch case clause doesn’t have a break statement, execution will keep going to also execute the next case’s case! In general you likely want all of your case clauses to have a break statement, but the above code also shows how you can omit the break statement to combine cases.

continue , break and return statements in loops and functions also exist and work as you’d expect as well.

Character type and Input/Output #

C uses char type to store characters and letters. Interestingly, under the hood, the char type is an integer type. C stores integer numbers instead of characters. More specifically, in C, a char variable is stored as one byte in memory with value ranging from \(-128\) to \(127\). To represent characters, the computer must map each integer to a corresponding character using a numerical code. ASCII is the most common numerical code and it stands for American Standard Code for Information Interchange. Take a look at the ASCII table .

The original ASCII defined characters with values from 0 to 127. Later, many countries used the remaining 128 values in a byte to support their local character set, or more symbols. This lead to the possibility that an email sent from one country could appear corrupted when read in another. The contents were identical, but the computers were picking different (most likely nonsensical) characters to display!

The following code checks to see if a char value is a valid letter from the English alphabet. Note that the condition checks for both lower-case and upper-case letters.

You might be tempted to write 'a' <= c <= 'z' like Python allows, but in C this would not evaluate as you might expect. It first evaluates 'a' <= c to 0 or 1 , and then compares if this is less than or equal to 'z' , which is always true! This is why we split the comparisons and join the results with && .

Checking if c is between the first and last letters works in ASCII because the numerical values of letters are consecutive from a to z and from A to Z (but not from z to A ! There is a gap with symbols in between).

The header file ctype.h provides a number of useful utilities to manipulate characters. You can find several resources with a list and description of useful methods. Here is one useful resource .

getchar and putchar #

It is useful to be able to read one character at a time from keyboard. Each time it is called, getchar reads one character from the keyboard. The code

reads a character from the keyboard and assigns it to the integer variable c . The function putchar prints a character each time it is called:

prints the contents of the integer variable c as a character on the screen.

When interacting with your program through a terminal, getchar does not return as soon as you press a key. The character data is available only when the user presses Enter to indicate they are happy with what is typed. Read more here .

We will now look at writing programs that use control flow and character manipulation. But before that, we want to introduce two useful elements for writing cool programs. The first one is another compiler directive, namely #define . The #define directive allows the definition of constant values to be declared for use throughout your code. Consider the code below

Once we define HIGH and LOW to be 1 and 0, respectively, we can use them anywhere in the code. Any occurrence of HIGH will be replaced with 1 and LOW with 0. More generally, HIGH is a symbolic constant and 1 is the replacement text. Symbolic constants are useful for defining constants at the start of a program and judicious use can improve code readability.

A useful symbolic constant defined in stdio.h is EOF (end-of-file) and it indicates there is no more possible input to read. Detecting the end of input is useful when reading input characters from the keyboard as we will see shortly.

The standard input (keyboard) is treated as a special file in C. A program can read input from the keyboard until the end-of-file is encountered. A user can indicate end-of-file by typing a special key combination. If you are typing at the terminal and you want to provoke an end-of-file, use Ctrl - D (Linux, macOS), or Ctrl - Z (Windows). The following C program reads input characters from screen and prints them on screen until the end-of-file is typed.

Note that EOF is not a character and therefore we must use the larger int type for the variable c against which we compare EOF .

Open the file src/copy.c and carefully read the code. Compile and run the code. Try and rewrite the code to use as few statements as possible.

To test the compiled program, make sure to press Enter each time you input a character from the keyboard.

You can do an assignment and test a condition as part of the condition in the while loop. The following is perfectly valid C syntax:

Note: if you are on Windows and are using WSL in the terminal while using VSCode in Windows, or for another reason may have cloned your repo in Windows while accessing it in WSL, the command git add -A (add all unstaged changes) may add all files in the repo. See here for advice if this occurs to you.

Open the file src/lines.c and carefully read the code. Can you guess what the code is doing? Compile and run the code to test your guess.

Write a program in src/wordcount.c that counts the number of words typed on the standard input (via keyboard). We define a word as follows: a sequence of characters that does not contain a blank or newline. The program terminates when EOF is encountered.

Interlude: Scopes of Variables #

Let it be noted that variables defined inside functions are only visible inside the function. You can also have variables that sit in the “top level” program outside all of the functions, which are global and visible in all functions.

Control flow statements also define inner scopes in their clauses. For example, a variable defined in an if statement is not visible outside of it:

Instead, we need to define the variable outside the if statement and only initialise it in the if statement:

This is behaviour you should be used to from Java.

Exercise 4: Pointers, Arrays and Strings #

Up until now, C has perhaps looked like nothing more than a simple imperative language, but that will all change with pointers and how C directly relies on the user to control memory!

Every type in C has a corresponding pointer type. A ‘pointer’ is C’s terminology for a memory address. Recall that memory is divided into a number of byte or word-sized locations. Each such location has an address. C is unique in that it gives the programmer the ability to manipulate both the address and the contents of any memory location. Therefore, if you have a pointer to a variable, you have the memory address of that variable. Recall in assembly the use of labels. Pointers and labels are similar in the sense that both contain a memory address. C pointers are real variables that exist at run-time (i.e., when the program runs). In summary:

A pointer is a variable that contains the address of a variable.

The syntax for declaring pointer variables is as follows,

Note that we have inserted * between the type ( int in this case) and the variable name ( my_pointer ). Here we have declared that my_pointer is a variable whose value is the memory address of some int variable. The * operator has multiple uses in C. We have just seen a second use above for pointer declaration, and recall the first use was for multiplication.

But we have not initialised this variable with a value. We cannot use it for anything yet, because that would be undefined behaviour, and correct programs do not have undefined behaviour. We can initialise the pointer variable to point to another variable as follows

Here we have put & before the use of x to get the address of x instead of its value.

OK, so now we have a valid pointer pointing to another variable. What can we do with it? Consider the following program.

It is important to note that we have introduced above a third use of the * operator, which is to dereference a pointer. Dereferencing allows us to read or modify the memory at the location pointed to by the pointer (which, remember, is just a variable that holds a memory address).

As we dereferenced p on the left hand side of the assignment, we have used dereferencing to modify the memory pointed to by p . But this memory is of our variable x ! We have changed x without using the name x , except for when we initialised p .

You can print the value of pointers using printf and the %p format, which gives the corresponding address.

Read the file src/pointers.c . Predict the values of x and p that will be printed before and after the dereference step. Then run

What do you see as the outcome? Does it match your prediction?

The operator & gives the address of another variable. The operator * is the dereferencing operator; when applied to a pointer, it accesses the object the pointer points to.

Return to src/pointers.c and remove the contents of the existing main program. Then, define 3 variables consecutively inside the main program like so:

Now use the reference operator and %p option in printf to print the addresses of these variables. What do you notice? Recall the sizes of int s and long s in C. What does this mean about how these variables are laid out in memory?

Now try adding a global variable that is defined OUTSIDE the main program in the top level scope, and print its address. What do you notice? How might you explain this observation?

Pointers represent memory addresses, which are really just numbers. This means you can cast any integer to a pointer, and while C might give a conversion warning, it will not error. Return to src/pointers.c and write code to read the contents of the address 0 (or any other random address). What happens?

You will learn more about the error you got in the last exercise when you study the operating system and virtual memory in lectures, but for now just understand that you can’t freely access memory like on the Microbit. The memory has to be allocated to your application, e.g. when you define a global variable the compiler knows to allocate memory for it, and the memory address for it will be valid.

Arrays and pointer arithmetic #

An array is a block of consecutive variables or objects of the same type. Declaring and accessing them is, at a surface level, the same as in Java; you can declare and optionally initialise an array as below (when initialising, you do not need to provide the size since it can be inferred from how many elements you initialised it with)

There is a strong relationship in C between arrays and pointers. To understand this, recall how you defined an array in assembly in COMP2300; it is just a label followed by data that appears consecutively in memory. So you might define the marks array like this:

Since the start of this array is just a label, which in C we consider as a pointer, the array itself is just a pointer to the start. And indeed, in C, the name of the array is a synonym for the location of the first element. In fact, it is itself a type of pointer. We can declare a pointer named pa and initialise it with the address of the first element of the marks array like so:

Furthermore, a reference to marks[i] can also be written as *(marks+i) . We can in fact also do the same operation on the new pointer pa , even though the compiler does not know it points to an array!

In evaluating marks[i] , the compiler converts it to *(marks+i) immediately; the two forms are equivalent.

Here we introduce a new pointer operation: pointer arithmetic. We can add an integer to the pointer pa and make it point to any other element of the marks array.

For example, pa+1 points to the second element of the marks array, i.e., marks[1] (see top of the figure below). Note that pa , pa+1 , and pa+2 contain the addresses of the array elements and not their contents. These remarks are true regardless of the type and size of variables in the marks array. The meaning of adding 1 to a pointer , and by extension, all pointer arithmetic, is that pa+1 points to the next object, and pa+i points to the i-th object after pa .

Note here that in assembly , the byte address of the ith element of marks would be byte address of marks + sizeof(int) * i . But because in C, marks is a pointer of type int * and it knows already that it points to objects of type int, it multiplies by sizeof(int) for you behind the scenes; adding i to the pointer traverses by i ints in memory instead of i bytes. The middle section of the figure below shows the actual byte addresses of elements in the array, which may help clarify this point for you.

To obtain the contents of an array element, we need to use the dereferencing (*) operator. Dereferencing is depicted at the bottom of the figure. For instance, *(pa+2) refers to the value stored at the memory address pa+2 .

pointers

The following two C statement both print the value of the third element of the marks array,

Consider the following two C statements. Their behaviour is equivalent.

The close relationship between arrays and pointers should now be obvious. Consider the first statement above. We have just indexed the pointer pa to access an element of the array (marks[2]) ! The compiler knows that we want to access the third integer in the marks array. Similarly, in the second statement, when we add 2 to pa , the result (memory address) points to the third element of the array.

Finally, the following two statements are equivalent and both assign the address of the first element of the marks array to the pointer variable pa .

We often say that arrays decay to pointers. This behaviour is especially true when passing arrays to functions as arguments, which we will discuss in a moment.

Note that there IS a difference between array types and pointers though, which is that when using an array type, the compiler knows it is an array. This means, for instance, that you can do sizeof() on an array and it will take into account all the elements in the array, e.g. sizeof(int[7]) = 4*7 = 28 . Meanwhile, you lose that information when given just a raw pointer; sizeof(int *) = 8 . This also means that you need to use some kind of workaround to know the size of the array if you only have a pointer to it; either have a variable containing the size, or make the array end with some special “terminator” value.

C does no bounds checking at runtime; it is very easy to access an index of an array that is beyond the end of its length. This has implications for security as it potentially allows users to access memory they’re not supposed to, as well as program correctness! Most of the time, a segmentation fault will notify you of the error, but sometimes it can be incredibly tricky to debug…

Read the src/arrays.c program and predict the outcome. Then run the program and check if your predictions match the actual outcome. The program should print a warning. Make sure you understand what this warning is about.

In src/arrays.c , write a C program where you define an array of integers, and print the address of each element of the array using the subscript ( [] ) and reference operators ( & ). Confirm that the elements really are contiguous in memory.

Recall how we described pointer arithmetic. Consider the following code:

Put this in src/arrays.c , compile and run it. How much does p increment by each time 1 is added? Now try changing all the instances of “int” in the above code to “char”. Does your answer to the last question change? Why should it?

Controlling pointer arithmetic will be important especially in your first assignment.

C Strings #

Unlike Java, which has a dedicated String object type, strings in C are just arrays of char values. So the following is a C string

When you create a string in this way, the C compiler will automatically write a byte with value 0x00 at the end. The resulting array is called a null-terminated string, and is a method of determining the length of the string without tracking the length in a separate variable. So the above string initialises memory the same in the following way,

Single and double quotes mean different things in C. Single quotes are used to create char values. Double quotes are used to create string values (an array of char values ending with a null (zero) byte).

Similar to \n , the sequence \0 is replaced by the C compiler with an actual null byte.

It is not possible to modify a string declared using "..." syntax. Trying to do so is undefined behaviour. It might even work on your computer, but fail on someone else’s.

Open the src/string-util.c file and implement string_cpy and reverse functions. Don’t forget to set the trailing null bytes!

Exercise 5: Pointers as function arguments #

Recall how functions in C look like from the last tutorial. Functions take input arguments and they optionally return a value. C passes arguments to functions by value (affectionately called pass by value or call by value ). These phrases mean that when we provide an argument to a function, the value of that argument is copied into a distinct variable for use within the function. Consider the following function that tries to swap two arguments. We call this version of swap the version 1 or v1 .

We first safely store a in a temporary local variable called temp . We then do the swapping. Run the program src/swap.c and you will find something strange. Although a and b have been successfully swapped inside the swap function, when we print a and b from the main function, we still see their original (non-swapped) values.

Why do you think this is happening?

We can use pointers to rewrite the swap function. We can use the indirection ( * ) operator to declare pointers and dereference them. Consider the following prototype of the swap_v2 function

Passing arguments in the above fashion is called pass by reference . We are not providing the swap_v2 function the actual values of a and b . Instead, we are passing a reference to a and b . In other words, we are providing the swap_v2 function with the memory addresses of a and b .

Open src/swap.c and write the code to swap a and b in the swap_v2 function. Test that your new function definition swaps the input arguments, so even from the main function, when we print a and b , we observe their values swapped. Does your new function work?

You can push your work to GitLab to check – the CI will run a test of the swap program.

Pointers as function arguments serve another important purpose. Recall that C functions can return only a single value. What if we want our functions to return more than one value? We can pass the address of a variable to a function (i.e., pass a pointer as the input argument). The function can then assign a value to the variable pointed-to by the input argument using the dereference operator.

Read the program in src/return2.c . What value of ret1 and ret2 do you expect to see on the screen? Run the program and test your hypothesis.

Exercise 6: Arrays and strings as function arguments #

Now that we have introduced pointers as functions, we can also pass arrays and strings to functions. The following exercises ask you to do this while also testing your understanding of pointers, arrays and strings.

Open src/sum.c and complete the function definition of the sum function. Make sure it correctly sums up the elements of the input array to the function. Note again that array arguments can be passed to functions as pointers, and we can do the usual pointer arithmetic on these input arguments. So, sum(int *array) is the same as sum(int array[]) .

Will your sum function still work if given an array of a different length?

Is it possible to determine the size of the array argument inside the sum function, or will you need to modify sum to include the array length as an argument?

Write a program that compares two strings character-wise and returns a 1 if the two strings are equal. Otherwise, the function returns 0. Write your code in src/strcmp.c . You can rely on the caller to pass null-terminated strings to the str_cmp function.

Write a function that takes a null-terminated string as an input argument. It computes and returns the length of the string. Test your function by writing a C program with a main function. Write the code in src/strlen.c .

Exercise 7: Program Arguments #

Program arguments are a list of values passed to our program when it is run. You have used this when you ran the make command:

runs the program make with the argument hello_world . That is how make knows to build that particular file.

In C, we can get the program arguments from the argc and argv parameters to main . The function signature for main now looks like

The type of the char **argv parameter looks new, but you have seen this type before: it is just two levels of pointer ! argv is a pointer to a pointer to a char . If you read the memory pointed to by argv , the value you get is itself a pointer of type char * . If you read the memory where that pointer points, then you get a char value.

But these argv related pointers are not just to single values — both levels of pointer are to arrays of values. So really argv is an array of C strings , which themselves are null-terminated arrays of char values.

Also remember that C arrays do not store their length like you might be accustomed to in Python. This is fine for the C strings, because they end when we see a null byte, but how long is the overall argv array? This is where argc comes in: argc is the number of elements in the argv array. The given names are actually abbreviations:

  • argc : arg ument c ount
  • The term vector in the context of programming refers to a resizable array-like structure. The use of ‘vector’ in the name argv is historic; as you cannot change its size, array is a better description of the actual data structure.

So altogether we have an array of string arguments argv , this array having length argc , and each element in the array is a pointer to a null-terminated C string.

In src/program-args.c , write a program that, assuming there is at least one program argument,

  • On the first line prints There are X arguments where X is replaced with the number of program arguments
  • On the next line, print The first argument is Y where Y is replaced by the argument at index 0
  • On the next line, print The following arguments are
  • Then print the rest of the arguments (from index 1) on a new line each with the format: - Z (size: N) where Z is the argument and N is the sizeof that argument
  • Then, on the next line, print The total size of the arguments is T where T is replaced by the sum of the sizeof the arguments.

Refer back to earlier sections (as needed) for using pointer values and printing formatted strings.

Build and run your program with different arguments. E.g.,

Do you notice something odd?

You will most likely notice that the first argument that is printed is not “first” as you would expect - instead it is “program-args”.

The C Reference has a page dedicated to the main function available here . It says:

If argv[0] is not a null pointer (or, equivalently, if argc > 0 ), it points to a string that represents the program name.

You may also see the function signature for main written as:

This behaves equivalently to the char **argv declaration used above.

If you’ve reached this point, you have finished all the content from Lab 1. Excellent work!

You can look at next weeks lab ahead of time if you are feeling eager to keep learning more about C.

Resources #

cppreference : Comprehensive C reference pages. This reference is not a tutorial. It is instead a reference for the entire C language. It contains a lot of content and terminology we do not cover. It is most helpful for reviewing documentation and usage of specific functions, such as printf .

codecademy : Free external resource for learning C.

x86 is a CISC ISA that originally debuted on the Intel 8086 in 1978. It has since been expanded from 16 to 32, to 64 bits. Featuring variable instruction lengths, over 30 extensions, many addressing modes, and full backward compatibility (16-bit code will run on a modern 64bit processor!), x86 is rightfully considered one of the most complex ISAs to exist.  ↩

C Data Types

C operators.

  • C Input and Output
  • C Control Flow
  • C Functions
  • C Preprocessors

C File Handling

  • C Cheatsheet

C Interview Questions

C programming language tutorial.

In this  C Tutorial , you’ll learn all C programming basic to advanced concepts like variables, arrays, pointers, strings, loops, etc. This C Programming Tutorial is designed for both beginners as well as experienced professionals, who’re looking to learn and enhance their knowledge of the C programming language.

C is a general-purpose, procedural, high-level programming language used in the development of computer software and applications, system programming, games, and more.

  • C language was developed by  Dennis M. Ritchie  at the Bell Telephone Laboratories in  1972 .
  • It is a powerful and flexible language which was first developed for the programming of the  UNIX operating System .
  • C is one of the most widely used programming languages.

C programming language  is known for its simplicity and efficiency. It is the best choice to start with programming as it gives you a foundational understanding of programming.

C-Programming-Language

Getting Started With C Tutorial

Start your coding adventure with our free C Tutorial. A perfect C programming tutorial for beginners and advanced coders alike, this tutorial is your key to unlocking the magic of C programming. With clear explanations and fun examples.

Table of Content

C Variables and Constants

C input/output, c control statements decision-making, c arrays & strings, c user-defined data types, c storage classes, c memory management, c preprocessor, c error handling, miscellaneous.

  • C Language Introduction
  • Features of C Programming Language
  • C Programming Language Standard
  • Setting Up C Development Environment
  • C Hello World Program
  • Compiling a C Program: Behind the Scenes
  • Tokens in C
  • C Identifiers
  • Keywords in C
  • C Variables
  • Constants in C
  • Const Qualifier in C
  • Different Ways to Declare Variable as Constant in C
  • Scope Rules in C
  • Internal Linkage and External Linkage in C
  • Global Variables in C
  • Data Types in C
  • Data Type Modifiers in C
  • Literals in C
  • Escape Sequence in C
  • Integer Promotions in C
  • Character Arithmetic in C
  • Type Conversion in C
  • Basic Input and Output in C
  • Format Specifiers in C
  • printf in C
  • Scansets in C
  • Formatted and Unformatted Input and Output Functions
  • Operators in C
  • Arithmetic Operators in C
  • Unary Operators in C
  • Relational Operators in C
  • Bitwise Operators in C
  • Logical Operators in C
  • Assignment Operators in C
  • Increment and Decrement Operators in C
  • Conditional or Ternary Operator (?:) in C
  • size of Operator in C
  • Operator Precedence and Associativity in C
  • Decision-Making in C
  • C if Statement
  • C if…else Statement
  • C if-else-if Ladder
  • Switch Statement in C
  • Using Range in switch case in C
  • while looping in C
  • do…while Loop in C
  • for versus while Loop
  • continue Statement in C
  • break Statement in C
  • goto Statement in C
  • User-Defined Function in C
  • Parameter Passing Techniques in C
  • Importance of Function Prototype in C
  • Return Multiple Values From a Function
  • main Function in C
  • Implicit Return Type int in C
  • Callbacks in C
  • Nested Functions in C
  • Variadic functions in C
  • _Noreturn Function Specifier in C
  • Predefined Identifier __func__ in C
  • Maths Functions in C
  • Properties of Array in C
  • Multidimensional Arrays in C
  • Initialization of Multidimensional Arrays in C
  • Pass Array to Functions in C
  • Pass a 2D Array as a Parameter in C
  • Data Types for Which Array is Not Possible
  • Pass an Array by Value in C
  • Strings in C
  • An Array of Strings in C
  • Difference Between Single Quoted and Double Quoted Initialization
  • String Functions in C
  • Pointer Arithmetics in C
  • Pointer to Pointer (Double Pointer) in C
  • Function Pointer in C
  • Declare Function Pointer in C
  • Pointer to an Array in C
  • Constant Pointer in C
  • Pointer vs Array in C
  • Dangling, Void, Null and Wild Pointers
  • Near, Far and Huge Pointers in C
  • restrict Keyword in C
  • C Structures
  • dot (.) Operator in C
  • Structure Member Alignment, Padding and Data Packing
  • Flexible Array Members in a Structure in C
  • Bit Fields in C
  • Difference Between Structure and Union in C
  • Anonymous Union and Structure in C
  • Enumeration (or enum) in C
  • Storage Classes in C
  • extern Keyword in C
  • Static Variables in C
  • Initialization of Static Variables in C
  • Static Functions in C
  • Understanding “volatile” Qualifier in C
  • Understanding the “register” Keyword in C
  • Memory Layout of C Programs
  • Dynamic Memory Allocation in C
  • Difference Between malloc() and calloc()
  • What is a Memory Leak?
  • Dynamic Array in C
  • Dynamically Allocate a 2D Array in C
  • Dynamically Growing Array in C
  • C Preprocessor Directives
  • How a Preprocessor Works in C?
  • Header Files in C
  • Difference Between Header Files “stdio.h” and “stdlib.h”
  • Write Your Own Header File in C
  • Macros and their Types in C
  • Interesting Facts About Macros and Preprocessors in C
  • # and ## Operators in C
  • Print a Variable Name in C
  • Multiline Macros in C
  • Variable Length Arguments for Macros
  • Branch Prediction Macros in GCC
  • typedef versus #define in C
  • Difference Between #define and const in C
  • Basics of File Handling in C
  • C fopen() Function
  • EOF, getc() and feof() in C
  • fgets() and gets() in C
  • fseek() vs rewind() in C
  • Return Type of getchar(), fgetc() and getc()
  • Read/Write Structure From/to a File in C
  • C Program to Print Contents of File
  • C Program to Delete a File
  • C Program to Merge Contents of Two Files into a Third File
  • Difference Between printf, sprintf and fprintf
  • Difference Between getc(), getchar(), getch() and getche()
  • Error Handling in C
  • Using goto for Exception Handling in C
  • Error Handling During File Operations in C
  • C Program to Handle Divide By Zero and Multiple Exceptions
  • Basic C Programs
  • Control Flow Programs
  • Pattern Printing Programs
  • Functions Programs
  • Arrays Programs
  • Strings Programs
  • Conversions Programs
  • Pointers Programs
  • Structures and Unions Programs
  • File I/O Programs
  • Date and Time Programs
  • More C Programs
  • Date and Time in C
  • Input-output system calls in C
  • Signals in C
  • Program Error Signals in C
  • Socket Programming in C
  • _Generics Keyword in C
  • Multithreading in C
Top 50 C Programming Interview Questions and Answers Commonly Asked C Programming Interview Questions | Set 1 Commonly Asked C Programming Interview Questions | Set 2 Commonly Asked C Programming Interview Questions | Set 3

Why Learn C?

C programming language is one of the most popular programming language. It is a must learn for software engineering students. C is called the mother of all modern programming languages so learning C will help you to learn other languages easily like Java, C++, C#, Python, etc. C language is faster than other programming languages like Java and Python. It can handle low-level programming and we can compile the C code in a variety of computer platforms.

List of some  key advantages of C language :

  • Easy to learn.
  • Versatile Language, which can be used in both applications and technologies.
  • Mid-Level Programming Language.
  • Structured Programming Language.

C compiler is a software that translates human-readable C language code into machine code or an intermediate code that can be executed by a computer’s central processing unit (CPU).

There are many  C compilers  available in the market, such as  GNU Compiler Collection (GCC) ,  Microsoft Visual C++ Compiler ,  Clang ,  Intel C++ Compiler , and  TinyCC (TCC) .

For this tutorial, we will be using the GNU-based online C compiler provided by GeeksforGeeks which is developed for beginners and is very easy to use compared to other compiler/IDE’s available on the web.

Print Hello World using C Programming

“Give this C code a try, and here’s a fun challenge: print ‘Hello World’ along with your name!”

Features of C Language

There are some key features of C language that show the ability and power of C language:

  • Simplicity and Efficiency:  The simple syntax and structured approach make the C language easy to learn.
  • Fast Speed:  C is one of the fastest programming language because C is a static programming language, which is faster than dynamic languages like Java and Python. C is also a compiler-based which is the reason for faster code compilation and execution.
  • Portable:  C provides the feature that you write code once and run it anywhere on any computer. It shows the machine-independent nature of the C language.
  • Memory Management:  C provides lower level memory management using pointers and functions like realloc(), free(), etc.
  • Pointers:  C comes with pointers. Through pointers, we can directly access or interact with the memory. We can initialize a pointer as an array, variables, etc.
  • Structured Language:  C provides the features of structural programming that allows you to code into different parts using functions which can be stored as libraries for reusability.

Applications of C Language

C was used in programs that were used in making operating systems. C was known as a system development language because the code written in C runs as fast as the code written in assembly language.

The use of C is given below:

  • Operating Systems
  • Language Compilers
  • Text Editors
  • Print Spoolers
  • Network Drivers
  • Modern Programs
  • Language Interpreters

FAQs on C Language

Q1. how to learn c easily.

The first steps towards learning C or any language are to write a hello world program. It gives the understanding of how to write and execute a code. After this, learn the following: Variables Operators Conditionals Loops and Errors Arrays and Strings  Pointers and Memory Functions Structures Recursions 

Q2. Difference between C and C++?

C

CPP

C is a procedural programming language.

C++ is both a procedural and object-oriented programming language.

It does not support Function overloading.

It supports function overloading.

Operator overloading is not supported.

Operator overloading is supported.

C does not support data hiding which leads to security concerns.

Data hiding is supported in C++ by Data Encapsulation.

 Q3. Is C easy to learn for beginners?

While C is one of the easy languages, it is still a good first language choice to start with because almost all programming languages are implemented in it. It means that once you learn C language, it’ll be easy to learn more languages like C++, Java, and C#.

Q4. Why should we learn C first rather than C++?

C is a ‘ mother of all languages .’ It provides a solid understanding of fundamental programming concepts and is considered easier to grasp. C offers versatile applications, from software development to game programming, making it an excellent choice for building a strong programming foundation.

Please Login to comment...

Similar reads, improve your coding skills with practice.

 alt=

What kind of Experience do you want to share?

Tutorials Class - Logo

  • C All Exercises & Assignments

Write a C program to check whether a number is even or odd

Description:

Write a C program to check whether a number is even or odd.

Note: Even number is divided by 2 and give the remainder 0 but odd number is not divisible by 2 for eg. 4 is divisible by 2 and 9 is not divisible by 2.

Conditions:

  • Create a variable with name of number.
  • Take value from user for number variable.

Enter the Number=9 Number is Odd.

Write a C program to swap value of two variables using the third variable.

You need to create a C program to swap values of two variables using the third variable.

You can use a temp variable as a blank variable to swap the value of x and y.

  • Take three variables for eg. x, y and temp.
  • Swap the value of x and y variable.

Write a C program to check whether a user is eligible to vote or not.

You need to create a C program to check whether a user is eligible to vote or not.

  • Minimum age required for voting is 18.
  • You can use decision making statement.

Enter your age=28 User is eligible to vote

Write a C program to check whether an alphabet is Vowel or Consonant

You need to create a C program to check whether an alphabet is Vowel or Consonant.

  • Create a character type variable with name of alphabet and take the value from the user.
  • You can use conditional statements.

Enter an alphabet: O O is a vowel.

Write a C program to find the maximum number between three numbers

You need to write a C program to find the maximum number between three numbers.

  • Create three variables in c with name of number1, number2 and number3
  • Find out the maximum number using the nested if-else statement

Enter three numbers: 10 20 30 Number3 is max with value of 30

Write a C program to check whether number is positive, negative or zero

You need to write a C program to check whether number is positive, negative or zero

  • Create variable with name of number and the value will taken by user or console
  • Create this c program code using else if ladder statement

Enter a number : 10 10 is positive

Write a C program to calculate Electricity bill.

You need to write a C program to calculate electricity bill using if-else statements.

  • For first 50 units – Rs. 3.50/unit
  • For next 100 units – Rs. 4.00/unit
  • For next 100 units – Rs. 5.20/unit
  • For units above 250 – Rs. 6.50/unit
  • You can use conditional statements.

Enter the units consumed=278.90 Electricity Bill=1282.84 Rupees

Write a C program to print 1 to 10 numbers using the while loop

You need to create a C program to print 1 to 10 numbers using the while loop

  • Create a variable for the loop iteration
  • Use increment operator in while loop

1 2 3 4 5 6 7 8 9 10

  • C Exercises Categories
  • C Top Exercises
  • C Decision Making

CS31 In-Lab Assignment 02: C programming and debugging with gdb

1. goals for this week:, 2. copy over example code, 3. c arrays, 4.1. reading input from a file, 4.2. running a program with command line args, 5.1. running gdb, 5.2. example gdb session, 5.3. gdb and command line arguments, 6. lab 2 intro, 7. handy resources.

Practice with a C program that uses arrays.

Practice with input in C: our read_file library to read from a file.

High-level overview of C programs with command line arguments.

Learn some basic gdb debugging commands. You should start using gdb to help with debugging your Lab 2 code. Over the course of the semester we will revisit using gdb , introducing more commands and features.

Introduce and get started on Lab 2 .

Create a In-Lab Assignment 02 directory in your cs31/inlab subdirectory and copy over some files:

Together we are going to start by looking at arrays.c , which contains examples of how to use (and abuse) arrays in C.

First, let’s open the arrays.c file in your favorite editor.

Next, let’s compile and run it next (we can use make to compile):

4. Input in C

In testfile.c are examples of reading values from a file using the C read_file library that the CS31 instructors wrote (implemented in read_file.c and read_file.h ).

Information about using the library is documented in comments in the .h file. Let’s open those both these in your favorite editor:

testfile.c has some code to open an input file and to read in an int value from the file. And read_file.h describes the functions provided by the library, some of which are called in testfile.c .

We are going to focus on read_file library functions ( read_float and read_int ) that read in two different types values from a file once the file is open.

Note that read_int and read_float need to know the memory location of where to put the values read in. We we use the & (ampersand) operator on a variable name to pass this memory location to the functions. We’ll talk much more about what that ampersand means as we build up our C programming skills in future assignments, but for the next lab assignment you will need to use & to pass the memory location of program variables to these functions.

The file read by the program is given as a command line argument when the program is run. To run the program testfile , specify the name of the input file on the command line like this:

You can list the contents and see the format of the values1 and values2 files, using the cat command:

Refering to the library interface commented in readfile.h , you can add calls to readfile library functions in the testfile.c program to read in the the next few values from an input file, which include both integers and floats. Then, compile and try running.

5. GDB intro

gdb is the gnu debugger for C and C++ programs.

Last week we used gdb as a calculator and converter, but it is normally used to help debug programs.

Over the course of the semester will will explore gdb features in more depth, but today we will learn just a few basics so that you can start using gdb to help you debug your C lab assignments.

To use the debugger, you usually want to compile your C program with the -g flag to add debugging information to the a.out file (this allows gdb to map binary machine code to C program code that the programmer understands).

The Makefile already has this rule for us, so let’s just run make .

Next, we will run the executable file inside the gdb debugger:

The first thing we get is the gdb prompt. At this point testprog has not yet started running.

We usually begin a debugging session by setting a break point at main before starting the program running in gdb. A breakpoint tells gdb to grab control at a certain point in the execution, in this case right before the first instruction in main is executed:

Next, we will enter the run command at the gdb prompt to tell gdb to start running our program:

The run command will start your program running, and gdb will only gain control again when a breakpoint is hit.

There are a few other primary gdb commands we will learn today. The first is the list command that displays the C source code around the point where we are in the execution:

list with a line number lists the source code around that line:

The next command (or just n as a shortcut) tells gdb to execute the next instruction and then grab control again:

The print command can be used to print out the value of a program variable or expression:

cont tells gdb to let the program continue running. Since we have no more breakpoints it will run until termination.

Now let’s add a breakpoint in the function mystery , and rerun the program:

The run command starts the program’s execution over from the beginning. When re-run, the breakpoint at the beginning of the main function will be hit first (and list displays the code around the breakpoint).

Let’s set a breakpoint at line 20, right before the call to mystery. Next, type cont to continue execution from breakpoint in main:

The program continues running until it reaches the breakpoint we just set at line 20 (Breakpoint 3). We can examine the program’s execution state at line 20 by printing out the argument values before the call to mystery (using print ), and then type cont to continue the program’s execution:

After continuing, the breakpoint in mystery is hit next (Breakpoint 2), let’s step through some of the mystery function’s execution, and print out some of its parameters and locals.

We can use the print command to print out expressions in the program, so let’s print out the values of the arguments passed to mystery, and type cont to run until the next break point is hit:

The where or bt command list the call stack:

When you’re done using gdb , type the command quit .

If you use gdb to help you debug the lab this week, you will need to give the run command a command-line argument that is the file name:

In general, for programs with command line arguments, simply list the arguments after the run command, for example to run with 3 command line arguments (6, 4, and hello), do the following:

We will learn more about C and gdb over the course of the semester, but these gdb basics are enough to start using gdb to help you debug your C programs.

Lets talk through the next Lab 2 Assignment , where you will implement a C program that, among other things, uses arrays, command line arguments, and reads values in from a file.

GitHub Org for CS31

Using Git for CS31

Git help page and GitHub one time setup steps

C code style guide

C programing resources

Compiling and running C programs on our system

C Compiling and Debugging Guide

Chapter 1 and Chapter 2 on C programming in course textbook

Chapter 3 on gdb

Some Useful Unix Commands

vi (and vim) quick reference

CS Department Using Unix

"Hello World!" in C Easy C (Basic) Max Score: 5 Success Rate: 85.68%

Playing with characters easy c (basic) max score: 5 success rate: 84.44%, sum and difference of two numbers easy c (basic) max score: 5 success rate: 94.64%, functions in c easy c (basic) max score: 10 success rate: 96.03%, pointers in c easy c (basic) max score: 10 success rate: 96.62%, conditional statements in c easy c (basic) max score: 10 success rate: 96.94%, for loop in c easy c (basic) max score: 10 success rate: 93.79%, sum of digits of a five digit number easy c (basic) max score: 15 success rate: 98.66%, bitwise operators easy c (basic) max score: 15 success rate: 94.99%, printing pattern using loops medium c (basic) max score: 30 success rate: 95.95%, cookie support is required to access hackerrank.

Seems like cookies are disabled on this browser, please enable them to open this website

Pardon Our Interruption

As you were browsing something about your browser made us think you were a bot. There are a few reasons this might happen:

  • You've disabled JavaScript in your web browser.
  • You're a power user moving through this website with super-human speed.
  • You've disabled cookies in your web browser.
  • A third-party browser plugin, such as Ghostery or NoScript, is preventing JavaScript from running. Additional information is available in this support article .

To regain access, please make sure that cookies and JavaScript are enabled before reloading the page.

« Back to the main CS 300 website

Lab 1: C Programming and Makefiles

  • Due February 2, 2021, at 8:00PM AoE

:warning:

1. Completed Lab 0 – This will ensure that your VM and grading server account are set up properly. 2. Completed the Diversity Survey – Your grades for Lab 0 and Lab 1 will depend on whether you’ve submitted this (though all questions are optional).

  • Introduction

The purpose of this lab is to give you some experience with writing and understanding the syntax of C programs and apply the tools used to compile and run them. After this lab, you will also be more familiar with pointers and why C and C++ use them.

If you take away anything from this course, hopefully, it’s that Computer Systems are not magic and that much of it actually makes a lot of sense. Don’t be afraid to look up questions on Stack Overflow and Linux Man Pages (which provide great documentation on C library functions), and if that doesn’t help, ask on Piazza!

Check out this article for more on why C programming is awesome! Here are some of the article’s highlights: C is an imperative programming language that was mainly developed as a systems programming language to write operating systems. The main features of the C language include low-level access to memory, a simple set of keywords, and clean style, these features make C suitable and widely-used for system programming.

If you are looking for a detailed tutorial on C, check out the links on our C primer .

  • Assignment Installation

Start with the cs300-s21-labs-YOURNAME repository you used for Lab 0.

First, ensure that your repository has a handout remote. Type:

If this reports an error, run:

This will merge our Lab 1 stencil code with your previous work. If you have any “conflicts” from Lab 0 (although this is unlikely), resolve them before continuing further. Run git push to save your work back to your personal repository.

Assignment Part I: C Programming

After you set up the lab, you should find within the lab1 folder a couple of files:

File Description
Header file for . Contains declarations for the functions you should be implementing. More information about this file is in the file itself.
You will be writing your code in this file.
Contains the test suite in which your implementation will be tested.

In this part of the lab, you will be writing a program that will reverse an array of strings (or, as they are known in C, char pointers). You will be writing two functions in the file reverse.c and you will test your implementation with the code found in test_reverse.c .

  • Review of pointers and strings

Pointers are memory locations that store addresses (i.e., they “point” at whatever is at that address!). For instance, int* is a pointer to an integer. On a 64-bit architecture (which most computers today use), the pointer occupies 8 bytes in memory, which store the address it points. And that address refers to the first byte of a 4-byte sequence of memory that stores an int .

As you will notice, there isn’t an explicit data type called “string” in C. That’s because strings in memory are just a sequence of one bytes, each represented as a char (a 1-byte value). Instead of having a datatype explicitly called “string”, in C, you can think of char pointers (i.e., char* ) as strings.

Since store is defined as a char pointer, store will point to a byte of memory that stores a character. And if you increment the value of the pointer by 1 (going to the next box) and dereference that value, you would get the next character of the string. This raises the question: couldn’t you just keep incrementing this pointer? How would you know where the end of the string is?

The answer: all strings in C are terminated by a NUL byte (a char storing numeric value 0), also known as \0 . This byte indicates that you have reached the end of the string.

Consider the following memory layout for the example program above:

Now think through what happens at each iteration of the loop:

  • if i == 0 , then *(store + 0) dereferences the memory address stored in store , which is 0x2000 , and at address 0x2000 , the character “h” is stored as a single byte. This is equivalent to writing store[0] .
  • if i == 1 , then *(store + 1) dereferences the memory address stored in store + 1 , which is 0x2001 . At 0x2001 , there is the character “e”. This is equivalent to writing store[1] .

What you saw here is an example of pointer arithmetic , that is, arithmetic on memory addresses.

  • Let’s get coding!

Task: You will be writing two functions in the file reverse.c :

  • Note : you can assume that you will have the same number of elements in the array as specified by the second argument, and you will not have to reverse an empty array and all elements will be defined (i.e., not NULL ).
  • swap will take in two elements from the array and swap them. Note : Remember that pointers are also passed by value as an argument to a function, meaning a copy of the address is passed. Thus, if you make changes to the value of the pointer, the address to which the pointer points changes (rather than the memory object that the pointer points to). Since the address value is copied when passing a pointer, changes to the address will not be reflected outside that function.
  • Running and Testing

Once you have finished writing your code, you are ready to test your implementation!

To test your code, we provide a file called test_reverse.c which calls reverse_arr , which you implemented in reverse.c . In order to run it, you must compile it and link the two files together into an executable by running the following command:

This generates an executable called reverse_test . An executable is a special file that contains machine instructions which are made up of machine instructions encoded as 0s and 1s. And running this file causes the computer to perform those instructions.

In this case, those instructions are to run the program starting from main() , which first parses input from the command line, reverses the array given, and calls functions that run the tests found in test_reverse() . (One of the tests will open a file called test.txt in the current directory, reverses each line of the file, and writes it to an output file called testout.txt. )

You run your executable via:

For instance:

will print out the results of reversing the input array and running the test suite. If you fail a test, the output provides the expected result at a given index in the array and the actual result.

To debug, you may find it helpful to print what’s happening in your swap and reverse_arr function. For instance, if you wanted to print the variable store from the code sample above, you can do:

Hint : If you want to print out the value of a pointer, use the %p syntax for printf.

Once all of your tests pass, you are ready to move on!

Assignment Part II: More on Compiling

As your saw from the previous section, you compiled your program by running:

With the -o flag, you can direct the output of the gcc compiler into a file specified by the argument following the flag. If you didn’t use the -o flag, you could run:

And this will produce an executable file called a.out (this is just a default filename defined by the compiler), which you can run by typing ./a.out .

The gcc compiler supports the use of hundreds of different flags, which we can use to customize the compilation process. Flags, typically prefixed by a dash or two ( -<flag> or --<flag> ), can help us in many ways from warning us about programming errors to optimizing our code so that it runs faster.

The general structure for compiling a program with flags is:

Warning Flags:

  • Uninitialized and unused variables
  • Incorrect return types
  • Invalid type comparisons
  • The -Werror flag forces the compiler to treat all compiler warnings as errors, meaning that your code won’t be compiled until you fix the errors. This may seem annoying at first, but in the long run, it can save you lots of time by forcing you to take a look at potentially problematic code.
  • Assert statements that always evaluate to true because of the datatype of the argument
  • Unused function parameters (only when used in conjunction with -Wall )
  • Empty if/else statements.

Task : Add the -Wall , -Werror , and -Wextra flag when compiling test_reverse.c and fix the errors that come up. Notice that in test_reverse.c the main() function takes in two parameters:

  • argc indicates the number of arguments passed into the program.
  • argc == 1 then only the test suite should be executed
  • The number of elements to be reversed
  • The elements to be reversed
  • For example: ./reverse_test 2 csci 300
  • For example: ./reverse_test 2 csci should cause an error
  • Make sure to return 1 from main on an error, so that the OS can detect that your program exited with errors.

Debugging with Sanitizers: The warning flags don’t catch all errors. For example, memory leaks, stack or heap corruption, and cases of undefined behavior are often not detected by the compiler. You can use sanitizers to help with identifying these bugs! Sanitizers sacrifice efficiency to add additional checks and perform analysis on your code. You will be using these flags in the next lab in greater detail.

-fsanitize=address

  • This flag enables the AddressSanitizer program, which is a memory error detector developed by Google. This can detect bugs such as out-of-bounds access to heap / stack, global variables, and dangling pointers (using a pointer after the object being pointed to is freed). In practice, this flag also adds another sanitizer, the LeakSanitizer, which detects memory leaks (also available via -fsanitize=leak ).

-fsanitize=undefined

  • This flag enables the UndefinedBehaviorSanitizer program. It can detect and catch various kinds of undefined behavior during program execution, such as using null pointers, or signed integer overflow.
  • This flag requests the compiler to generate and embed debugging information in the executable, especially the source code. This provides more specific debugging information when you’re running your executable with gdb or address sanitizers. You will see this flag being utilized in the next lab.

Optimizations In addition to flags that let you know about problems in your code, there are also optimization flags that will speed up the runtime of your code at the cost of longer compilation times. Higher optimization levels will optimize by running analyses on your program to determine if the compiler can make certain changes that improve its speed. The higher the optimization level, the longer the compiler will take to compile the program, because it performs more sophisticated analyses on your program. These are the capital O flags, which include -O0 , -O1 , -O2 , -O3 , and -Os .

  • This will compile your code without optimizations — it’s equivalent to not specifying the -O option at all. Because higher optimization levels will often remove and modify portions of your original code, it’s best to use this flag when you’re debugging with gdb or address sanitizers.
  • This will enable the most aggressive optimizations, making your code run the fastest.

Task : Time your program before you add the -O3 flag and then after you’ve added the -O3 flag to your compilation. Because this program is so small, you probably won’t be able to detect a difference in speed, but in future assignments where there is a lot more code, the optimization flag will come in handy. The -O3 flag will ask the compiler to examine what your code is trying to do and rather than following the provided code verbatim it will replace it with machine instructions that functionally do the same thing, but in a more efficient manner. You can time your program by running the time command in your vagrant instance. For this exercise, pay attention to the real time, but if you’re curious about the different types of times below, check out this post .

  • Assignment Part III: Makefiles

Now you know how to compile C programs! This is great, but actual software projects rarely require you to invoke the compiler directly like we did so far. Often (e.g., in the CS 300 projects!) you need to compile many source files and use specific sets of flags. It’s very easy to forget a flag or source file, and doing this all by hand on the command line is time-consuming. Additionally, when you have many source files (more than 2), it can be annoying to individually recompile/relink each source file when you make a change to it.

This is why the make tool was created! Running the make tool will read a file called the Makefile for specifications on how to compile and link a program. A well-written Makefile automates all the complicated parts of compilation, so you don’t have to remember each step. Additionally, they can do tasks other than just program compilation — they can execute any shell command we provide.

In this part of the lab, you will be writing a Makefile to use when compiling your reverse array program.

A Makefile consists of one or more rules. The basic structure of a Makefile rule is:

  • The target is the name of an output file generated by this rule, or a rule label that you choose in certain special cases.
  • The dependencies are the files or other targets that this target depends on.
  • The shell command is the command you want to run when the target or dependencies are out of date.
  • From gnu.org : A target is out of date if it does not exist or if it is older than any of the dependencies (by comparison of last-modification times). The idea is that the contents of the target file are computed based on information in the dependencies, so if any of the dependencies changes, the contents of the existing target file are no longer necessarily valid.
  • If a target is out of date, running make <target> will first remake any of its target dependencies and then run the <shell_command> .
  • In general, the name of the Makefile target should be the same as the name of the output file, because then running make <target> will rebuild the target when the output file is older than its dependencies.

Linking is the process of combining many object files and libraries into a single (usually executable) file. If you look at the file test_reverse.c , at the top, you can see there is an #include “reverse.h” . This is so that we can use the functions that you wrote to test them, and as you can see, reverse_arr is called in the function test_reverse . You can link these two files together with the following Makefile rule:

The target is the executable named reverse_test, the dependencies are test_reverse.c , reverse.c , and reverse.h . And to compile, instead of typing the shell command, you can just type:

This will cause the Makefile to run the reverse_test target, which will execute the command gcc test_reverse.c -o reverse_test if a reverse_test executable doesn’t exist or if the reverse_test executable is older than any of the dependencies. Notice how this only works properly if the name of the output executable is the same as the target name.

That was a lot of reading and information, but now you are ready to create your own Makefile!

  • Create an empty Makefile by typing touch Makefile in your lab directory.
  • Modify your Makefile so that it has one target, reverse_test , that will compile reverse.c and test_reverse.c .
  • Run make reverse_test to make sure it compiles successfully. (You may need to delete the reverse_test binary via rm -f reverse_test to make this work.)

Note : Don’t worry about errors with the ‘modification time’ or ‘clock’. These occur because the clock in your VM’s internal clock differs from your actual machine’s clock, but shouldn’t cause any big issues with our compilation process.

Makefiles support defining variables, so that you can reuse flags and names you commonly use. MY_VAR = "something" will define a variable that can be used as $(MY_VAR) or ${MY_VAR} in your rules. A common way to define flags for C program compilation is to have a CFLAGS variable that you include whenever you run gcc. For example, you can then rewrite your target like this:

Automatic Variables are special variables called automatic variables that can have a different value for each rule in a Makefile and are designed to make writing rules simpler. They can only be used in the command portion of a rule!

Here are some common automatic variables:

$@ represents the name of the current rule’s target. $^ represents the names of all of the current rule’s dependencies, with spaces in between. {{{html}}}lt; represents the name of the current rule’s first dependency.

If we wanted to stop using test_reverse.c and reverse.c to avoid repetitiveness, we could rewrite our target like this:

Task : Use regular variables (i.e. CFLAGS ) and automatic variables simplify your Makefile and add the -O3 flag. Note : you can do MY_VAR += <additional flags> if you want to compile with more flags and only use one variable.

Phony Targets

There are also targets known as ‘phony’ targets. These are targets that themselves create no files, but rather exist to provide shortcuts for doing other common operations, like making all the targets in our Makefile or getting rid of all the executables that we made.

To mark targets as phony, you need to include this line before any targets in your Makefile:

.PHONY: target1 target2 etc.

Why do we need to declare a target as phony?

  • To avoid a conflict with a file of the same name: We learned earlier that targets will only execute their <shell_command> if the target file is out-of-date. This is problematic because phony targets generally don’t create files under the target name. If somehow there exists a file under the same name as a phony target, the phony target’s command will never be run. You can avoid this by explicitly declaring a target as phony to specify to the make tool to rebuild the target even if it’s not “out-of-date”.
  • To improve performance: there’s also a more advanced performance advantage that you can learn more about here .

Here are some common phony targets that we’ll be using in this course:

all target We use the all target to make all of the executables (targets) in our project simultaneously. This is what it generally looks like:

all: target1 target2 target3

As you can see, there are no shell commands associated with the all target. In fact, we don’t need to include shell commands for all, because by including each target (target1, target2, target3) as dependencies for the all target, the Makefile will automatically build those targets in order to fulfill the requirements of all.

In other words, since the all target depends on all the executables in a project, building the all target causes make to first build every other target in our Makefile.

clean target We also have a target for getting rid of all the executables (and other files we created with make) in our project. This is the clean target.

The clean target generally looks like this:

As you can see, the clean target is fundamentally just a shell command to remove all the executables and object files that we made earlier. By convention, the clean target should remove all content automatically generated by make. It must be a phony target, because by definition, make clean doesn’t generate output files (but rather removes them)!

Note : Be careful which files you put after the rm -f command , as they will be deleted when you run make clean. Don’t put your .c or .h files because you might lose the code that you wrote!

format target In this class, you will notice that all of the Makefiles will also contain a format target, which use a command called clang-format to style your .c and .h files following a specified standard. A typical format command would look like this:

The above command will format any listed files according to Google’s coding conventions (a set of stylistic and technical conventions that Google engineers agreed to use).

Note : When using this, keep in mind the order of your #include files. Formatting might change the order of include statements. This is something to consider if, for example, you are importing a header file that relies on standard libraries from the file you’re importing it in. To avoid this, make sure that your header files are self-contained (i.e., include all the headers they need).

check target You’ll also notice a check target in the Makefiles we provide in future labs and projects. If you were to create a check target in this particular instance, the dependency for the check target is the reverse_test executable.

Task : Add all , clean , and format targets to your Makefile.

  • Running make without any targets will run the first target in your Makefile. Consequently, you should place the all target as the first target so that typing make will automatically generate all the executables.
  • Don’t forget to mark these targets as phony!

Simplifying Linking

It is often a good idea to break compilation of a large program into smaller sub-steps. Consider, for example, this command you used earlier:

gcc test_reverse.c reverse.c -o reverse_test

For this program, gcc creates two separate .o files, one for test_reverse.c and one for reverse.c and then links them together. But what if you had hundreds of source files?

Large vs. Small Projects: For small projects, the above works well. However, for large projects it can be much faster to generate intermediate .o files (so-called “object files”) and then separately link the .o files together into an executable. Linking is the process of combining multiple object files (which already contain machine code, but not a full program) into a full executable program.

Why does this make sense? Imagine a project that generates two shared libraries and four executables, all of which separately link a file called data.c . Let’s say the data.o file takes 1 second to compile. If you compile and link each executable in one command (without creating intermediate .o files), gcc will rebuild the data.o file five times, resulting in 5 seconds of build time. If you separately build the data.o file, you’ll build the data.c file only once (taking 1 second) and then link it (which is much faster than compiling from scratch, especially with large source files). So, if linking takes 0.2 seconds per file, the total build time will be 2 seconds instead of 5 seconds.

Although this technique won’t yield a huge performance benefit in the case of our small lab, let’s try this to drive the concept of linking home! We can then use our Makefile to automate this process for us, so that we don’t have to regenerate all object and source files every time we edit one of them.

To do this, we need to first generate object files for each file, containing the machine instructions. Then we need to link these programs together into one executable.

To create the object files without linking them, we use the -c flag when running gcc. For example, to create object files for test_reverse.c and reverse.c , we would run:

This will generate reverse.o and test_reverse.o files. Then, to link the object files into an executable, we would run:

gcc test_reverse.o reverse.o -o <executable name>

The advantage of creating object files independently is that when a source file is changed, we only need to create the object file for that source file. For example, if we changed reverse.c , we would just have to run gcc -c reverse.c -o reverse.o to get the object file, and then gcc reverse.o test_reverse.o instead of also regenerating test_reverse.o to get the final executable.

Task: In your Makefile, create targets for test_reverse.o and reverse.o , that each include the corresponding source file as a dependency.

  • Each of these targets should compile their source file into an object file (not an executable). They also need their correct flags for optimization and debugging.
  • Update your reverse_test targets to use the .o flags.
  • Update your clean and format targets.
  • Thanks to this, make will only recompile each individual object file if that file’s source was changed. It may not make the biggest difference for this lab, but in a larger project doing this will save you lots of time.

Pattern Rules

The last Makefile technique we’ll discuss are pattern rules. These are very commonly used in Makefiles. A pattern rule uses the % character in the target to create a general rule. As an example:

The % will match any non empty substring in the target, and the % used in dependencies will substitute the target’s matched string. In this case, this will specify how to make any file_<name> executable with another file called <name>.c as a dependency. If <name>.c doesn’t exist or can’t be made, this will throw an error.

As you may have noticed, both the test_reverse.o and reverse.o targets are running the same command, which means that we can simplify it.

Task : Use pattern rules to simplify your Makefile targets such that you can generate reverse.o and test_reverse.o using only one rule rather than two seperate rules. If you need help, this documentation might help.

  • Handin instructions

Turn in your code by pushing your git repository to csci0300-s21-labs-YOURUSERNAME.git .

Then, head to the grading server . On the “Labs” page, use the “Lab 1 checkoff” button to check off your lab.

Browse Course Material

Course info, instructors.

  • Daniel Weller
  • Sharat Chikkerur

Departments

  • Electrical Engineering and Computer Science

As Taught In

  • Programming Languages
  • Software Design and Engineering

Learning Resource Types

Practical programming in c, lab 1: game of life.

Lab assignment to implement John Conway’s Game of Life as a C program.

facebook

You are leaving MIT OpenCourseWare

Project #0 - C++ Primer Last Updated: Jan 22, 2024

Do not post your project on a public Github repository.

All the programming projects this semester will be written on the BusTub database management system. This system is written in C++. To make sure that you have the necessary C++ background, you must complete a simple programming assignment to assess your knowledge of basic C++ features. You will not be given a grade for this project, but you must complete the project with a perfect score before being allowed to proceed in the course. Any student unable to complete this assignment before the deadline will be asked to drop the course.

All of the code in this programming assignment must be written in C++. The projects will be specifically written for C++17, but we have found that it is generally sufficient to know C++11. If you have not used C++ before, here are some resources to help:

  • 15-445 Bootcamp , which contains several small examples to get you familiar with C++11 features.
  • Learncpp is a useful resource that includes quizzes to test your knowledge.
  • cppreference has more detailed documentation of language internals.
  • A Tour of C++ and Effective Modern C++ are also digitally available from the CMU library.

If you are using VSCode, we recommend you to install CMake Tools , C/C++ Extension Pack and clangd . After that, follow this tutorial to learn how to use the visual debugger in VSCode: Debug a C++ project in VS Code .

If you are using CLion, we recommend you to follow this tutorial: CLion Debugger Fundamentals .

If you prefer to use gdb for debugging, there are many tutorials available to teach you how to use gdb . Here are some that we have found useful:

  • Debugging Under Unix: gdb Tutorial
  • GDB Tutorial: Advanced Debugging Tips For C/C++ Programmers
  • Give me 15 minutes & I'll change your view of GDB [VIDEO]

This is a single-person project that will be completed individually (i.e. no groups).

  • Release Date: Jan 16, 2024
  • Due Date: Jan 28, 2024 @ 11:59pm

Project Specification

In this project, you will implement an Observed Remove Set (OR-Set), a common Conflict-free replicated data type (CRDT) .

Imagine a group of friends is drafting a travel plan together on Google Docs. Everyone is typing, adding pictures, and striking off items all at once. But here's the cool part: there's no stepping on each other's toes. Every change, from a new destination to a deleted activity, seamlessly integrates into the document. This real-time, harmonious editing is the magic of CRDTs at play, transforming a potentially chaotic collaboration into a smooth, enjoyable experience.

In general, Conflict-Free Replicated Data Types (CRDTs) are data structures designed for distributed systems where multiple nodes operate independently without the need for immediate synchronization. These data structures can be updated independently and concurrently across multiple nodes, and still converge to the same state once all updates are propagated and processed. To this end, we need an abstraction with commutative , associative , and idempotent operations, then we could create a Merge method to "eventually" reconcile to a definitive final state.

The OR-Set is a specific type of CRDT that handles the addition and removal of elements in a set. In an OR-Set, each element added to the set is tagged with a unique identifier. When an element is removed, its identifier is moved to a "tombstone" set, instead of being completely deleted. This allows the system to track both the additions and deletions of elements, so we could re-add elements after deletion.

When a concurrent add and remove operation over the same element occur, one among several post conditions can be chosen: add-wins, remove-wins or an error mark. The OR-Set can also be called add-wins set since it always lets add operations win over remove operations. Therefore, the OR-Set always leads to a predictable state.

  • Short paper on the OR-Set. It contains the interface description in Figure 2.
  • If you want a gentler intro, check out this video (the link starts when they talk about sets, but start from the beginning if you want the full intro.)

Task #1 - OR-Set

In this task, you will need to modify orset.h and orset.cpp to implement an OR-Set. We suggest you to skim through the above short paper, especially section 4 (no need to implement the optimized version).

To implement add-wins semantics, the OR-Set distinguishes the different add operations on the same element by adding a unique token. This token is stored with the element as a tuple (e,n). Take a look at the GenerateUid() function in the orset_driver.h file to see how a unique token is generated.

ORset

Removals do not only modify the set of elements. Instead, you would also add the corresponding pair (e,n) to the tombstone set. (See figure below)

ORset

To merge a replica A is merged to a replica B: First, the elements are merged by removing the elements equal to the tombstones from replica B. Second, the set is united with the elements from B that are not included in the tombstones of the set A. After that, the tombstones are updated and therefore united with the tombstones of replica B (see figure below).

ORset

Your OR-Set must support five operations:

  • Contains(elem) : Checks if an element is in the set.
  • Add(elem, uid) : Adds an element to the set.
  • Remove(elem) : Removes an element from the set if it exists.
  • Merge(set) : Merge changes from another OR-Set.
  • Elements() : Gets all the elements in the set.

For the full specifications of these operations, please refer to the above short paper and the starter code. We intentionally left some design room for you to think about how to represent your element set and tombstone set. Your implementation should use two sets as in the above examples. Do not use one single std::unordered_set to implement it.

To test your OR-Set implementation, we provided the ORSetDriver and ORSetNode classes in orset_driver.h/cpp . * ORSetDriver serves as a mock for a large cluster in a CRDT, which is responsible for creating nodes and managing meta data for synchronization. Most importantly, it generates a globally unique identifier upon each OR-Set Node Add operation. * ORSetNode is a single node in this distributed system. It's essentially a wrapper around the ORSet you just implemented with methods to communicate with peers via the driver.

All test cases are public in the orset_test.cpp file.

Task #2 - SQL String Functions

Now it is time to dive into BusTub itself! You will need to implement upper and lower SQL functions. This can be done in 2 steps: (1) implement the function logic in string_expression.h . (2) register the function in BusTub, so that the SQL framework can call your function when the user executes a SQL, in plan_func_call.cpp .

To test your implementation, you can use bustub-shell :

Your implementation should pass all 3 sqllogictest test cases.

Note: If you see BufferPoolManager is not implemented yet. when running sqllogictest, this is normal and you can safely ignore this warning in project 0.

Instructions

Creating your own project repository.

If the below git concepts (e.g., repository, merge, pull, fork) do not make sense to you, please spend some time learning git first.

Follow the instructions to setup your own PRIVATE repository and your own development branch. If you have previuosly forked the repository through the GitHub UI (by clicking Fork), PLEASE DO NOT PUSH ANY CODE TO YOUR PUBLIC FORKED REPOSITORY! Make sure your repository is PRIVATE before you git push any of your code.

If the instructor makes any changes to the code, you can merge the changes to your code by keeping your private repository connected to the CMU-DB master repository. Execute the following commands to add a remote source:

You can then pull down the latest changes as needed during the semester:

Setting Up Your Development Environment

First install the packages that BusTub requires:

See the README for additional information on how to setup different OS environments.

To build the system from the commandline, execute the following commands:

We recommend always configuring CMake in debug mode. This will enable you to output debug messages and check for memory leaks (more on this in below sections).

You can test the individual components of this assignment using our testing framework. We use GTest for unit test cases. You can disable tests in GTest by adding a DISABLED_ prefix to the test name. To run the tests from the command-line:

In this project, there are no hidden tests. In the future, the provided tests in the starter code are only a subset of the all the tests that we will use to evaluate and grade your project. You should write additional test cases on your own to check the complete functionality of your implementation.

Make sure that you remove the DISABLED_ prefix from the test names otherwise they will not run!

Your code must follow the Google C++ Style Guide . We use Clang to automatically check the quality of your source code. Your project grade will be zero if your submission fails any of these checks.

Execute the following commands to check your syntax. The format target will automatically correct your code. The check-lint and check-clang-tidy targets will print errors that you must manually fix to conform to our style guide.

Memory Leaks

For this project, we use LLVM Address Sanitizer (ASAN) and Leak Sanitizer (LSAN) to check for memory errors. To enable ASAN and LSAN, configure CMake in debug mode and run tests as you normally would. If there is memory error, you will see a memory error report. Note that macOS only supports address sanitizer without leak sanitizer .

In some cases, address sanitizer might affect the usability of the debugger. In this case, you might need to disable all sanitizers by configuring the CMake project with:

Development Hints

You can use BUSTUB_ASSERT for assertions in debug mode. Note that the statements within BUSTUB_ASSERT will NOT be executed in release mode. If you have something to assert in all cases, use BUSTUB_ENSURE instead.

We will test your implementation in release mode. To compile your solution in release mode,

Post all of your questions about this project on Piazza. Do not email the TAs directly with questions.

TAs will not look into your code or help you debug in this project.

The instructor and TAs will not teach you how to debug your code.

Grading Rubric

In order to pass this project, you must ensure your code follows the following guidelines:

Note that we will use additional test cases to grade your submission that are more complex than the sample test cases that we provide you in future projects.

Late Policy

There are no late days for this project.

You will submit your implementation to Gradescope:

  • https://www.gradescope.com/courses/674039

Run this command in build directory and it will create a zip archive called project0-submission.zip that you can submit to Gradescope.

Although you are allowed submit your answers as many times as you like, you should not treat Gradescope as your only debugging tool. Most students submit their projects near the deadline, and thus Gradescope will take longer to process the requests. You may not get feedback in a timely manner to help you debug problems. Furthermore, the output from Gradescope is unlikely to be as informative as the output from a debugger (like gdb ), provided you invest some time in learning to use it.

CMU students should use the Gradescope course code announced on Piazza.

Collaboration Policy

  • Every student must work individually on this assignment.
  • Students are allowed to discuss high-level details about the project with others.
  • Students are not allowed to copy the contents of a white-board after a group meeting with other students.
  • Students are not allowed to copy solutions from another person.
  • In this project, you are allowed to search on Google or ask ChatGPT high-level questions like "what is CRDT", "how to use std::move ".

WARNING: All of the code for this project must be your own. You may not copy source code from other students or other sources that you find on the web. Plagiarism will not be tolerated. See CMU's Policy on Academic Integrity for additional information.

IMAGES

  1. SOLUTION: Lab assignment on c language programming practice questions

    lab assignment c programming

  2. C Programming Lab Course

    lab assignment c programming

  3. Compound Assignment Operators in C Programming Language

    lab assignment c programming

  4. Assignment Operators in C with Examples

    lab assignment c programming

  5. Lab Assignments Solutions of C++

    lab assignment c programming

  6. Clab3

    lab assignment c programming

COMMENTS

  1. C Programming Exercises, Practice, Solution

    C programming Exercises, Practice, Solution: C is a general-purpose, imperative computer programming language, supporting structured programming, lexical variable scope and recursion, while a static type system prevents many unintended operations.

  2. C Exercises

    C Exercises for Beginners and Advances: Level up your C programming skills step-by-step with hands-on practice questions. Practice and learn syntax, loops, functions, and more through rewarding C programming exercises.

  3. Comprehensive C Programming Lab Report Repository

    Description Welcome to the Comprehensive C Programming Lab Report Repository, curated by jrTilak. This repository is designed to provide a comprehensive collection of solutions for the C Programming lab assignments, covering various topics and concepts. Whether you are a student studying at Tribhuvan University's Institute of Engineering or an aspiring programmer, this repository is a valuable ...

  4. Labs

    This section provides the lab assignments, supporting files, solutions, and a description of the final project for the course.

  5. Assignments

    This section provides the course assignments, supporting files, and solutions.

  6. C programming exercises: Function

    3. Write a program in C to swap two numbers using a function. Test Data : Input 1st number : 2 Input 2nd number : 4 Expected Output : Before swapping: n1 = 2, n2 = 4 After swapping: n1 = 4, n2 = 2. Click me to see the solution. 4. Write a program in C to check if a given number is even or odd using the function.

  7. Problem Set 1

    Problem set on writing, compiling, and debugging C programs, preprocessor macros, the C file structure, variables, functions and program statements, and returning from functions.

  8. C Examples

    The best way to learn C programming is by practicing examples. The page contains examples on basic concepts of C programming. You are advised to take the references from these examples and try them on your own.

  9. Practice C

    Practice C. Improve your C programming skills with over 200 coding practice problems. Solve these beginner friendly problems online to get better at C language. Please login to see the progress.

  10. Lab 1: C Programming and Makefiles

    Assignment Part I: C Programming In this part of the lab, you will be writing a program that will reverse an array of strings (or, as they are known in C, char pointers).

  11. Learn C Programming

    Learn C Programming. C is one of the foundational programming languages used in the development of compilers, operating systems, and embedded systems where speed and efficiency matter. It is considered the best language to start because it provides a strong understanding of fundamental coding concepts like data types, variables, loops, and ...

  12. Lab 1: Writing and Debugging C Programs

    Introduction. The purpose of this lab is to give you some experience with the syntax and basic features of the C programming language, as well as introduce you to a C debugging tool called gdb (GNU Debugger). Learning C will help you understand a lot of the underlying architecture of the operating system, and as a whole demystify how programs run.

  13. PDF Programming with C

    Programming with C - Lab Prepared by IT & CSE Page 9 The commonly used high level languages are FORTRAN, BASIC, COBOL, PASCAL, PROLOG, C, C++, JAVA etc. The complete instruction set written in one of these languages is called a high level language program or computer program or source program.

  14. Lab 1: Introduction to C

    In this week's lab, you will: Learn about the C programming toolchain we use in the rest of the course. Learn to write simple C programs. Practice using getchar, putchar and printf for terminal I/O, as well as command line program arguments. Learn about C pointers, and how to implement pass by reference using them.

  15. C Programming Language Tutorial

    What is C? C is a general-purpose, procedural, high-level programming language used in the development of computer software and applications, system programming, games, and more.

  16. C All Exercises & Assignments

    Learn C programming with exercises and assignments on various topics. Tutorials Class helps you master C skills with solutions and examples.

  17. PDF C Programming Lab Manual

    Welcome to C programming Lab. For the practical works of C programming, you have to complete at least eight to ten lab activities throughout the course. These lab sheets will guide you to prepare for programming and submission of lab reports. Further, it helps you to understand practically about the knowledge of programming.

  18. Practical Programming in C

    Daily programming assignments and weekly laboratory exercises are required. Knowledge of C is highly marketable for summer internships, UROPs, and full-time positions in software and embedded systems development.

  19. CS 31 In-Lab Assignment 02

    Lets talk through the next Lab 2 Assignment, where you will implement a C program that, among other things, uses arrays, command line arguments, and reads values in from a file.

  20. Solve C

    Practice C programming skills and solve real-world problems on HackerRank, the leading platform for competitive coding.

  21. Lab 10 Assignment (pdf)

    The University of Michigan Electrical Engineering & Computer Science EECS 281: Data Structures and Algorithms Spring 2024 Lab 10: Algorithm Families and Dynamic Programming Instructions: Work on this document with your group, then enter the answers on the canvas quiz. Note: This lab assignment contains a survey, multiple choice quiz, and coding portion.

  22. Lab 1: C Programming and Makefiles

    Assignment Installation Start with the cs300-s21-labs-YOURNAME repository you used for Lab 0. First, ensure that your repository has a handout remote. Type:

  23. C Programming Lab Practical progams

    All programs related to programming exercises. C programming language lab manual for programming in lab 304s) 3rd semester diploma in computer science

  24. Lab 1: Game of Life

    Lab assignment to implement John Conway's Game of Life as a C program.

  25. Project #0

    All the programming projects this semester will be written on the BusTub database management system. This system is written in C++. To make sure that you have the necessary C++ background, you must complete a simple programming assignment to assess your knowledge of basic C++ features.