why there is a need to define temporary reg and only then assign to the output in verilog?
There is no difference in the two examples you wrote. You can even make is simpler:
module counter (
  input  wire clk, clr,
  output reg [3:0] q
);
always @(posedge clk or posedge clr)
begin
   if (clr)
      q&lt;= 4'b0000;
   else
      q&lt;= q+ 1'b1;
end

endmodule