In this paper we investigate the computational power of simple programming languages and provide characterizations (or partial characterizations) of the functions computable by such programs in terms of some space and/or time complexity classes of Turing machines. Call a function f( x 1,…, x 1) over the nonnegative integers linearly bounded if f( x 1,…, x 1)< O( x 1+…+ x 1). We show that any linearly bounded function f( x 1,…, x 1) computable by a Turing machine in O( n) space and O(2 λn ) time, where λ<1 and n=¦x 1+…+x 1¦ is the length of the binary representation of x 1+…+ x 1, can be computed by a program without nested loops using only the instruction set R=x←x−1, if x=0 then y←y+1, do x…lcubendrcub . Thus, functions like ¦x y ¦, ged{x,y}, x k , [log x] , etc. can be computed by R-programs. Any function computable by an R -program can be computed by a Turing machine in O( n) space and O(2 n ) time. It is open whether or not the time can be reduced to O(2 λ ) for some λ<1 (which may depend on the program). We also introduce simple programming languages which are complete characterizations of the functions computable by certain space bounded (linear bounded, polynomial bounded. etc.) classes of Turing machines. For example, we show that a function f( x 1,…, x 1 over the nonnegative integers is computable by a linear space bounded Turing machine if and only if it is computable by a program using only the constructs x←1, x←x+y, x←x−y, do x… end such that (i) there are no nested loops, and (ii) the occurence of a construct x← x+ y in a loop precludes the occurrence of a construct y← x+ z within the same loop. Extensions are also made for some time complexity classes of Turing machines.