473,405 Members | 2,261 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

pls expand this macro


/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/
#include <stdio.h>
#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?

3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

Can any one explain both of the macros.
--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
Nov 15 '05 #1
8 1735
sathyashrayan wrote:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/
#include <stdio.h>
#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?
* the macro doesn't know the type of the variable.
if you expand the macro, it looks like this

case 1 / plural_text(0) : &"s"[0]
...
2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?
* "&" operand will make the right-side variable's pointer
so it makes the array of string which started from the index value
of the array..

3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?
* << operator shifts the result of "(1==(n))",
so its last value is only be "0" or "2"
"0" will be the "es"
"2" will be the NULL

so you can see the boxes, or box

Can any one explain both of the macros.
--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com


I'm poor at english.

- Park, Sung-jae
Nov 15 '05 #2
In article <43***************@REMOVETHISgmail.com>,
sathyashrayan <sa***********@REMOVETHISgmail.com> wrote:
#define plural_text(n) &"s"[(1 == (n))] 1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
No, there is no assignment done. (1 == (n)) is an expression which
produces a value which is either 0 or 1, and the string "s" is indexed
at that offset, and the address (&) of the result is taken.
&"s"[0] is a pointer to the 's' character in a string, but
&"s"[1] is a pointer to the nul that follows the 's'.

In other words the result is either the string "s" or the empty string.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?


No, treat the inside as an expression again and look at the offsets
into the string.
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
Nov 15 '05 #3
sathyashrayan wrote:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/
#include <stdio.h>
#define plural_text(n) &"s"[(1 == (n))]
This is equivalent to ( "s" + (1 == (n) ) )
ie. adding 0 or 1 to the starting address of the string literal "s". If
adding zero, the result is a pointer to the string "s". If adding one,
the result is a pointer to the string "".
#define plural_text2(n) &"es"[(1 == (n))<<1]
This is equivalent to ( "es" + (1 == (n)) * 2 )
ie. adding 0 or 2 to the starting address of the string literal "es". If
adding zero, the result is a pointer to the string "es". If adding two,
the result is a pointer to the string "".
int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i),
i, plural_text2(i));
return 0;
}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
That's irrelevant. This code uses array subscripting in the usual way,
with the array on the left, and the subscript between the brackets.
so in the above we could expand the macros as plural_text n[1] = "s" .
No. Not at all. The invocation
plural_text(i)
expands to the following eleven tokens:
& "s" [ ( 1 == ( i ) ) ]
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?
No. It acts on an expression, not a variable. The parenthesis are in
case the expression given contains other operators that may affect the
parsing.
2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?
The & operator is not applied to the array. It is applied to the
expression containing the subscript. That is, it is parsed as
& ( "s"[(1 == (i))] )
rather than
(& "s") [(1 == (i))]

Here's one way to understand it: "s" is an array of two char. That array
is subscripted, to give an lvalue referring to either the first or
second element of the array, and then the address-of operator is applied
to the lvalue, giving a pointer to the first or second element of the array.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?


The << operator is a binary shift on an integer value. Shifting left by
one bit is equivalent to multiplying by two. It has the effect of
changing a value that could be 0 or 1, into a value that could be 0 or 2
respectively.

--
Simon.
Nov 15 '05 #4
On Sun, 30 Oct 2005 18:55:14 +0530, sathyashrayan wrote:
/*
** PLURALTX.C - How to print proper plurals ** public domain -
original algorithm by Bob Stout */
#include <stdio.h>
#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
That expansion isn't correct. In this situation, the array is "s". "s"
is known as a string literal and here it is equivalent to a char array of
size two, first member 's' and second member '\0' ('\0' is the string
terminating character which is identical to integer 0, and is sometimes
confusing referred to as NUL).

So indexing can be applied to that array:
"s"[0] gives the first array element, the character 's'
"s"[1] gives the second array element, the terminating character '\0'.

This has the same effect as first declaring:
char str[2] = "s";
and then indexing as:
str[0] and str[1]

The property of subscripting that you're referring to means that:
str[0] is identical to writing 0[str]
str[1] is identical to writing 1[str]
"s"[0] is identical to writing 0["s"]
"s"[1] is identical to writing 1["s"]
"s"[(1 == (n))] is identical to writing (1 == (n))["s"]
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?
The macro doesn't and can't know the type of its parameter and parentheses
do nothing to help it. What they're actually there for is to prevent
unintended precedence if n is a complex expression.

