Except when it is the operand of the sizeof or unary & operator, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element in the array.
When you write
scanf("%s", books[1].author);
the expression books[i].author has type "33-element array of char".  By the rule above, it will be converted to an expression of type "pointer to char" (char *) and the value of the expression will be the address of the first element of the array.
When you write
scanf("%s", &books[1].name);
the expression books[1].name is an operand of the unary & operator, so the conversion doesn't happen; instead, the type of the expression &books[1].name has type "pointer to 15-element array of char" (char (*)[15]), and its value is the address of the array.  
In C, the address of the array and the address of the first element of the array are the same, so both expressions result in the same value; however, the types of the two expressions are different, and type always matters.  scanf expects the argument corresponding to the %s conversion specifier to have type char *; by passing an argument of type char (*)[15], you invoke undefined behavior, meaning the compiler isn't required to warn you about the type mismatch, nor is it required to handle the expression in any meaningful way.  In this particular case, the code "works" (gives you the result you expect), but it isn't required to; it could just as easily have caused a crash, or led to corrupted data, depending on the specific implementation of scanf.  
Both calls should be written as
scanf("%s", books[1].name);
scanf("%s", books[1].author);
Edit
In answer to your comment, a picture may help.  Here's what your books array would look like:
+---+        +---+
  |          |   |  name[0]                  
  |          +---+
  |          |   |  name[1]
  |          +---+
  |           ...
  |          +---+
  |          |   |  name[14]
  |          +---+
books[0]     |   |  author[0]
  |          +---+
  |          |   |  author[1]
  |          +---+
  |           ...
  |          +---+
  |          |   |  author[33]
  |          +---+
  |          |   |  year
+---+        +---+
  |          |   |  name[0]    <------ books[1].name
  |          +---+
  |          |   |  name[1]
  |          +---+
  |           ...
  |          +---+
  |          |   |  name[14]
  |          +---+
books[1]     |   |  author[0]  <------ books[1].author
  |          +---+
  |          |   |  author[1]
  |          +---+
  |           ...
  |          +---+
  |          |   |  author[33]
  |          +---+
  |          |   |  year
+---+        +---+
Each element of the books array contains two arrays plus an integer.  books[1].name evaluates to the address of the first element of the name array within books[1]; similarly, the expression books[1].author evaluates to the address of the first element of the author array within books[1].