The classical complexity classes (P, NP, LOGSPACE, etc) are defined formally starting from a Turing cost model -- that is we count resources used by a Turing machine that solves the problem. It turns out, however, that this detail is not really relevant for classes such as P and NP, because a Turing machine can simulate most other realistic models of computation with at most polynomial slowdown. So NP relative to a RAM ends up being the same as NP relative to Turing machines.
As far as complexity is concerned, C can be viewed as a RAM with unit-cost basic arithmetic and bitwise operations -- except that this does not model the fact that C (or rather the real computers we program with it) has a limited word length. Allowing unlimited integers in C programs leads to anomalies, because one can quickly build very large numbers using multiplication, and then use those to pack unlimited parallelism into the unit-cost arithmetic operations. Totally unrealistic, of course.
What one usually does about this problem is sweep it under the rug and pretend it doesn't exist. Any polynomial-time C program that one can reasonably imagine running on a real computer can be simulated in polynomial time on a Turing machine (though probably a polynomial of higher degree), so that thinking about such programs suffices for understanding, say, $P\overset ?= NP$.
However, if one wants to face the problem more explicitly, then natural strategy would be to work in a restricted C-like model that includes a word length restriction. It won't do to insist on a fixed word size (as in reality), because then for large enough problem instances, the restricted C model won't even be able to index enough memory to store the problem itself -- but complexity is all about asymptotic behavior, so we must be able to contemplate arbitrarily large problem instances being solved by our programs. I don't know if there's any completely standard assumption here, but it seems reasonable to say that the program must work with a word length that is a fixed multiple of the shortest word that can represent the size of the input. This ought to allow representing algorithms up to PSPACE fairly naturally -- and in the other direction it lets us characterize LOGSPACE as problems solvable by programs with bounded recursion depth that don't allocate memory dynamically (but are given a read-only pointer to the input).
When one speaks of finer distinctions than the classical polynomial-or-not, such as the $O(n)$, $O(n^2)$, $O(n\log n)$ classes one learns about in introductory algorithmics, it is usually tacitly understood that this "RAM with unit-cost arithmetic up to a logarithmic word size" model unless something else is explicitly specified -- that is, unit cost except that you're must write the program such that it doesn't exceed the word size you announce it will need, and be prepared too prove this if challenged. (I believe this is equivalent to a logarithmic-cost model for arthimetic, since one can imagine implementing a bignum library using a limited word length -- multiplication and division may need $\log^2$-cost, though).
Yes -- in the "modified RAM" or "C-like" model I speak about above (which I claim to be the underlying model of most actual complexity analysis), copying an integer is indeed a unit-cost operation. It is a different matter in the classical "counter RAM" model, of course (where a programmed copying operation takes time linear in the number being copied), or in the Turing model (where it is slower yet).
At least, charging cost $1$ for an assignment is the easiest model to defend and motivate. One could also choose to assign zero cost to assignment and arithmetic! Unrealistic though this sounds, it leads to exactly the same asymptotic complexities as unit cost, as long as jumps still cost something. This is because constant factors don't matter in asymptotic analysis, and between two jumps the program can do a bounded amount of arithmetic and assignments. In fact, for a C program all you really need to count is (a) the number of times you start executing a loop body, plus (b) the number of possibly recursive function calls you make. Doing so can simplify the bookkeeping of analyzing a concrete algorithm a great deal -- as long as you're only interested in the big-O behavior!