Homework 7 - C Functions
Write a C file named smallfunc.c
that contains implementations of at least five of the following eight functions.
When you compile, make sure to use the -m64
flag to ensure that long
is a 64-bit number and void *
a 64-bit pointer.
No function you write in this file should invoke a function you did not write.
When you submit do not include main in your file. You are welcome to add it for testing, but remove it before submitting.
Capitalize
void capitalize(char *s);
Write a function with the above signature that converts all lower-case letters in s
into upper-case letters.
You did this by hand Lab 2.
Example: The following usage code
char *s = strdup("the book \"The C Programming Language.\"");
printf("before: %s\n", s);
capitalize(s);
printf("after: %s\n", s);
free(s);
will display
the book "The C Programming Language."
THE BOOK "THE C PROGRAMMING LANGUAGE."
Tip: test this with empty strings, strings with digits and punctuation in them, etc.
Fibonacci Array
void fibarray(unsigned char *dest, unsigned num);
Write a function with the above signature that places the first num
fibonacci numbers (modulo 256, since the array stores only bytes) into dest
.
You implemented something very like this in Lab 5. Unlike Lab 5, however, your code must work for any location and number of values requested.
Example: The following usage code
unsigned char a[64];
fibarray(a, 64);
for (int row=0; row<4; row+=1) {
for (int col=0; col<16; col+=1) {
printf(" %02hhx", a[row*16 + col]);
}
printf("\n");
}
will display
01 01 02 03 05 08 0d 15 22 37 59 90 e9 79 62 db
3d 18 55 6d c2 2f f1 20 11 31 42 73 b5 28 dd 05
e2 e7 c9 b0 79 29 a2 cb 6d 38 a5 dd 82 5f e1 40
21 61 82 e3 65 48 ad f5 a2 97 39 d0 09 d9 e2 bb
Tip: test this with 0- and 1-entry arrays as well as larger ones, and make sure you don’t set more values of the array than the requested num
.
Recursive Power
long recpow(long x, unsigned char e);
Write a function with the above signature that computes and returns x
^e
^. You must implement this recursively, not iteratively (do not use for
, while
, do
, or goto
).
You implemented something very like this in HW 5. Unlike HW05, however, your code must work for any
x
(including negative and zero) and anye
(including zero).
Example: The following usage code
long x = -21;
unsigned char e = 13;
long ans = recpow(x, e);
printf("%ld\n", ans);
printf("%ld\n", recpow(11, 0));
will display
-154472377739119461
1
Tip: test with both negative and positive x
and both even and odd e
.
Next Prime
unsigned long nextprime(unsigned long x);
Write a function with the above signature that returns the smallest prime number larger than x
.
Example: The following usage code
long x = 100;
for (int i=0; i<10; i+=1) {
x = nextprime(x);
printf("%ld\n", x);
}
printf("%ld\n", nextprime(1000000000000));
will display
101
103
107
109
113
127
131
137
139
149
1000000000039
Note: if your code is not very efficient, the last number might not appear for so long you lose patience waiting for it. That’s OK; we’ll only test with inputs that end in a reasonable time.
Tip: A number x is prime if and only if it is 2, or it is odd and is not a multiple of any odd number between 3 and √x.
Tip: Make sure you test with the arguments 0
, 1
, and 2
.
Interleave Bits
unsigned long binterleave(unsigned x, unsigned y);
Write a function with the above signature that returns a 64-bit number created by interleaving the bits of the two arguments. The low-order bit of the result should be the low-order bit of x
; then the low-order bit of y
, then the next-to-lowest bit of x
, then the next-to-lowest bit of y
, and so on up to high-order bit of y
.
You should use at least one loop in your solution.
Example: The following usage code
printf("%lx\n", binterleave(0x100030f, 0x1003f0));
printf("%lx\n", binterleave(0xffffff0f, 0x00000000));
printf("%lx\n", binterleave(0x00000000, 0xffffff0f));
will display
10200000faa55
5555555555550055
aaaaaaaaaaaa00aa
Tip: Remember that most operations, if given only 32-bit arguments, will truncate their result to 32 bits. You’ll probably want to make sure you have a long
value (such as 0L
) involved in important operations in your code.
Tip: You almost certainly want to test this with smaller numbers than the example uses first, so that you can more easily convert them to binary to check your work.
Reverse
void reverse(int *arr, unsigned length);
Reverse the fist length
elements of arr
in place.
Example: The following usage code
int x[] = {1, 1, 2, 3, 5, 8, 13, 21};
for (int i=0; i<8; i+=1) printf("%d, ", x[i]); printf("\n");
reverse(x, 6);
for (int i=0; i<8; i+=1) printf("%d, ", x[i]); printf("\n");
will display
1, 1, 2, 3, 5, 8, 13, 21,
8, 5, 3, 2, 1, 1, 13, 21,
Tip: Test this with both even and odd array lengths.
Push Zeros
void push0(int *arr, unsigned length);
Rearrange the first length
values of arr
in place, such that all of its non-zero values appear in their original order, followed by all of its zero values.
Example: The following usage code
int x[] = {1, 7, 3, 2, 0, 5, 0, 8, 0, 7, 5, 6, 8, 8, 7, 7, 2, 9};
for (int i=0; i<18; i+=1) printf("%d ", x[i]); printf("\n");
push(x, 15);
for (int i=0; i<18; i+=1) printf("%d ", x[i]); printf("\n");
will display
1 7 3 2 0 5 0 8 0 7 5 6 8 8 7 7 2 9
1 7 3 2 5 8 7 5 6 8 8 7 0 0 0 7 2 9
Tip: Test this with both arrays that do and don’t include zeros.
Find Non-duplicated Element
int nondup(int *arr, unsigned length);
Assume that arr
’s first length
elements contains exactly two copies of each value it contains, except one value it has only once. Return that one non-duplicated element.
If the array does not have a unique non-duplicated element, the behavior of nondup
is undefined.
Example: The following usage code
int x[] = {28, 12, 8, 0, 0, 28, 8};
printf("%d\n", nondup(x, 7));
printf("%d\n", nondup(x + 2, 5));
will display
12
28
Tip: There are (at least) two very different solution approaches: one with nested loops and another using xor.