CS100 · Fall 2026 · Programming Assignment

HW2: Bash, Git and C Programs

C17 · Online questions and Git submission on Gradescope

Released · 发布

Tue, Oct 13 · 20:00

⏰ Deadline · 截止

Thu, Oct 22 · 23:59

Download starter (ZIP)

Overview

HW2 consists of five problems on two Gradescope assignments. Problems 1 and 2 are online objective questions; Problems 3–5 are programming problems.

ProblemTopicGradescope assignmentPoints
Problem 1Basic knowledge II (C: pointers, UB, arrays)HW2_p1 (online questions)100
Problem 2Bash & Git (objective)HW2_p2 (online questions)100
Problem 3Polynomial evaluationHW2_programming100
Problem 4GCC argument descriptorHW2_programming100
Problem 5CPU emulatorHW2_programming100

Problems 1 and 2 are two separate online assignments (HW2_p1 and HW2_p2). The full statements of the programming problems are below. Read the Submission section carefully before your first upload.

P1

Basic knowledge II

100 pts · HW2_p1

Problem 1 is a set of online questions on the Gradescope assignment HW2_p1: single-choice and multiple-choice questions about undefined behavior, integer overflow, pointers, arrays and selection sort in C.

Answer the questions directly on Gradescope. Each question is graded all-or-nothing (a multiple-select question is correct only if your selection matches exactly). Your score is visible immediately after submission, and you may resubmit as many times as you like until the deadline; the latest answers count.

P2

Bash & Git

100 pts · HW2_p2

Problem 2 is a separate online assignment, HW2_p2, covering the command-line and version-control skills from the recitations:

Bash (Recitation 1): common commands (ls, cd, cp, rm, mkdir, touch), output redirection (>, >>) and pipes (|), and file permissions (rwx, chmod).

Git (Recitation 3): the local workflow (git add / commit / status / log), branches and merges, undoing changes (git reset), and working with remotes (clone, push, pull, fetch) — including a few fill-in-the-blank commands.

Already submitted HW2_p1? Your answers are untouched — Problem 2 is a separate assignment (HW2_p2). Simply open HW2_p2 and answer the questions there.

P3

Polynomial evaluation

100 pts · HW2_programming

Given a polynomial P(x) of degree n

P(x) = a₀ + a₁x + ⋯ + aₙxⁿ = Σ aᵢxⁱ  (i = 0..n)

we want to evaluate the polynomial at several points x0, x1, …, xm−1.

Input format

On the first line, a nonnegative integer n, which is the degree of the polynomial.

On the second line, n+1 numbers a0, a1, …, an separated by space, which are the coefficients of the polynomial.

On the third line, a nonnegative integer m.

Then m lines follow, the i-th of which is a number xi (i = 0, 1, …, m−1).

Output format

m lines, the i-th of which is a number P(xi), rounded to three decimal places.

Example

Input

2
-0.5 1 2.5
5
0
-6.6
1000
-1
32

Output

-0.500
101.800
2500999.500
1.000
2591.500

Notes

It is guaranteed that n ≤ 30. An array is enough to store the coefficients. Do not use heap memory.

Your program will not be compiled and linked against the math library, so do not use the functions in <math.h>.

The evaluation of P(xi) at a given point xi should be done using only one loop without calls to standard library functions. Think about how to do this efficiently.

P4

GCC argument descriptor

100 pts · HW2_programming

Problem background

To compile C/C++ code, we need to execute a command that calls the compiler with some arguments. For example:

gcc hello.c -o hello -std=c17 -Wall -Wpedantic -Wextra

This command compiles the C source code file hello.c with gcc, setting the output file to be hello, setting the language standard to be ISO C17, and enabling some kinds of warnings and errors by -Wall -Wpedantic -Wextra.

Taking a look at GCC's manual, you will find an overwhelmingly long list of supported arguments. Is there a tool that can generate some explanations of the arguments, or at least for some of the most common ones? For example, suppose the name of that tool is gcc_descriptor. It would be helpful if the following command

./gcc_descriptor hello.c -o hello -std=c17 -Wall -Wpedantic -Wextra

could print

hello.c: C source code as input file.
-o hello: Place the primary output in file hello.
-std=c17: Set the language standard to ISO C17.
-Wall: Enable all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning).
-Wpedantic: Issue all the warnings demanded by strict ISO C and ISO C++ and reject all programs that use forbidden extensions.
-Wextra: Enable some extra warning flags that are not enabled by -Wall.

Your task is to implement such a tool that generates explanations for some very common GCC arguments.

Problem description

Write a program that accepts command-line arguments, which are the arguments that we want to pass to GCC, and print the descriptions for them. The supported kinds of arguments are as follows.

1. -Wall

-Wall: Enable all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning).

2. -Wpedantic

-Wpedantic: Issue all the warnings demanded by strict ISO C and ISO C++ and reject all programs that use forbidden extensions.

3. -Wextra

-Wextra: Enable some extra warning flags that are not enabled by -Wall.

