📄 chapter 3 numbers, characters and strings -- valvano.htm
字号:
<TR>
<TD vAlign=top width="41%"><FONT size=2>E or e</FONT> </TD>
<TD vAlign=top width="28%"><FONT size=2>14</FONT> </TD>
<TD vAlign=top width="31%"><FONT size=2>1110</FONT> </TD></TR>
<TR>
<TD vAlign=top width="41%"><FONT size=2>F or f</FONT> </TD>
<TD vAlign=top width="28%"><FONT size=2>15</FONT> </TD>
<TD vAlign=top width="31%"><FONT size=2>1111</FONT>
</TD></TR></TBODY></TABLE></P>
<ADDRESS>Table 3-13. Definition of hexadecimal representation.</ADDRESS>
<P>Computer programming environments use a wide variety of symbolic notations to
specify the numbers in various bases. The following table illustrates various
formats for numbers </P>
<P>
<TABLE cellSpacing=0 width=533 border=0>
<TBODY>
<TR>
<TD vAlign=top width="40%">environment</TD>
<TD vAlign=top width="15%">binary format</TD>
<TD vAlign=top width="21%">hexadecimal format</TD>
<TD vAlign=top width="25%">decimal format</TD></TR>
<TR>
<TD vAlign=top width="40%">Motorola assembly language</TD>
<TD vAlign=top width="15%">%01111010</TD>
<TD vAlign=top width="21%">$7A</TD>
<TD vAlign=top width="25%">122</TD></TR>
<TR>
<TD vAlign=top width="40%">Intel and TI assembly language</TD>
<TD vAlign=top width="15%">01111010B</TD>
<TD vAlign=top width="21%">7AH</TD>
<TD vAlign=top width="25%">122</TD></TR>
<TR>
<TD vAlign=top width="40%">C language</TD>
<TD vAlign=top width="15%">-</TD>
<TD vAlign=top width="21%">0x7A</TD>
<TD vAlign=top width="25%">122</TD></TR></TBODY></TABLE></P>
<ADDRESS>Table 3-14. Various hexadecimal formats.</ADDRESS>
<P>To convert from binary to hexadecimal we can:</P>
<DIR>
<P>1) divide the binary number into right justified nibbles;<BR>2) convert each
nibble into its corresponding hexadecimal digit.</P></DIR>
<CENTER>
<P><IMG height=116
src="Chapter 3 Numbers, Characters and Strings -- Valvano.files/Image16.gif"
width=309></P></CENTER>
<P> </P>
<P>To convert from hexadecimal to binary we can:</P>
<DIR>
<P>1) convert each hexadecimal digit into its corresponding 4 bit binary
nibble;<BR>2) combine the nibbles into a single binary number.</P></DIR>
<CENTER>
<P><IMG height=116
src="Chapter 3 Numbers, Characters and Strings -- Valvano.files/Image17.gif"
width=303></P></CENTER>
<P>If a sequence of digits begins with <B>0x</B> or <B>0X</B> then it is taken
as a hexadecimal value. In this case the word digits refers to hexadecimal
digits (0 through F). As with decimal numbers, hexadecimal numbers are converted
to their binary equivalent in 8-bit bytes or16-bit words. The range of a
hexadecimal number depends on the data type as shown in the following table.</P>
<P>
<TABLE cellSpacing=0 width=410 border=0>
<TBODY>
<TR>
<TD vAlign=center width="18%"><U><FONT size=2>type</FONT></U></TD>
<TD vAlign=center><U><FONT size=2>range</FONT></U></TD>
<TD vAlign=center><U><FONT size=2>precision</FONT></U></TD>
<TD vAlign=center width="30%"><U><FONT size=2>examples</FONT></U></TD></TR>
<TR>
<TD vAlign=center width="18%"><FONT size=2>unsigned char</FONT></TD>
<TD vAlign=center><FONT size=2>0x00 to 0xFF</FONT></TD>
<TD vAlign=center><FONT size=2>8 bits</FONT></TD>
<TD vAlign=center width="30%"><FONT size=2>0x01 0x3a 0xB3</FONT></TD></TR>
<TR>
<TD vAlign=center width="18%"><FONT size=2>char</FONT></TD>
<TD vAlign=center><FONT size=2>-0x7F to 0x7F</FONT></TD>
<TD vAlign=center><FONT size=2>8 bits</FONT></TD>
<TD vAlign=center width="30%"><FONT size=2>-0x01 0x3a -0x7B</FONT></TD></TR>
<TR>
<TD vAlign=center width="18%"><FONT size=2>unsigned int</FONT></TD>
<TD vAlign=center><FONT size=2>0x0000 to 0xFFFF</FONT></TD>
<TD vAlign=center><FONT size=2>16 bits</FONT></TD>
<TD vAlign=center width="30%"><FONT size=2>0x22 0Xabcd 0xF0A6</FONT></TD></TR>
<TR>
<TD vAlign=center width="18%"><FONT size=2>int</FONT></TD>
<TD vAlign=center><FONT size=2>-0x7FFF to 0x7FFF</FONT></TD>
<TD vAlign=center><FONT size=2>16 bits</FONT></TD>
<TD vAlign=center width="30%"><FONT size=2>-0x22 0X0 +0x70A6</FONT></TD></TR>
<TR>
<TD vAlign=center width="18%"><FONT size=2>unsigned short</FONT></TD>
<TD vAlign=center><FONT size=2>0x0000 to 0xFFFF</FONT></TD>
<TD vAlign=center><FONT size=2>16 bits</FONT></TD>
<TD vAlign=center width="30%"><FONT size=2>0x22 0Xabcd 0xF0A6</FONT></TD></TR>
<TR>
<TD vAlign=center width="18%"><FONT size=2>short</FONT></TD>
<TD vAlign=center><FONT size=2>-0x7FFF to 0x7FFF</FONT></TD>
<TD vAlign=center><FONT size=2>16 bits</FONT></TD>
<TD vAlign=center width="30%"><FONT size=2>-0x1234 0x0
+0x7abc</FONT></TD></TR>
<TR>
<TD vAlign=center width="18%"><FONT size=2>long</FONT></TD>
<TD vAlign=center><FONT size=2>-0x7FFFFFFF to 0x7FFFFFFF</FONT></TD>
<TD vAlign=center><FONT size=2>32 bits</FONT></TD>
<TD vAlign=center width="30%"><FONT size=2>-0x1234567
0xABCDEF</FONT></TD></TR></TBODY></TABLE></P>
<ADDRESS>Table 3-15. The range of hexadecimal numbers.</ADDRESS>
<P> </P>
<P><B><I><FONT face=Helvetica,Arial><A name=CHARACTER></A>Character
Literals</FONT></I></B></P>
<P>Character literals consist of one or two characters surrounded by
apostrophes. The manner in which character literals are treated depends on the
context. For example</P>
<DIR>
<P><CODE>short I;<BR>unsigned short J;<BR>char K;<BR>unsigned char L;<BR>long
M;<BR>void main(void){
<BR> I='a'; /* 16 bits 0x0061
*/<BR> J='a'; /* 16 bits 0x0061
*/<BR> K='a'; /* 8 bits 0x61
*/<BR> L='a'; /* 8 bits 0x61
*/<BR> M='a'; /* 32 bits
0x00000061 */}</CODE></P></DIR>
<P>The 6812 code generated by the ICC12 compiler is as follows</P>
<DIR>
<P><CODE> .area text <BR>_main::
<BR> pshx <BR> tfr s,x
<BR> movw #97,_I ;16
bits<BR> movw #97,_J ;16 bits
<BR> movb #97,_K ;8 bits
<BR> movb #97,_L ;8 bits
<BR> ldy #L2 <BR> jsr __ly2reg ;32
bits<BR> ldy #_M <BR> jsr __lreg2y
<BR> tfr x,s <BR> pulx
<BR> rts <BR> .area bss <BR>_M::
.blkb 4 <BR>_L:: .blkb 1 <BR>_K:: .blkb 1 <BR>_J:: .blkb 2 <BR>_I:: .blkb 2
<BR> .area text <BR>L2: .word 0,97</CODE></P></DIR>
<P>The 6812 code generated by the Hiware compiler is as follows</P>
<DIR>
<P><CODE> LDAB #97<BR> CLRA
<BR> STD I<BR> STD
J<BR> STAB K<BR> STAB
L<BR> STD M:2<BR> CLRB
<BR> STD M<BR> RTS
<BR></CODE></P></DIR>
<P>All <A
href="http://www.ece.utexas.edu/~valvano/embed/chap2/chap2.htm#ASCII">standard
ASCII characters</A> are positive because the high-order bit is zero. In most
cases it doesn't matter if we declare character variables as signed or unsigned.
On the other hand, we have seen earlier that the compiler treats signed and
unsigned numbers differently. Unless a character variable is specifically
declared to be unsigned, its high-order bit will be taken as a sign bit.
Therefore, we should not expect a character variable, which is not declared
unsigned, to compare equal to the same character literal if the high-order bit
is set. For more on this see <A
href="http://www.ece.utexas.edu/~valvano/embed/chap4/chap4.htm">Chapter 4 on
Variables</A>.</P>
<P><B><I><FONT face=Helvetica,Arial><A name=STRING></A>String
Literals</FONT></I></B></P>
<P>Strictly speaking, C does not recognize character strings, but it does
recognize arrays of characters and provides a way to write character arrays,
which we call <I>strings</I>. Surrounding a character sequence with quotation
marks, e.g., <B>"Jon"</B>, sets up an array of characters and generates the
address of the array. In other words, at the point in a program where it
appears, a string literal produces the address of the specified array of
character literals. The array itself is located elsewhere. ICC11 and ICC12 will
place the strings into the text area. I.e., the string literals are considered
constant and will be defined in the ROM of an embedded system. This is very
important to remember. Notice that this differs from a character literal which
generates the value of the literal directly. Just to be sure that this distinct
feature of the C language is not overlooked, consider the following example:</P>
<DIR>
<P><CODE>char *pt;<BR>void main(void){
<BR> pt="Jon"; /* pointer to the string
*/<BR> printf(pt); /* passes the pointer not the
data itself */<BR>}</CODE></P></DIR>
<P>The 6812 code generated by the ICC12 compiler is as follows</P>
<DIR>
<P><CODE> .area text <BR>_main::
<BR> movw #L2,_pt <BR> ldd
_pt<BR> jsr _printf<BR> rts
<BR> .area bss <BR>_pt:: .blkb 2
<BR> .area text <BR>L2: .byte 'J,'o,'n,0
</CODE></P></DIR>
<P>The 6812 code generated by the Hiware compiler is virtually the same as
ICC12. Both compilers place the string in memory and use a pointer to it when
calling printf. ICC12 will pass the parameter in RegD, while Hiware pushes the
parameter on the stack.</P>
<DIR>
<P><CODE> MOVW #"Jon",pt <BR> LDD
pt<BR> PSHD<BR> JSR
printf<BR> PULD<BR> RTS
</CODE></P></DIR>
<P>Notice that the pointer, <CODE>pt</CODE>, is allocated in RAM (.area bss) and
the string is stored in ROM (.area text). The assignment statement
<CODE>pt="Jon";</CODE> copies the address not the data. Similarly, the function
<CODE>printf()</CODE> must receive the address of a string as its first (in this
case, only) argument. First, the address of the string is assigned to the
character pointer <CODE>pt</CODE><B> </B>(ICC11/ICC12 use the 16 bit Register D
for the first parameter). Unlike other languages, the string itself is not
assigned to <CODE>pt</CODE>, only its address is. After all, <CODE>pt</CODE> is
a 16-bit object and, therefore, cannot hold the string itself. The same program
could be written better as </P>
<DIR>
<P><CODE>void main(void){ <BR> printf("Jon"); /*
passes the pointer not the data itself */<BR>}</CODE></P></DIR>
<P>Notice again that the program passes a pointer to the string into
<CODE>printf()</CODE>, and not the string itself. The 6812 code generated by the
ICC12 compiler is as follows</P>
<DIR>
<P><CODE> .area text <BR>_main::
<BR> ldd #L2<BR> jsr
_printf<BR> rts <BR> .area text
<BR>L2: .byte 'J,'o,'n,0 </CODE></P></DIR>
<P>Except for the parameter passing, the 6812 code generated by the Hiware
compiler is virtually the same as ICC12. </P>
<DIR>
<P><CODE> LDD #"Jon"
<BR> PSHD<BR> JSR
printf<BR> PULD<BR> RTS
</CODE></P></DIR>
<P>In this case, it is tempting to think that the string itself is being passed
to <CODE>printf()</CODE>; but, as before, only its address is.</P>
<P>Since strings may contain as few as one or two characters, they provide an
alternative way of writing character literals in situations where the address,
rather than the character itself, is needed.</P>
<P>It is a convention in C to identify the end of a character string with a null
(zero) character. Therefore, C compilers automatically suffix character strings
with such a terminator. Thus, the string <B>"Jon"</B> sets up an array of four
characters (<B>'J'</B>, <B>'o'</B>,<B> 'n'</B>, and zero) and generates the
address of the first character, for use by the program.</P>
<P>Remember that 'A' is different from "A", consider the following example:</P>
<DIR>
<P><CODE>char letter,*pt;<BR>void main(void){
<BR> pt="A"; /*
pointer to the string */<BR> letter='A'; /*
the data itself ('A' ASCII 65=$41) */<BR>}</CODE></P></DIR>
<P>The 6812 code generated by the ICC12 compiler is as follows</P>
<DIR>
<P><CODE> .area text <BR>_main::
<BR> movw #L2,_pt <BR> movb
#65,_letter<BR> rts <BR> .area bss
<BR>_letter:: .blkb 1 <BR>_pt:: .blkb 2 <BR> .area text
<BR>L2: .byte 'A,0 </CODE></P></DIR>
<P>The 6812 code generated by the Hiware compiler is as follows </P>
<DIR>
<P><CODE> MOVW #"A",pt <BR> LDAB
#65<BR> STAB letter<BR> RTS
</CODE></P></DIR>
<P><B><I><FONT face=Helvetica,Arial><A name=ESCAPE></A>Escape
Sequences</FONT></I></B></P>
<P>Sometimes it is desirable to code nongraphic characters in a character or
string literal. This can be done by using an <I>escape sequence</I>--a sequence
of two or more characters in which the first (escape) character changes the
meaning of the following character(s). When this is done the entire sequence
generates only one character. C uses the backslash (<B>\</B>) for the escape
character. The following escape se
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -