View previous topic :: View next topic |
Author |
Message |
nina
Joined: 20 Apr 2007 Posts: 111
|
simple questions |
Posted: Tue Feb 23, 2010 4:36 am |
|
|
What does it mean this line? 0x42?
#define test 0x42
I have seen Register, shift_register in some codes, AP and datasheet.
could someone give me a brief explanation about these?
Tks a lot |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Tue Feb 23, 2010 5:18 am |
|
|
0x42 is the hex representation of the decimal value 66 or in binary 0b01000010
A #define is used to make reading code easier. The compiler will replace all references in the code which match the #define with the value it represents.
#defines usually sit at the top of your code to make it easier to change the maximum size of a string for instance.
They should be in uppercase to make them easy to see:-
#define TEST 0x42
So
Code: |
#define TEST 0x24
void main()
{
int i;
for (i = 0; i < TEST; i++)
{
printf("%u", i);
}
}
|
the compiler will replace the word "TEST" in the for (i=0; i<TEST; i++) with the value 0x42 so it becomes
for(i = 0; i < 0x42; i++)
You can do more complicated things with #defines but that is the basic use.
If you know C then you would know this so I am assuming your are trying to learn.
I would sugest getting a decent C book or following some online tutorials on C programming. |
|
![](templates/subSilver/images/spacer.gif) |
nina
Joined: 20 Apr 2007 Posts: 111
|
simple |
Posted: Tue Feb 23, 2010 6:32 am |
|
|
Could you give a simple example where it is used #define?
What about register and shift_register?
Thank you a lot |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Tue Feb 23, 2010 7:05 am |
|
|
erm, did you read my post ? It contains an example ?)
Register has a special meaning in C, it assigns a variable to a CPU register for faster processing. As the PIC only has one register W it doesn't do anything. As specified in the CCS Help.
shift_register, This is used in the PIC to shift data into and out of a serial port (I2C, SPI, Serial). The functionality of which is handled by the CCS built in functions such as putc() and getc().
Actually, have you tried reading the CCS help files ? |
|
![](templates/subSilver/images/spacer.gif) |
nina
Joined: 20 Apr 2007 Posts: 111
|
smp |
Posted: Tue Feb 23, 2010 7:17 am |
|
|
Thank you again Wayne...
Could you give me a useful example when I use.
For what purpose?
I this example will print 0 and 1??
#define TEST 0x24
void main()
{
int i;
for (i = 0; i < TEST; i++)
{
printf("%u", i);
}
} |
|
![](templates/subSilver/images/spacer.gif) |
John P
Joined: 17 Sep 2003 Posts: 331
|
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Tue Feb 23, 2010 9:20 am |
|
|
It is decimal 42 as in the answer to the question. |
|
![](templates/subSilver/images/spacer.gif) |
jaimechacoff
Joined: 14 Feb 2010 Posts: 24 Location: Santiago, Chile
|
|
![](templates/subSilver/images/spacer.gif) |
Gavin Pinto
Joined: 18 Oct 2009 Posts: 27 Location: Australia
|
Re: simple questions |
Posted: Wed Feb 24, 2010 2:16 am |
|
|
nina wrote: | What does it mean this line? 0x42?
#define test 0x42
Tks a lot
|
Nina Pretty Ballerina,
My preferred way of doing things when dealing with values or numbers or instead of always using the #define is
Code: |
const int test = 0x42;
|
or
Code: |
rom int test =0x42;
|
You can also do this
Also you must know in some cases #define and typedef produce similar results.
For example
Code: |
#define WORD int16
typedef int16 WORD;
|
As you can see #define can do what const int does and it also does what typedef can do. The reverse is not always true.
So there are indeed many many ways to skin a cat.
Feel free to ask more questions. _________________ Clear Logic |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 24, 2010 3:24 am |
|
|
Using const and rom takes up space and can add extra processing, take for example:-
Code: |
#define max 10
#define min 20
int a = max * min;
|
The compiler should remove the equation completely in this case because it will compile to
int a = 10 * 20;
and then
int a = 200;
Using const or rom I would expect the compiler to read the value from memory and do the calculation.
If it does not then you could have a big problem as it would be possible to change the value in code using write_program_memory or whatever but this would not actually change the value in the equation! |
|
![](templates/subSilver/images/spacer.gif) |
Gavin Pinto
Joined: 18 Oct 2009 Posts: 27 Location: Australia
|
|
Posted: Wed Feb 24, 2010 3:37 am |
|
|
Wayne_ wrote: | Using const and rom takes up space and can add extra processing |
"const" construct, on the other hand, does all the type checking that the compiler does, so if you do something that's out of line you'll get a warning or an error.
It also makes the variable available in your debugger (by name). If it is only a few definitions, I think the const is a better practice (since the memory penalty is not going to be significant). If it is, then your system has no margin and requires a review.
1. They obey the language's scoping rules
2. You can see them in the debugger
3. You can take their address if you need to
4. They don't create new "keywords" in your program.
In short, const identifiers act like they're part of the language because they are part of the language. The preprocessor can be thought of as a language layered on top of C. You can imagine that the preprocessor runs as a separate pass through your code, which would mean your original source code would be seen only by the preprocessor, not by the C compiler itself. In other words, you can imagine the preprocessor sees your original source code and replaces all #define symbols with their values, then the C compiler proper sees the modified source code after the original symbols got replaced by the preprocessor.
There are cases where #define is needed, but you should generally avoid it when you have the choice. You should evaluate whether to use const vs. #define based on business value: time, money, risk. In other words, one size does not fit all. Most of the time you should use const rather than #define for constants, but sometimes you'll use #define. But please remember to wash your hands afterwards. _________________ Clear Logic |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Feb 24, 2010 5:20 am |
|
|
Gavin Pinto wrote: |
There are cases where #define is needed, but you should generally avoid it when you have the choice. You should evaluate whether to use const vs. #define based on business value: time, money, risk. In other words, one size does not fit all. Most of the time you should use const rather than #define for constants, but sometimes you'll use #define. But please remember to wash your hands afterwards. |
Based on your personal preference the .h files contained in CCS should be converted to const values ?
I agree, the programmer should decide on the method.
I personally am quite happy with using #define and would use rom to allow for changes without re-compilation.
Microsoft too have decided that using #define as well as other things like pointers is too dangerous for us mere mortals, so they have produced C# and .net So it is harder for us to make mistakes
Funny, considering windows is one of the most bug ridden pieces of software. I think they should re-write it in C#
So based on what you now know, you choose ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Gavin Pinto
Joined: 18 Oct 2009 Posts: 27 Location: Australia
|
|
Posted: Wed Feb 24, 2010 4:15 pm |
|
|
Non-modifiable lvalues vs. rvalues (see below for defination)
The crux of the problem with constant objects is that, while an enumeration constant is an rvalue, a constant object is a non-modifiable lvalue.
Enumeration constants are rvalues. As such, they have neither storage duration nor linkage. An enumeration constant cant be declared as static or extern. You can declare an enumeration constant in local or global scope and the declaration's scope is unlikely to affect the way the compiler generates code for the constant.
An advantage of constant objects over enumeration constants is that you can take the address of a constant object. The ability to take the address of a constant object sometimes leads compilers to generate unnecessary code, so maybe it's not much of an advantage after all.
I care about my code being compact and efficient. Since compilers are less likely to generate run-time storage and initialization code for enumeration constants than for constant objects, I'll stick with enumeration constants when I do not need to take the address and am dealing with int (we do not have choice of type with enum and are limited to int)
Lvalues and Rvalues
An object is a region of storage that can be examined and stored into. An lvalue is an expression that refers to such an object. An lvalue does not necessarily permit modification of the object it designates. For example, a const object is an lvalue that cannot be modified. The term modifiable lvalue is used to emphasize that the lvalue allows the designated object to be changed as well as examined. The following object types are lvalues, but not modifiable lvalues:
An array type
An incomplete type
A const-qualified type
An object is a structure or union type and one of its members has a const-qualified type
Because these lvalues are not modifiable, they cannot appear on the left side of an assignment statement.
The term rvalue refers to a data value that is stored at some address in memory. An rvalue is an expression that cannot have a value assigned to it. Both a literal constant and a variable can serve as an rvalue. When an lvalue appears in a context that requires an rvalue, the lvalue is implicitly converted to an rvalue. The reverse, however, is not true: an rvalue cannot be converted to an lvalue. Rvalues always have complete types or the void type. _________________ Clear Logic |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Feb 25, 2010 2:45 am |
|
|
Gavin Pinto and that is relevant because ? No mention of #define.
Also that description is full of inconsistancies:-
"and the declaration's scope is unlikely to affect the way the compiler generates code" (unlikely ?)
"Since compilers are less likely to generate run-time storage and initialization code for enumeration constants than for constant objects" (less likely)
nice description of enums v const ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Gav Pinto Guest
|
|
Posted: Thu Feb 25, 2010 3:46 am |
|
|
Wayne_ wrote: | And that is relevant because ? No mention of #define.
|
Wayne,
# define has already been discussed. Not necessary to repeat the reasons why I prefer not to use it. |
|
![](templates/subSilver/images/spacer.gif) |
|