Exercise 6.1 from ANSI C book - getword function
The last logic is quite hard to trace, and it is prone to bugs. Consider /* ... */*. Once the code reached the closing /, it returns, but last is not updated, and remains /, so the next * is still treated as a beginning of a comment.
Handling of string constants has a definite problem: it doesn't account for an escaped quote char in the middle of the string (e.g. "aaa\"bbb").


Combining the two above observations, I strongly recommend to revisit the design, and realize few more functions, such as get_line_comment, get_c_comment, get_quoted_string etc.


No word in keytab starts with an underscore. You don't need to go into binsearch in that case.
The preprocessor directive may not appear in the middle of the line. I am not sure if a directive in such case should be counted.