4. -Werror

-Werror: Make all warnings into errors.

5. -o xxx

-o xxx: Place the primary output in file xxx.

where xxx is replaced by the actual file name (see the example below). Note that this option consists of two arguments, where the first one is -o and the second one is the file name.

6. -I xxx

-I xxx: Add the directory xxx to the list of directories to be searched for header files during preprocessing.

where xxx is replaced by the actual directory name (see the example below). Note that this option consists of two arguments, where the first one is -I and the second one is the directory name.

7. -std=xxx

-std=xxx: Set the language standard to yyy.

where xxx is replaced by the actual value and yyy is replaced by the name of the standard according to the following table.

xxxyyyexampleexample output
cNISO CNc17ISO C17
c++NISO C++Nc++20ISO C++20
gnuNGNU dialect of CNgnu11GNU dialect of C11
gnu++NGNU dialect of C++Ngnu++14GNU dialect of C++14

N consists of two digits. For example, the 2003 ISO C++ standard is named C++03.

8. Other

Anything that does not match the patterns above is treated as an input file.

xxx: yyy as input file.

where xxx is replaced by the file name and yyy is replaced by the type of the file according to the following table.

xxxyyyexample
*.cC source codehello.c
*.hC/C++ header filestdio.h
*.cpp, *.C, *.cc, *.cxxC++ source codechecker.cc, game.cpp
*.hpp, *.hxxC++ header fileutils.hpp

Notes

There is no input for this problem. The arguments to be explained are given as the command line arguments of your program.

It is guaranteed that the arguments are valid: anything that does not match the patterns in 1–7 must be a valid C/C++ source or header file name as described in the table above. For the language standards (pattern 7), you don't need to check whether the standard that it refers to actually exists. Things like -std=c++100000 won't appear.

Also, there won't be any invalid file name or something like -Wall.cpp, which means you should focus on the implementation itself, not some tricky corner cases.

The names of the files and directories involved in the arguments do not contain whitespaces or quotes. The name following -o or -I is not a C/C++ source or header file. Print the explanations in order of the arguments.

Please be extremely careful about the output contents, especially the spaces, newlines and punctuations.

Example

If the following command is executed,

./my_program -std=c++20 -Wall -Wpedantic -Wextra a.c b.hxx c.cpp -Werror -o output_file -I /usr/local/boost_1_80_0/

the output is

-std=c++20: Set the language standard to ISO C++20.
-Wall: Enable all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning).
-Wpedantic: Issue all the warnings demanded by strict ISO C and ISO C++ and reject all programs that use forbidden extensions.
-Wextra: Enable some extra warning flags that are not enabled by -Wall.
a.c: C source code as input file.
b.hxx: C++ header file as input file.
c.cpp: C++ source code as input file.
-Werror: Make all warnings into errors.
-o output_file: Place the primary output in file output_file.
-I /usr/local/boost_1_80_0/: Add the directory /usr/local/boost_1_80_0/ to the list of directories to be searched for header files during preprocessing.
P5

CPU emulator

100 pts · HW2_programming

To understand how the computer executes your program, let me give a short introduction to the CPU. The CPU basically contains 2 parts: a register file with registers and an ALU (more in CS110). You can consider registers as an array. Each cell of this array has a name (for example, x0, x1, x2, …, x31 in RISC-V 32), and can store 32-bit data. Arithmetic calculations (addition, subtraction, multiplication, division, …) are done by the ALU.

When executing your program, the assembly codes (written in binary) are sent to the CPU. Each line of assembly code specifies some operation on registers, and the CPU uses a special register named PC (program counter) to identify the current execution line number. For example, if the code is add x3 x1 x2, then the CPU takes the values in registers x1 and x2, adds them up and stores the result in register x3. This is shown in the figure below (only 5 registers shown here). Then, the CPU increments PC by 1 to execute the next instruction.

CPU executing add x3 x1 x2

In this problem, you are required to implement a toy CPU which is able to execute a very simple assembly language (similar to RISC-V). You only need to consider 6 registers, named x0, x1, x2, x3, x4 and x5, all in lowercase, and each register stores a 16-bit signed integer. The x0 register is a special one, whose value is always zero (that is, whatever operation done to x0 will not affect its value). Also, there are only 6 instructions in this assembly language: add, sub, mul, div, let and print, which are introduced below.

In this problem, we use a 16-bit machine code. An example of a 16-bit instruction is as follows.

16-bit instruction format: opcode, r1, r2, imm

The instructions add, sub, mul and div are similar. The syntax is shown in the following table. Note that in these operations, the imm part is discarded.

InstructionSyntaxExplanationOpCode
addadd r1 r2value in r1 += value in r2000
subsub r1 r2value in r1 -= value in r2001
mulmul r1 r2value in r1 *= value in r2010
divdiv r1 r2value in r1 /= value in r2011

The let instruction is used to assign a value to a register. The syntax is:

InstructionSyntaxExplanationOpCode
letlet r1 immvalue in r1 = imm100

