time_t represents the current time -- normally the number of seconds since some epoch (e.g., midnight, 1 Jan, 1970). It's intended to represent calendar/wall clock time, but still be easy to manipulate as a single, simple arithmetic type (e.g., difftime can find the difference between two specified times).
clock_t represents an amount of CPU time used since a process was started. It can be converted to seconds by dividing by CLOCKS_PER_SEC. Its real intent is to represent CPU time used though, not calendar/wall clock time.
struct tm is a structure (with specified members) that represents a calendar/wall clock time broken down into components -- year, month, day, hour, minute, second, etc. It's intended (primarily) as an external interface, while a time_t is intended primarily for internal use -- i.e., typical use is that when you get a date/time from the outside world, you put the components into a struct tm and convert it to a time_t for internal storage. Then, when you need to do something like displaying a time/date, you convert the time_t to a struct tm. The routines that do that manipulation include a fair amount of intelligence to do things like normalizing the dates, so a date like 30 February would be converted to 2 March (or in a leap year, 1 March).