Without using any arithmetic or comparison operators (e.g., +
, -
, *
, /
,
%
, <
, <=
, >
, >=
, ==
, or !=
), fill in the blanks according to the
description. Exception: you may use -
only to account for off-by-one
(e.g., x - 1
is ok; x - 32
or x - n
is not).
Bonus: don’t assume that sizeof(int) == 4
; make this work for any int
size!
mul8(x)
should return x * 8
:
int mul8(int x) {
return ________________; // (3.1.1)
}
make_odd(x)
should return x
if x
is odd, and return x + 1
otherwise:
unsigned int make_odd(unsigned int x) {
return ________________; // (3.1.2)
}
is_negative(x)
should return 1
when x
is negative, and 0
otherwise:
int is_negative(int x) {
if (________________) // (3.1.3)
return 1;
else
return 0;
}
set_bit(x, n, b)
should return x
, with its n
-th bit is set to 1
if b
is non-zero, and set to 0
otherwise (n
is zero-indexed; set_bit(0, 0, 1)
should return 1
):
int set_bit(int x, int n, int b) {
if (b)
return ________________; // (3.1.4)
else
return ________________; // (3.1.5)
}
Check out the solutions by checking out the examples on CLAC:
git clone ~j-hui/cs3157-pub/examples/bitmask
In this repo, the solutions are written in bitmask-solutions.h
as macros;
you can fill in bitmask.c
yourself before looking at the solutions.
Build using make
, test by running ./bitmask
.
Consider the following program:
#include <stdio.h>
int add(int x, int y) {
return x + y;
}
int print_int(int x) {
printf("%d\n", x);
return x;
}
int main(void) {
int x = 1, y = 2, z = 0;
// CODE FRAGMENT HERE
}
What does the program print if we substitute the // CODE FRAGMENT HERE
comment
with each of the following code fragments? If the behavior of the program is
not well-defined (e.g., undefined or unspecified behavior), write “UNSPECIFIED”.
// 3.2.1
if (print_int(z)) {
print_int(y);
} else {
print_int(x);
}
// 3.2.2
print_int(add(++x, ++x));
// 3.2.3
print_int(print_int(y) - print_int(x));
// 3.2.4
while (print_int(y) && print_int(z)) {
print_int(x);
}
// 3.2.5
print_int(print_int(y) || print_int(x));
// 3.2.6
print_int(add(print_int(x), print_int(y)));
// 3.2.7
print_int(sizeof(print_int(x)) - sizeof(print_int(y)));
// 3.2.8
print_int(print_int(x) + x++);
// 3.2.9
print_int(add(y++, ++z));
// 3.2.10
while (print_int(y--) || print_int(--x)) {
print_int(z);
}
Check out the solutions by checking out the examples on CLAC:
git clone ~j-hui/cs3157-pub/examples/eval-order
In this repo, each part is in its own subdirectory, where the program is
implemented in eval.c
. See inline comments for answers and explanations;
run make
to build eval
, which you can run to see the output for yourself
(if the behavior is well-defined).
Each of the following programs try to print an integer, but only some succeed without memory leaks or errors. For each program, answer “ERROR” if there is a memory error, “LEAK” if there are no errors but it leaks memory, and “OK” if there are no memory errors or leaks.
malloc()
never returns NULL
.#include
directives have been omitted for brevity.// 3.3.1
int *m(int n) {
return &n;
}
int main(void) {
int *p = m(1);
printf("%d\n", *p);
return 0;
}
// 3.3.2
int g;
int *m(int n) {
g = n;
return &g;
}
int main(void) {
int *p = m(1);
printf("%d\n", *p);
return 0;
}
// 3.3.3
int *m(int *n) {
*n = 0;
return n;
}
int main(void) {
int i;
int *p = m(&i);
printf("%d\n", *p);
free(p);
return 0;
}
// 3.3.4
int *m(int n) {
return malloc(n);
}
int main(void) {
int *p = m(sizeof(int));
printf("%d\n", *p);
free(p);
return 0;
}
// 3.3.5
int *m(int n) {
int *p = malloc(n);
*p = n;
free(p);
return p;
}
int main(void) {
int *p = m(sizeof(int));
printf("%p\n", p);
return 0;
}
// 3.3.6
int *m(int n) {
int *p = malloc(n);
*p = n;
return p;
}
int main(void) {
int *p = m(sizeof(int));
printf("%d\n", *p);
free(p);
free(p);
return 0;
}
// 3.3.7
int *m(int *n) {
if (n)
*n = 1;
return n;
}
int main(void) {
int *p = m(malloc(sizeof(m(NULL))));
printf("%d\n", *p);
return 0;
}
Check out the solutions by checking out the examples on CLAC:
git clone ~j-hui/cs3157-pub/examples/mem-safety
In this repo, each part is in its own subdirectory, where the program is
implemented in mem.c
. See inline comments for answers and explanations;
run make
to build mem
, which you can run with valgrind
to see whether
there are memory leaks or errors.