where r1 is the name of some register (x0 to x5), and imm is an integer within the range [0, 27−1]. In this instruction, the r2 part is discarded and the imm part is used. For example, the execution of instruction let x1 80 is shown below.

let x1 80 instruction encoding

Also, we need a print instruction to print the value in some register so that we can test whether the execution result is correct. For example, if the value in register x1 is 5, your emulator should print x1 = 5 on the screen when the instruction print x1 is executed. The r2 part is also discarded in this instruction.

InstructionSyntaxExplanationOpCode
printprint r1print value in r1101

Notes

1. In the div instruction, the division result is truncated towards zero, and the denominator will always be non-zero.

2. Values in all registers should be initialized to 0 before execution.

3. Remember that the value in x0 is always zero. Any instruction that attempts to modify it should have no effect.

4. We only consider unsigned immediates in this problem.

Input format

The first line of the input is a number n, indicating the total lines of code. The following n lines are the instructions written in hexadecimal.

Output format

Your emulator should execute the input program, and only print the result when a print instruction is executed. It is guaranteed that the input and output are both non-empty.

Example 1

Input

2
0x8401
0xA400

Output

x1 = 1

Example 2

Input

10
0x8401
0x8801
0x8C01
0x9001
0x9401
0xA400
0xA800
0xAC00
0xB000
0xB400

Output

x1 = 1
x2 = 1
x3 = 1
x4 = 1
x5 = 1

Explanation

0x8401 is 1000010000000001 in binary, whose opcode is 100, r1 is 001 (x1), r2 is 000 (x0) and imm is 0000001 (1). From the opcode we know that this is a let instruction, so the instruction is let x1 1.

0xA400 is 1010010000000000 in binary, whose opcode is 101 and r1 is 001 (x1). This is a print instruction, so the instruction is print x1.

Your program will not be compiled and linked against the math library, so do not use the functions in <math.h>.

Submission

Starter package: download HW2_student_starter.zip — the three source files (already correctly named) and a README that walks you through the compile commands. Fill in your code and submit the files as-is.

Problems 1 and 2: answer the online questions on Gradescope — Problem 1 on HW2_p1, Problem 2 on HW2_p2. You may update your answers any number of times before the deadline.

Problems 3–5: submit to the Gradescope assignment HW2_programming. Write one C source file per problem, named exactly p3.c, p4.c and p5.c. Submission is via a GitHub repository (see Recitation 3): create a private repository with the three files at the top level, then on Gradescope choose the GitHub submission method, select your repository and the branch. Each problem is graded independently, and the three problems show up as three rows of 100 points each.

The autograder builds your code with the course's own trusted Makefile — you do not need to write one. Any Makefile you submit is replaced before building, so local changes to compilation flags have no effect on grading. Each problem is built with make p3 (respectively p4, p5).

Compilation and static checks

You compile each problem by typing a gcc command yourself in the terminal (WSL). The command has the same shape for all three problems; only the file name changes. The minimal form is:

gcc p3.c -o p3

That builds and runs, but we recommend the advanced form — it turns on the C17 standard, all the useful warnings, and the sanitizers that catch memory errors and undefined behaviour while you test:

gcc p3.c -o p3 -std=c17 -Wall -Wpedantic -Wextra -Werror -fsanitize=undefined -fsanitize=address

Type it out yourself (muscle memory beats copy-paste), and replace both p3's with the problem you are building: p4 or p5. What each option does:

OptionWhat it does
-std=c17Use the C17 language standard (the course standard).
-Wall -WextraTurn on the standard and the extra sets of compiler warnings.
-WpedanticWarn about anything that is not strict ISO C.
-WerrorTreat every warning as an error, so a warning can never slip through.
-fsanitize=undefined -fsanitize=addressRuntime checkers: UBSan reports undefined behaviour such as signed overflow; ASan reports memory errors (out-of-bounds, use-after-free) with exact line numbers.

What the autograder requires

On Gradescope your code is built by the course's trusted Makefile (any Makefile you submit is replaced) with a deliberately simple command: just -std=c17 plus small per-problem additions — -O2 -g for p3, -Wno-unused-parameter for p4, and -O2 for p5. There is no -Werror or sanitizer gate on the OJ side; we still recommend compiling locally with the advanced command above, because its warnings and sanitizers catch bugs before the test cases do. Source-level static checks (course rules, e.g. the ban on heap memory where stated) still run: a failed static check earns 0 points for that problem, and the diagnostics are shown in the corresponding row on Gradescope.

Each problem's 100 points are split across its test cases, and a problem's score is the sum of the test cases you pass. A run is stopped if it exceeds its time limit, produces excessive output, or crashes (including sanitizer reports).

Tip: press the up arrow key in the terminal to bring back the last command you typed — press it repeatedly to walk further back through your history. You will never have to retype a long gcc line. Problem 4 reads no standard input; pass the GCC arguments on the command line instead: ./p4 -std=c17 -Wall hello.c -o hello.