It might be easier to consider a simpler situation to show why
parenthesising macro parameters is good practice. The result of double(x
+ 1) and double_safe(x + 1) given the code below will be different, and
only the second form will give the expected result:

#define double(n) 2 * n
#define double_safe(n) 2 * (n)
int x = 1;
2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into the pointer to it's first
element"?
Actually the & operator isn't making direct use of that rule. See the
description below.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?


The second macro:
#define plural_text2(n) &"es"[(1 == (n))<<1]

can be simplified to:
#define plural_text2(n) &string_array[index]

where string_array is "es" and index is (1 == (n))<<1

Now consider (1 == (n))

This will be 1 when n is 1 and 0 when n is other than 1.

So the index will be either:
1<<1, or 0<<1

The first expression results in 2, and the second results in 0.

So "es" is being indexed at 2 or 0, and then its address is taken.

Indexing "es" at 2 results in the terminating '\0' character element, and
the & operator returns the address of this element. The final result is
an empty string (a pointer to a terminating character element).

Indexing "es" at 0 results in the first character element, 'e', and the &
operator returns the address of this element, which is the same as the
string "es" (because being an array, "es" decays into a pointer to its
first element - this is the rule you described).

So when n is 1, the macro results in an empty string - which is expected -
a single element doesn't have a plural form. When n is 0 or greater than
1, the macro results in the string "es" - which is again expected.

--
http://members.dodo.com.au/~netocrat
Nov 15 '05 #5


Simon Biber wrote:
sathyashrayan wrote:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/
#include <stdio.h>
#define plural_text(n) &"s"[(1 == (n))]
This is equivalent to ( "s" + (1 == (n) ) )
ie. adding 0 or 1 to the starting address of the string literal "s".


"s" is the variable at the base address of the array. == evaluates to true or
false. So if
the array's size should 1 as per the result of == operator evaluation. So
("s" + (1 == (n))) is base + index of array. Correct?

If
adding zero, the result is a pointer to the string "s". If adding one,
the result is a pointer to the string "".
" " in the above sence is '\0' , nul?
#define plural_text2(n) &"es"[(1 == (n))<<1]


This is equivalent to ( "es" + (1 == (n)) * 2 )
ie. adding 0 or 2 to the starting address of the string literal "es". If
adding zero, the result is a pointer to the string "es". If adding two,
the result is a pointer to the string "".

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i),
> i, plural_text2(i));
return 0;
}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
That's irrelevant. This code uses array subscripting in the usual way,
with the array on the left, and the subscript between the brackets.


Macros are text replacement. So 'n' is replaced with
&"s"[(1 == (n))]

or simply

"s"[0] or "es"[n*2]
So the commutative rule does not apply hear. Correct?

so in the above we could expand the macros as plural_text n[1] = "s" .
No. Not at all. The invocation
plural_text(i)
expands to the following eleven tokens:
& "s" [ ( 1 == ( i ) ) ]


understood
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?
No. It acts on an expression, not a variable. The parenthesis are in
case the expression given contains other operators that may affect the
parsing.


Arguments in macros evaluates only once for every call and also itself.
There is a famous example covered in almost all C books about macro pit fall.
I dont remember that at present.

2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?


The & operator is not applied to the array. It is applied to the
expression containing the subscript. That is, it is parsed as
& ( "s"[(1 == (i))] )
rather than
(& "s") [(1 == (i))]

Here's one way to understand it: "s" is an array of two char. That array
is subscripted, to give an lvalue referring to either the first or
second element of the array, and then the address-of operator is applied
to the lvalue, giving a pointer to the first or second element of the array.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?


The << operator is a binary shift on an integer value. Shifting left by
one bit is equivalent to multiplying by two. It has the effect of
changing a value that could be 0 or 1, into a value that could be 0 or 2
respectively.

--
Simon.


Thanks. I am clear with the rest of explanation.
--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
Nov 15 '05 #6
thanks for all the explanation.

sathyashrayan wrote:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/

#include <stdio.h>

#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?

3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

Can any one explain both of the macros.
--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com


--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
Nov 15 '05 #7
[sniped...]

Arguments in macros evaluates only once for every call and also itself.
There is a famous example covered in almost all C books about macro pit fall.
I dont remember that at present.
netocrat explained the answer in the other thread.


