CS 330 Lecture 13 – Data Structures in C, Make
Agenda
- what ?s
- riddle
- variable-length arrays
- distinct ideas:
- memory is addressable
- heap memory can be allocated dynamically
- generating stereo tones
- pointer arithmetic
- a stack data structure without classes
- typedef
- separate compilation and header files
- a postfix calculator
- managing separate compile with make
Variable-length Arrays
The C99 standard allows arrays whose sizes are only known at runtime to be created on the stack. However, it may not be a good idea to make dynamically-sized arrays in this way:
- http://msdn.microsoft.com/en-us/library/zb1574zs.aspx
- http://en.wikipedia.org/wiki/Variable-length_array
- http://c-faq.com/aryptr/dynlocarys.html
Questions
- How Java and company get away without header files: http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx
- What can C macros do that functions can’t?
Code
audioh.c
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define ERROR(msg) \
printf("%s at line %d, file %s.\n", msg, __LINE__, __FILE__); \
exit(1);
void error(const char *msg) {
printf("%s at line %d, file %s.\n", msg, __LINE__, __FILE__);
exit(1);
}
#define EZMALLOC(type, n) \
(type *) malloc((n) * sizeof(type))
int main(int argc, char **argv) {
int nsamples = atoi(argv[1]);
float divisors[] = {
atof(argv[2]),
atof(argv[3])
};
short *samples = EZMALLOC(short, nsamples * 2);
/* samples[0]; // first sample of left channel */
/* samples[1]; // first sample of right channel */
/* samples[i * 2 + 0]; // ith sample of left channel? */
/* samples[i * 2 + 1]; // ith sample of left channel? */
int i;
float *sample = samples;
for (i = 0; i < nsamples; ++i) {
/* samples[i * 2 + 0] = (short) (sin(i / divisors[0]) * 32767); */
/* samples[i * 2 + 1] = (short) (sin(i / divisors[1]) * 32767); */
sample[0] = (short) (sin(i / divisors[0]) * 32767);
sample[1] = (short) (sin(i / divisors[1]) * 32767);
sample += 2;
}
FILE *file = fopen("samples.raw", "w");
fwrite(samples, sizeof(short), nsamples * 2, file);
fclose(file);
free(samples);
return 0;
}
stack.c
#define EZMALLOC(type, n) \
(type *) malloc((n) * sizeof(type))
struct stack_t {
int size;
int capacity;
int *items;
};
typedef struct stack_t stack_t;
stack_t *make_stack(int capacity) {
stack_t *stack = EZMALLOC(stack_t, 1);
stack->size = 0;
stack->capacity = capacity;
stack->items = EZMALLOC(int, stack->capacity);
}
void stack_push(stack_t *stack, int item) {
if (stack->size >= stack->capacity) {
fprintf(stderr, "Stack full, you foo bag.\n");
exit(1);
}
stack->items[stack->size] = item;
++stack->size;
}
int stack_pop(stack_t *stack) {
if (stack->size == 0) {
fprintf(stderr, "Stack empty, you foo bag.\n");
exit(1);
}
int item = stack->items[stack->size - 1];
--stack->size;
return item;
}
TODO
- Read the introduction (section 2) of the GNU Make manual.
- You may want to consult some of the other tutorials listed at http://en.wikibooks.org/wiki/Make. I can’t recommend one over another.
Haiku
They’re all powerups.
Every program I write.
Each takes me farther.
Every program I write.
Each takes me farther.