Miscellaneous C Topics
Prof. Brian D. Davison
Computer Science & Engineering, Lehigh University
Announcements
- ACM is offering a session on LaTeX on Wednesday at 5pm -- this is a
topic that I expect we will examine later this semester.
- Today's schedule
- Notes on Programming Assignment #3
- Review Short Quiz #4
- Exam #1 topics
- Complete discussion on dynamic memory allocation
- User-defined types
- The comma operator
- Wednesday we will start talking about large program development
- Unless you have questions for the exam...
Notes on Programming Assignment #3
- Yes, sample solution to p2 may be used for p3
- Arguments vs. options
- Previously, we had only considered arguments to a program
- Options, using the familiar -n syntax, are also possible
- Typically options must come before arguments
- The '-' argument
- Often represents the use of stdin (e.g., tar, cat, ghostview, etc.)
Notes on Programming Assignment #3
- "Divide the source code into two or more .c and .h files"
- That is, you need 2+ .c files, and 1+ .h files
- When you have separate source files (.c files), you need to declare functions in one that the other needs to call, usually via a header file (.h file)
- A local .h file is included with quotes
#include "myheaders.h"
instead of < and > and is specified relative to the current directory.
- Local header files work the same as library header files (e.g., stdio.h) containing function and variable declarations, macros, etc.
- The header file can be pretty simple, e.g.
p2.h
- Makefile will need to be updated
- Compile separate .c files
- Link both in linking step
- Add .h as dependency for all compilation steps
Exam #1 Topics
- First hourly exam is Friday, in class
- Exam is closed book, closed notes, except for a 1 page 'cheat sheet' which you will also hand in
- Covers all readings listed on the schedule including today, plus everything we've done in class or homeworks/projects
- Expect mixture of short answers, T/F and multiple choice, and short
programming exercises
- Major topics include:
- Using UNIX
- Using Emacs
- C Programming
- Pointers and Storage Management
Finish Wednesday's discussion
- We had been discussing dynamic memory allocation
- Wrote a simple routine to expand the size of a dynamically allocated array of integers
- Realized need for pointers to pointers
- We have a few more issues to cover w.r.t. pointers...
Functions that return pointers
- When using routines that return pointers, you must determine who is
responsible for the memory
- Possibilities include:
- Pointer is to a global value -- memory never needs to be free()d, but might get overwritten by later function calls (e.g., some networking code)
- Pointer is to a dynamically-allocated local structure that must be
destroyed/freed with another library call
- Pointer is to a dynamically-allocated block of memory that your code
must later free (e.g., strdup())
- Pointer is to a portion of some other block of memory that could later
move or be freed independently of this pointer
(e.g., strstr())
- In general, you need to know if
- You are now responsible to free() this memory
- This memory might get overwritten in the future
Generally, either you need to free() or this is memory that you have no
control over...
Stack/Heap
- Finally, it is sometimes useful to think about exactly where
all this memory really is in your program.
- Let's consider the typical memory model for UNIX processes.
- The stack contains each calling frame of each function invocation, which are popped when the function returns.
- The heap contains dynamically allocated memory.
- The stack and heap grow toward each other.
Why can't malloc'd data be on the stack?
User-Defined Structures
- We have previously mentioned structs, as in
struct complex {
double real;
double imag;
};
which defined a new type
struct complex.
We could also have declared some new variables of that type, in two ways:
struct complex {
double real;
double imag;
} var1, var2;
struct complex var3, var4;
Access to Structs
- We also saw that we could access contents using the period operator:
c1.real = c2.real + c3.real;
Pointers to structs work as expected:
struct complex *p1, *p2;
*p1 = *p2;
printf("%lf\n", (*p1).real);
Parentheses are needed. Could instead use -> operator:
printf("%lf\n", p1->real);
which is an equivalent (and common) shortcut.
User-defined types
- A struct is a user-defined type
- The typedef operator also permits us to use an alternate name
for a defined type. Thus,
typedef char *StringPtr;
typedef struct complex Complex;
StringPtr string;
Complex c1, c2;
would be equivalent to
char *string;
struct complex c1, c2;
We often define new type names
- for convenience
- to make the code more self-documenting
- to make it possible to change the actual base type used for a lot of variables without rewriting the declarations of all those variables