454,498 Members | 1,740 Online
Need help? Post your question and get tips & solutions from a community of 454,498 IT Pros & Developers. It's quick & easy.

# pls expand this macro

 P: n/a /* ** PLURALTX.C - How to print proper plurals ** public domain - original algorithm by Bob Stout */ #include #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 Replies

 P: n/a sathyashrayan wrote: /* ** PLURALTX.C - How to print proper plurals ** public domain - original algorithm by Bob Stout */ #include #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

 P: n/a In article <43***************@REMOVETHISgmail.com>, sathyashrayan wrote: #define plural_text(n) &"s"[(1 == (n))] 1) I try to understand the two macros plural_text and plural_text2.array subscripting is commutativeso 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 thesecond one, in the above caseit 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

 P: n/a sathyashrayan wrote: /* ** PLURALTX.C - How to print proper plurals ** public domain - original algorithm by Bob Stout */ #include #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

 P: n/a 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 #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