Well for Prolog the underscore is simply an anonymous variable. So the a/1 predicate is equivalent to:
a(X) :-
b(Y),
c(X).
Now it may look useless to backtrack over the b(Y) clause, since once it is satisfied, the Y is nowhere used, and thus should not have impact on the rest of the program. Furthermore Y has no effect on X so b(Y) should not have the slightest influence on X.
In real Prolog however, there are some things that might have impact:
the b/1 predicate might perform I/O. Say that the predicate is implemented as:
b(a) :-
print(a).
b(a) :-
print(b).
then it will print a in the first branch and b in the second one.
b/1 might raise an exception in a second, third, ... path. In which case we probably want to handle the error;
b/1 might use asserta/1, assertz/1, etc. and alter the program. It might for instance add facts for c/1 such that in the second run c/1 has other results.
A lot of Prolog interpreters have a non-backtrackable store such that the different backtracking paths, can share information with each other.
other coding facilities such that the outcome of b/1 might have impact on c/1.
You can avoid this backtracking over b/1 by using the once/1 meta-predicate. For instance:
a(X) :-
once(b(_)),
c(X).