Rows are locked before being read. A row has to be read to see if it qualifies for a query predicate. If it does, then it's returned with no second read necessary.
This is why a query returning a single row can end up locking the entire table if there's no useful index, because every row in the table had to be read to see if it qualifies, which means every row had to be locked, and the efficient way to do that is with a table lock.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability