The usage of a backslash character(\) in an char assignment expression - c

char C = '\1'
int I = -3
printf("%d", I * C);
output:
-3
Hi, I just saw this weird syntax in my practice book, but it doesn't give me much detail about what it is and its usage. Why is there a backslash next to 1 in the quotation mark? Is '\1' any different from '1'? If so, why the result of I * C is the same as 1 * 3? Thank you

In the initializer of the variable C
char C = '\1';
there is used an octal escape sequence. That is the digits after the backslash are considered as an octal representation of a number.
The number of digits in the octal escape sequence shall not be greater than 3 and the allowed digits are 0-7 inclusively.
For example this declaration
char C = '\11';
initializes the variable C with the value 9.
So the expression used in the call of printf
printf("%d", I * C);
is equivalent to
printf("%d", -3 * 1);
And the output will be -3.
Instead of the octal escape sequence you could use hexadecimal escape sequence like
char C = '\x1';
this declaration is equivalent to the previous declaration of the variable C like
char C = '\1';
If to initialize the variable like
char C = '\x11';
then the variable C will get the value 17.
The number of digits in the octal escape sequence shall not be greater than 3 and the allowed digits are 0-7 inclusively.
As for a declaration like this
char C = '1';
then the variable C is initialized by the value of the internal representation of the character '1'. For example if the ASCII coding is used the variable C is initialized by the value 49. If the EBCDIC coding is used then the variable C is initialized by the value 241.

The '1' is the character “1”. Most platforms nowadays use ASCII to translate characters into bytes — '1' in ASCII is an integer 49 in decimal or 0x31 in hex.
From cppreference escape sequence:
\nnn arbitrary octal value byte nnn
Octal escape sequences have a limit of three octal digits, but terminate at the first character that is not a valid octal digit if encountered sooner.
The '\1' is an integer 0x1 in hex or 1 in decimal. In ASCII, it is a SOH character — start of heading.
The:
char C = '\1';
is equivalent to:
char C = 1;

'1' is internally a byte whose value is 49 (the ASCII code of symbol 1).
'\1' is a byte whose value is 1.

Related

How this C code working. I'm getting 56 as output for '\08' [duplicate]

This question already has answers here:
Printing char by integer qualifier
(4 answers)
Closed 3 years ago.
Output of this code is 56.
// Output : 56
#include <stdio.h>
int main() {
char c = '\08';
printf("%d",c);
return 0;
}
As #stark commented, Your constant consists of 2 bytes '\0' and '8'. These are truncated to '8' when stored in the variable c.
In ASCII Character Chart you can see that 8 is 56 in ASCII, and you get that because you use the %d format specifier to print:
You could have seen that yourself, if you paid attention to your warnings:
main.c:4:14: warning: multi-character character constant [-Wmultichar]
4 | char c = '\08';
|
Moreover, I suggest you try printing like this:
printf("%c", c);
and then the output would be:
8
which shows you what was really stored in the variable c.
Tip: If you use char c = '\01'; or char c = '\07'; and anything in between, you will see no warning and the corresponding number being printed, because these are valid octal digits, as #Gerhardh's answer mentions.
In C strings or character literals, it is possible to escape hexadecimal or octal values.
the prefix '\0' is used for octal values, while '\x' is used for hex values.
This means '\0' is equal to value 0, '\011' is equal to 9 etc.
In your case a '8' follows which is no valid octal digit. Therefore the escape sequence stops there and your literal is same as value 0 followed by character '8'.
Now you have a character literal with more than 1 character. This is a multibyte character literal and the value of this literal is implementation dependend.
In your case the final value of the character is the value of the last character, e.g. '8' which has ascii value 0x38 or 56.
As you print this as a decimal number, you get 56.
Its taking value of '8' as char. In ASCII its 56. Basicly char holds only 1 character

How is the string terminator '\0' has the same value as integer constant 0?

I have the following code -
#include <stdio.h>
#define LENGTH 5
int main(){
char* ch[LENGTH] = {"Zero", "One", "Two", "Three", "Four"};
char* pc;
char** ppc;
for(int i=0; i<LENGTH; i++){
ppc = ch+i;
pc = *ppc;
while(*pc != 0){
printf("%c ", *pc);
pc = pc +1;
}
printf("\n");
}
return 0;
}
It is an example of multiple indirection using string.
The output is
Z e r o
O n e
T w o
T h r e e
F o u r
Here in while() loop instead of *pc != '\0', *pc != 0 is used.
But both the approaches give same output. Why is it so?
A char is really nothing more than a small integer, and as such are implicitly convertible to int. Furthermore character literals (like e.g. 'A') are really represented by the compiler as int values (for example the literal character 'A' is represented by the int value 65 in ASCII encoding).
The C language allows one to insert any arbitrary integer (that can fit in a char) using escapes. There are two ways to escape such arbitrary values, using octal numbers, or using hexadecimal. For example, the ASCII value for A is 65, that can be represented as either 'A', '\101' in octal, '\x41' in hexadecimal, or plain 65.
Armed with that information it should be easy to see that the character literal '\0' is the octal representation of the integer 0. That is, '\0' == 0.
You can easily verify this by printing it:
printf("'\\0' = %d\n", '\0');
I mentioned that the compiler treats all character literals as int values, but also mentioned that the arbitrary numbers using escaped octal or hexadecimal numbers needs to fit in a char. That might seem like a contradiction, but it isn't really. A characters value must fit in a char, but the compiler will then internally convert it to an int when it parses the code.
Line feed \n, tab \t etc has their own escape sequence characters, but actually there does not exist one for the null terminator.
The industry de facto standard way of represending the null terminator is therefore to write an octal escape sequence with the value zero. Octal escape sequences are defined as \ followed by a number. So \0 simply means zero, with octal representation. Since this looks similar to other character escape sequences, it has become the de facto standard way of representing the null terminator.
This is why a decimal 0 works just as fine, it is just another way of writing the value zero. You could as well write \x0 if you wish to be obscure.
0 and '\0' are exactly the same value, and in C, are both int types. This is fixed by the C standard and is irrespective of the character encoding on your platform. In other words, they are completely indistinguishable. (In C++, the type of '\0' is a char.)
So while(*pc != 0), while(*pc != '\0'), and while(*pc) for that matter are all the same thing.
(Personally I find the last one I give the clearest, but some folk like to use the '\0' notation when working with C-style strings.)
Adding to the existing answers, to look into the sentinel, quoting C11, chapter §5.2.1
In a character constant or string literal, members of the execution character set shall be
represented by corresponding members of the source character set or by escape
sequences consisting of the backslash \ followed by one or more characters. A byte with
all bits set to 0, called the null character, shall exist in the basic execution character set; it
is used to terminate a character string.
and from chapter §6.4.4.4/P12,
EXAMPLE 1 The construction '\0' is commonly used to represent the null character.
So, a constant \0 is the one which satisfies the aforesaid property. This is a octal escape sequence.
Now, regarding the value, quoting §6.4.4.4/P5, (emphasis mine)
The octal digits that follow the backslash in an octal escape sequence are taken to be part
of the construction of a single character for an integer character constant or of a single
wide character for a wide character constant. The numerical value of the octal integer so
formed specifies the value of the desired character or wide character.
so, for a octal escape sequence '\0', the value is 0 (well, both in octal, as mentioned in §6.4.4.1, and decimal).

Using int to print character constants [duplicate]

This question already has answers here:
Multi-character constant warnings
(6 answers)
Print decimal value of a char
(5 answers)
Closed 5 years ago.
I wrote the following program,
#include<stdio.h>
int main(void)
{
int i='A';
printf("i=%c",i);
return 0;
}
and I got the result as,
i=A
So I tried another program,
#include<stdio.h>
int main(void)
{
int i='ABC';
printf("i=%c",i);
return 0;
}
According to me, since 32 bits are used to store an int value and each of 'A', 'B' and 'C' have 8 bit ASCII codes which totals to 24 bits therefore 24 bits were stored in a 32 bit unit. So I expected the output to be,
i=ABC
but the output instead was
i=C
and I can't understand why?
'ABC' in this case is a integer character constant as per section 6.4.4.4.10 of the standard.
An integer character constant has type int. The value of an integer
character constant containing a single character that maps to a
single-byte execution character is the numerical value of the
representation of the mapped character interpreted as an integer. The
value of an integer character constant containing more than one
character (e.g.,'ab'), or containing a character or escape sequence
that does not map to a single-byteexecution character, is
implementation-defined. If an integer character constant contains a
single character or escape sequence, its value is the one that results
when an object with type char whose value is that of the single
character or escape sequence is converted to type int.
In this case, 'A'==0x41, 'B'==0x42, 'C'==0x43, and your compiler then interprets i to be 0x414243. As said in the other answer, this value is implementation dependent.
When you try to access it using '%c', the overflown part will be cut and you are only left with 0x43, which is 'C'.
To get more insight to it, read the answers to this question as well.
The conversion specifier c used in this call
printf("i=%c",i);
in fact extracts one character from the integer argument. So using this specifier you in any case can not get three characters as the output.
From the C Standard (7.21.6.1 The fprintf function)
c If no l length modifier is present, the int argument is converted to
an unsigned char, and the resulting character is written
Take into account that the internal representation of a multi-byte character constant is implementation defined. From the C Standard (6.4.4.4 Character constants)
...The value of an integer character constant containing more than one character (e.g., 'ab'), or containing a character or escape
sequence that does not map to a single-byte execution character, is
implementation-defined.
'ABC' is an integer character constant. Depending on code set (overwhelming it is ASCII), endian, int width (apparently 32 bits in OP's case), it may have the same value like below. It is implementation defined behavior.
'ABC'
0x41424300
0x434241
or others.
The "%c" directs printf() to take the int value, cast it to unsigned char and print the associated character. This is the main reason for apparent loss of information.
In OP's case, it appears that i took on the value of 0x434241.
int i='A';
printf("i=%c",i); --> 'A'
// same as
printf("i=%c",0x434241); --> 'A'
if you want i to contain 3 characters you need to init a array that contains 3 characters
char i[3];
i[0]= 'A';
i[1]= 'B';
i[2]='C';
the ' ' can contain only one char your code converts the integer i into a character or better you store in your 32 bit intiger a converted 8 bit character. But i think You want to seperate the 32 bits into 8 bit containers make a char array like char i[3]. and then you will see that
int j=i;
this will result in an error because you are unable to convert a char array into a integer.
In C, 'A' is an int constant that's guaranteed to fit into a char.
'ABC' is a multicharacter constant. It has an int type, but an implementation defined value. The behaviour on using %c to print that in printf is possibly undefined if the value cannot fit into a char.

What does it mean to subtract '0' from a variable in C?

void push(float[],float);
Here, st[] is float data-type stack and exp[] is char data-type array storing postfix expression.
push(st,(float)(exp[i]-'0'));
I couldn't figure out the purpose of (exp[i]-'0') section though. Why are we subtracting '0'?
A character is basically nothing more than an integer, whose value is the encoding of the character.
In the most common encoding scheme, ASCII, the value for e.g. the character '0' is 48, and the value for e.g. '3' is 51. Now, if we have a variable someChar containing the character '3' and you do someChar - '0' it's the same as doing 51 - 48 which will result in the value 3.
So if you have a digit read as a character from somewhere, then you subtract '0' to get the integer value of that digit.
This also works on other encodings, not only ASCII, because the C specification says that all encodings must have the digits in consecutive order.
Note that this "trick" is not guaranteed to work for any non-digit character.

Octal representation inside a string in C

In the given program:
int main() {
char *p = "\0777";
printf("%d %d %d\n",p[0],p[1],p[2]);
printf("--%c-- --%c-- --%c--\n",p[0],p[1],p[2]);
return 0;
}
It is showing the output as:
63 55 0
--?-- --7-- ----
I can understand that it is converting the first two characters after \0 (\077) from octal to decimal but can any one explain me why 2 characters, why not 1 or 3 or any other ?
Please explain the logic behind this.
char *p = "\07777";
Here a string literal assigned to a pointer to a char.
"\07777"
In this string literal octal escape sequence is used so first three digits represents a octal number.because rules for octal escape sequence is---
You can use only the digits 0 through 7 in an octal escape sequence. Octal escape sequences can never be longer than three digits and are terminated by the first character that is not an octal digit. Although you do not need to use all three digits, you must use at least one. For example, the octal representation is \10 for the ASCII backspace character and \101 for the letter A, as given in an ASCII chart.
SO your string literal stored in memory like
1st byte as a octal number 077 which is nothing but 63 in decimal and '?' in character
2nd and 3rd byte as a characters '7' and '7' respectively
and a terminating character '\0' in last.
so your answer are as expected 1st,2nd,3d byte of the string literal.
for more explanation you can visit this web site
http://msdn.microsoft.com/en-us/library/edsza5ck.aspx
It's just the way the language defines octal escape sequences.
An octal escape sequence, which can be part of a character constant or string literal, consists of a \ followed by exactly 1, 2, or 3 octal digits ('0' .. '7').
In "\07777", the backslash is followed by 3 octal digits (0, 7, 7), which represents a character with the value 077 in octal, or 63 in decimal. In ASCII or an ASCII-derived encoding, that happens to be a question mark '?'.
So the literal represents a string with a length of 3, consisting of '?', '7', '7'.
But there must be a typo in your question. When I run your program, the output I get is:
63 55 55
--?-- --7-- --7--
If I change the declaration of p to
char *p = "\0777";
I get the output you describe. Note that the final ---- is really two hyphens, followed by a null character, followed by two hyphens. If you're on a Unix-like system, try piping the program's output through cat -v or cat -A.
When you post code, it's very important to copy-and-paste it, not retype it.
(And you're missing the #include <stdio.h> at the top.)

Resources