Assignment 1 - Getting Started With C, Part 1
Due: Wednesday, September 18, at 4:00pm
Starter code: a1.c
Upload solutions via Gradescope as: a1.c
Goals
This assignment is designed to help you with the following:
- learning some of the fundamentals of C programming
- starting thinking of your data in terms of bytes
- getting used to using some simple program testing automation
Collaboration policy
For this first assignment, you may work alone or with a partner, but you must type up all of the code yourself. (It is therefore unexpected for two code submissions to be completely identical.)
You may also discuss the assignment at a high level with other students.
You should list any student with whom you discussed the assignment, and the manner of discussion (high level, partner, etc.) in comments at the top of your C source file(s).
If you work alone, you should say so instead.
Assessment
To demonstrate proficiency, your submission needs to:
- pass the simple autograder tests for Parts A and B (these have names starting with
"_P"
) - be somewhat well-styled
To demonstrate mastery, your submission needs to:
- demonstrate proficiency
- pass all autograder tests
- be quite well-styled, particularly with well-chosen variable names, naming all magic numbers, and good identation
- have a well-chosen algorithm (i.e., don’t over-complicate this task!)
- have thorough error-handling
- include your name and collaboration statement at the top of your C source file(s)
Learning a new language
The following is taken from Jeff Ondich’s guidance on learning a new language, with minor adaptations.
Once you have learned a couple of programming languages, getting started in a new language is mostly a matter of finding good reference materials, getting a source of sample programs, and writing a bunch of small programs to get the syntax and core libraries under control.
An approach to this involves writing a few small programs, to make sure you can handle the basics. You could just do the first 10 programs at Project Euler. Instead, you could ramp up faster by writing programs specifically aimed at teaching yourself key elements of the new language. For example:
- Output: Write a “Hello, world!” program to print a simple text message to standard output.
- Input: Write a program that asks the users for their names, age in years, and some non-integer number (e.g., their hourly wage), and prints the information back.
- A function: Write a recursive factorial function as an example of a function that takes an integer parameter and returns an integer.
- Arithmetic and conditionals: Write a change-making program. Here’s a description of such a program as assigned to a CS 111 class many years ago.
- Input/output parameters: Write a function that takes two parameters and swaps them. Whether this is possible depends on whether the programming language supports pass-by-reference or pointers.
- File input, loops, and command-line-arguments: Read the contents of one text file and write the same contents, in all uppercase, to a second text file. Both the input and the output file names should be specified as command-line arguments.
- Lists/arrays: Given a text file consisting of one word on each line, read in the list of words, sort them into alphabetical order, and print the sorted list. Let the user specify the text file as a command-line argument.
- String manipulation and searching: Count the number of times each word in a text file appears. Print the results sorted in decreasing order by word count. Let the user specify the text file as a command-line argument.
- Dictionaries/hash tables: Do the word-counting exercise mentioned in the “string manipulation” item above, but keep track of the counts using a hash table (also known as a
dictionary
in some languages, including Python). This should run much faster than the one using lists, especially on large files with many unique words. - Classes: If your language has some form of object orientation (which C does not!), create a class called
Circle
with instance variables to keep track of the center and radius of a circle. The class should have a suitable constructor (or constructors), plus methodsgetArea
,getCircumference
, and a collection of appropriate accessors. Your program should read a list of circles from a text file whose lines consist of three numbers separated by spaces (e.g., “3.2 4 2.7
” represents a circle of radius2.7
centered at the coordinate(3.2, 4)
), instantiating aCircle
object for each one. Once you have a list ofCircle
objects, run through the list reporting the center, radius, area, and circumference of each circle. Let the user specify the file of circle data as a command-line argument. - Pointers, references, and memory allocation: Read a list of integers from a file into a linked list of your own construction. Sort the linked list (insertion sort and merge sort both work well with linked lists) and print the sorted list. Let the user specify the file as a command-line argument.
After getting these basics under control, you can start exploring the language’s standard libraries. For example, it is useful to know more about string manipulation, the file system (how to create/delete/move files, traverse a directory tree, etc.), simple GUIs and line graphics, invoking other programs, networking, etc. However, this is a longer-term project. If you have a good personal project (or class assignment!) to work on, most of these libraries come up naturally.
Assignment overview
For this first assignment, you will write a short C program to play around with char
s. This program is divided into four functions (you shouldn’t modify main()
at all!):
-
find_highest_char
: finds the highest-valued character in achar
array -
find_lowest_char
: finds the lowest-valued character in achar
array -
find_most_common_char
: finds the most common character in achar
array -
print_results
: prints out statistics from the previous three function calls
For this program, we’ll be interpreting the “value” of a char using ASCII, which maps decimal numbers to characters. For example:
- the number
36
corresponds to the character'$'
65
-90
map to uppercase letters'A'
through'Z'
97
-122
map to lowercase letters48
-57
correspond to'0'
through'9'
. You should interpret the “value” of a character as its decimal representation, which is a close enough approximation (for now) to what’s stored in the computer. You may assume that allchar
values in this assignment are between0
and127
(i.e., valid ASCII numbers).
Note that the functions for Parts A–C should each return -1
if the input array is empty (i.e., if n
has value 0
). Error handling of empty arrays is not required for demonstrating proficiency, but it is for mastery.
Getting the starter code
For this first assignment, you should download the a1.c
file from the top of this page. It has several functions marked // TODO
that you’ll need to fill in—here’s an example:
/*
* Find the highest-valued character in a character array,
* and returns that char. Returns -1 if the array is empty.
*
* arr: the character array
* n: the number of elements in the array (an int)
*/
char find_highest_char(char arr[], int n)
{
char highest = 0;
// TODO: Part A
return highest;
}
To get started on this first assignment:
-
Login to
mantis.mathcs.carleton.edu
using VS Code and open yourcs208
folder. Go back and look at Lab 0 if you have any questions about how to do this. -
Create a new folder named
a1
to store any files related to this assignment. Do this via the VS Code interface or the VS Code terminal:mkdir a1
-
Navigate (“change directory”) into your new folder, like this in the terminal:
cd a1
-
Either copy-paste the contents of
a1.c
into a new file in this folder, In your VS Code terminal, run:wget https://cs.carleton.edu/faculty/tamert/courses/cs208-f24/resources/assignments/a1.c
-
Look at the file to see what’s already there. Again, make sure not to modify the
main
function!
Testing your code
For some assignments in this course, I will give you simple tests. For this one, there are some example cases shown in the documentation at the top of the file:
/*
...
To compile this program:
gcc -Wall -Werror -g -o a1 a1.c
To run this program, you can specify 0 or 1 arguments:
./a1
./a1 welcomeback
./a1 "Hello there!"
*/
The first thing to do is try and compile it. You should do this from the VS Code terminal:
gcc -Wall -Werror -g -o a1 a1.c
You don’t need to understand this command right now. If it works, the terminal will just go to the next line, and you’ll be able to try running the program:
./a1
If that is successful, it should give you this output:
The string to parse is: "Supercalifragilisticexpialidocious"
Here is what that all looks like together in the terminal (note that $
is my terminal’s prompt; my typing automatically shows up just after it):
$ gcc -Wall -Werror -g -o a1 a1.c
$ ./a1
The string to parse is: "Supercalifragilisticexpialidocious"
Your assignment
Read through the code to see what each part needs to be able to do. If you don’t understand what a docstring says or what I’m looking for, just ask!
Proficiency
In order to demonstrate proficiency, you must complete Parts A and B, as well as enough of Part D to get the highest/lowest characters. Here are some examples (keep in mind that $
is the prompt at my terminal):
$ ./a1
The string to parse is: "Supercalifragilisticexpialidocious"
Highest: x (decimal value: 120)
Lowest: S (decimal value: 83)
$ ./a1 welcomeback
Highest: w (decimal value: 119)
Lowest: a (decimal value: 97)
$ ./a1 "Hello there!"
Highest: t (decimal value: 116)
Lowest: (decimal value: 32)
Note that your program must match these outputs exactly for the last couple of tests to pass.
Mastery
To demonstrate mastery, you must also complete Part C. This part requires implementing the function find_most_common_char
to determine the most-common character in the provided array. This may require some planning to design an algorithm that isn’t overly complex—hint: keep in mind that there are at most 128 possible values for each char in your input array (0
to 127
).
Here are the corresponding examples of the full output:
$ ./a1
The string to parse is: "Supercalifragilisticexpialidocious"
Highest: x (decimal value: 120)
Lowest: S (decimal value: 83)
Most Common: i (decimal value: 105)
$ ./a1 welcomeback
Highest: w (decimal value: 119)
Lowest: a (decimal value: 97)
Most Common: c (decimal value: 99)
$ ./a1 "Hello there!"
Highest: t (decimal value: 116)
Lowest: (decimal value: 32)
Most Common: e (decimal value: 101)
Again, your program must match these outputs exactly for the last couple of tests to pass. Note also that in the second example of welcomeback
, there is a tie: two e
s and two c
s, so the reported most-common character is c
, as the tie-breaker is to pick the lowest-ASCII-valued character in the event of a tie.
Note: Check the list at the top of this page to make sure you have everything you need (e.g., collaboration statement, good code style, etc.).
Submitting your work
You’ll need to follow these steps to submit your work:
-
Upload your
a1.c
file to Gradescope. -
Wait for the autograder to run.
-
Feel free to resubmit if the autograder points out an issue.
Advice
-
There are some really helpful examples on the Sample Programs page. Make sure to take a look and check your notes for any we specifically referenced in class!
-
Think ahead of time about error handling. What could go wrong? What should your program do if something bad happens? (For example, what if the input array is empty?)
-
This assignment is meant to help acclimate you to the process you’ll follow when submitting assignments in this course, and help you get familiar with C. If you are struggling, please reach out! Also, don’t be shy about experimenting and asking lots of questions!