[

Nov 15 '05 #8
sathyashrayan wrote:
Simon Biber wrote:
sathyashrayan wrote:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/

#include <stdio.h>

#define plural_text(n) &"s"[(1 == (n))]
This is equivalent to ( "s" + (1 == (n) ) )
ie. adding 0 or 1 to the starting address of the string literal "s".


"s" is the variable at the base address of the array. == evaluates to true or
false. So if
the array's size should 1 as per the result of == operator evaluation. So
("s" + (1 == (n))) is base + index of array. Correct?


When an array is used in any expression, except as the argument of & or
sizeof, it is implicitly converted into a pointer to the first element
of an array.

"s" is an array. The size of the array is 2. The first element of the
array is (char) 's', and the second element of the array is (char) 0,
ie. a null character.

Here it is used as the argument of the [ ] operator (in the original),
or the + operator (in my equivalent expression), but not the & operator.
So, it is implicitly converted into a pointer to the first element of
the array. That pointer points to the 's' character.

If the parameter n has the value 1, then the expression (1 == (n))
evaluates to 1, and the result is a pointer to the second element of the
array, which is a null character.

A pointer to a null character is an empty string, and so when passed to
printf with the %s specifier, nothing will be printed.
If
adding zero, the result is a pointer to the string "s". If adding one,
the result is a pointer to the string "".

" " in the above sence is '\0' , nul?


I wrote "" (with nothing between the quotes), not " " (with a space
between the quotes). The result is a pointer to the null character of
the string "s".

The term "nul" is ASCII-specific, and is not the correct term used in C.
My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative


That's irrelevant. This code uses array subscripting in the usual way,
with the array on the left, and the subscript between the brackets.

Macros are text replacement. So 'n' is replaced with
&"s"[(1 == (n))]


Macros are expanded as preprocessing tokens, rather than plain text, but
the effect is usually the same.

What makes you think 'n' is replaced with anything?
Suppose I write out the tokens, one on each line, with
...
...
...
representing a sequence of zero or more tokens.

When the preprocessor comes across the tokens
plural_text
(
...
...
...
)

they are replaced with
&
"s"
[
(
1
==
(
...
...
...
)
)
]
or simply

"s"[0] or "es"[n*2]
No! You have left out the & operator. And n is never multiplied by 2.

The result of plural_text(i) is always a pointer to one of the elements
of the string literal "s". Either a pointer to the 's' or a pointer to
the null character.

The result of plural_text2(i) is always a pointer to one of the elements
of the string literal "es". Either a pointer to the 'e' or a pointer to
the null character.
So the commutative rule does not apply hear. Correct?


The commutative rule for array subscripting means that
array[index]
is equivalent to
index[array]

But in these two macros, the array is in the conventional position on
the left of the brackets, and the index is in the conventional position
between the brackets. There is no need to apply the rule.

--
Simon.
Nov 15 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Adam Endicott | last post by:
I'm having some trouble using an HtmlListBox with a GridBagSizer. I'm not sure how best to explain what's happening, but it seems that every time my frame gets resized, the HtmlListBox grows...
1
by: James Hurrell | last post by:
Hi, I'm using the following javascript function to expand and collapse portions of text in a web page (targeted at IE5.5 and above): function doExpand(paraNum,arrowNum) { if...
8
by: 2centbob | last post by:
Has anyone had an issue with SQL Server not being able to expand against a RAID 5 file system? My current configuration is that the server is started and stopped using the local system account. I...
1
by: Randy Starkey | last post by:
Hi, Is there a way to expand and collapse all if I have multiple implementations of this script on a single page? The script works well individually. Thanks! --Randy Starkey ---
4
by: Karim El Jed | last post by:
Hi, I'm trying to expand a special Node of my TreeView from Codebehind. I have a TreeView on a page for navigating to another site. On the other tsite here is the same TreeView more precisely a...
0
by: Shadow Lynx | last post by:
When using ASP.NET 2.0's built-in TreeView on a page with <BASE target = "AnythingBut_Self"></BASE> in the HEAD, the expand/collapse buttons fail to function. The reason for this is that the...
7
by: Benzi Eilon | last post by:
I am executing an Expand command in order to expand a CAB file. This is done by calling CreateProcess with the Expand command and then WaitForSingleObject and checking the process exit code. My C++...
11
by: Nospam | last post by:
I don't know what it is I am doing wrong, I am trying to get the menus to either expand or contract based on their previous states, i.e if already expanded if clicked again contract, and if...
12
by: Fabrice | last post by:
Hi, Lets say I want to define a generic macro to swap bytes in a integer: #define swapbytes(x) ... I have several implementation of the macros, one is generic C, the other one will be an...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.