difference between sizeof('a') and sizeof("a") - c

My question is about the sizeof operator in C.
sizeof('a'); equals 4, as it will take 'a' as an integer: 97.
sizeof("a"); equals 2: why? Also (int)("a") will give some garbage value. Why?

'a' is a character constant - of type int in standard C - and represents a single character. "a" is a different sort of thing: it's a string literal, and is actually made up of two characters: a and a terminating null character.
A string literal is an array of char, with enough space to hold each character in the string and the terminating null character. Because sizeof(char) is 1, and because a string literal is an array, sizeof("stringliteral") will return the number of character elements in the string literal including the terminating null character.
That 'a' is an int instead of a char is a quirk of standard C, and explains why sizeof('a') == 4: it's because sizeof('a') == sizeof(int). This is not the case in C++, where sizeof('a') == sizeof(char).

because 'a' is a character, while "a" is a string consisting of the 'a' character followed by a null.

Related

Why the strlen() function doesn't return the correct length for a hex string?

I have a hex string for example \xF5\x17\x30\x91\x00\xA1\xC9\x00\xDF\xFF, when trying to use strlen() function to get the length of that hex string it returns 4!
const char string_[] = { "\xF5\x17\x30\x91\x00\xA1\xC9\x00\xDF\xFF" };
unsigned int string_length = strlen(string_);
printf("%d", string_length); // the result: 4
Is the strlen() function dealing with that hex as a string, or is something unclear to me?
For string functions in the C standard library, a character with value zero, also called a null character, marks the end of a string. Your string contains \x00, which designates a null character, so the string ends there. There are four non-null characters before it, so strlen returns four.
C 2018 7.1.1 1 says:
A string is a contiguous sequence of characters terminated by and including the first null character… The length of a string is the number of bytes preceding the null character…
C 2018 7.24.6.3 2 says:
The strlen function computes the length of the string pointed to by s [its first argument].
You could compute the size of your array as sizeof string_ (because it is an array of char) or sizeof string_ / sizeof *string_ (to compute the number of elements regardless of type), but this will include a terminating null character because defining an array with [] and letting the length be computed from a string literal initializer includes the terminating null character of the string literal. You may need to hard-code the length of the array, possibly using #define to define a preprocessor macro, and use that length in the array definition and in other places where the length is needed.
It is because you have zero at index [4]
string_[0] == 0xF5
string_[1] == 0x17
string_[2] == 0x30
string_[3] == 0x91
string_[4] == 0
...
"\xf5" puts char having integer value 0xf5 at position [0]
To see it as a string you need to escape the \ character
const char string_[] = "\\xF5\\x17\\x30\\x91\\x00\\xA1\\xC9\\x00\\xDF\\xFF";
At compile time, your "string" appears as consecutive hex values expressed in C syntax inside a pair of quotation marks.
strlen() is a run time function that scans through a series of bytes, looking for the first instance of a zero-value byte.
It's good to understand the difference between "compile time" and "run time".

Output of the following

Code snippet
int main(){
printf(5 + "GeeksQuiz");
return 0;
}
Output is Quiz
Can you tell me how this output is coming.
Whats the logic behind it.
Addition is commutative. a + b is equal to b + a.
Adding an integer to a pointer increments follows pointer arithmetic. Adding an integer to a pointer increments it by so many elements as the integer count. So (int*)a + b is equal to (int*)((uintptr_t)a + b * sizeof(int))
sizeof(char) is always equal to 1.
"GeeksQuiz" is a string literal. strlen("GeeksQuiz") is equal 9. Accounting for the string terminating null byte, the type of the literal is char[10]. It's an array of 10 characters with the content {'G','e','e','k','s','Q','u','i','z','\0'}.
The C rules say, that an array of type is converted into a pointer to the first element of that array in most contexts. That happens here: (char[])"GeeksQuiz" is converted into a char* pointer to the first character 'G' in the string.
5 + "GeeksQuiz": "GeeksQuiz" is converted to the pointer to the first character. Then that pointer is incremented by 5. So the result of 5 + "GeeksQuiz" will be char* pointer that will point to the character 'Q' inside the string literal.
printf prints the null terminated string passed to it as the first character, except for conversions that start with %, which does not apply here.
To the printf function is passed the address of a pointer that points to the letter 'Q' inside the "GeeksQuiz" string literal.
printf increments the pointer until it will find the string terminating null byte. So it will print {'Q','u','i','z'}, as after z character it will find the null byte.

What is wrong with printing sizeof(char) and sizeof("a")?

The sizeof(char) in C gives 1 and sizeof("a") gives 2. Please help
A char i.e. a character has size 1.
The string literal "a" is not a character. It is a "string" (and by string I mean char[]). All "strings" in C are null-terminated, so your "string" is actually:
{'a','\0'}
And that's two characters. So size is 2.
sizeof("a")
"a" is a string that reads {'a','\0'}, which is 2 chars, or 2 bytes. This is because in C, double quotes indicate a string. A string in C is required to be null-terminated.
sizeof(char)
a single character is guaranteed to have the size 1 byte.
A sizeof(char) is 1 byte of size, where as "a" is a string which having 1byte for character and it will end with null '\0', so sizeof("a") is 2 byte.
'a' is not the same as "a"
at least for 8-bit CPUs like AVRs:
'a' is a single char and
sizeof('a') == 1,
the answer you expected.
"a" is a string as noted in the other answers.

How does c compare character variable against string?

The following code is completely ok in C but not in C++. In following code if statement is always false. How C compares character variable against string?
int main()
{
char ch='a';
if(ch=="a")
printf("confusion");
return 0;
}
The following code is completely ok in C
No, Not at all.
In your code
if(ch=="a")
is essentially trying to compare the value of ch with the base address of the string literal "a",. This is meaning-and-use-less.
What you want here, is to use single quotes (') to denote a char literal, like
if(ch == 'a')
NOTE 1:
To elaborate on the difference between single quotes for char literals and double quotes for string literal s,
For char literal, C11, chapter §6.4.4.4
An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'
and, for string literal, chapter §6.4.5
Acharacter string literal is a sequence of zero or more multibyte characters enclosed in
double-quotes, as in "xyz".
NOTE 2:
That said, as a note, the recommend signature of main() is int main(void).
I wouldn't say the code is okay in either language.
'a' is a single character. It is actually a small integer, having as its value the value of the given character in the machine's character set (almost invariably ASCII). So 'a' has the value 97, as you can see by running
char c = 'a';
printf("%d\n", c);
"a", on the other hand, is a string. It is an array of characters, terminated by a null character. In C, arrays are almost always referred to by pointers to their first element, so in this case the string constant "a" acts like a pointer to an array of two characters, 'a' and the terminating '\0'. You could see that by running
char *str = "a";
printf("%d %d\n", str[0], str[1]);
This will print
97 0
Now, we don't know where in memory the compiler will choose to put our string, so we don't know what the value of the pointer will be, but it's safe to say that it will never be equal to 97. So the comparison if(ch=="a") will always be false.
When you need to compare a character and a string, you have two choices. You can compare the character to the first character of the string:
if(c == str[0])
printf("they are equal\n");
else printf("confusion\n");
Or you can construct a string from the character, and compare that. In C, that might look like this:
char tmpstr[2];
tmpstr[0] = c;
tmpstr[1] = '\0';
if(strcmp(tmpstr, str) == 0)
printf("they are equal\n");
else printf("confusion\n");
That's the answer for C. There's a different, more powerful string type in C++, so things would be different in that language.
There is difference between 'a' (a character) and "a" (a string having two characters a and \0). ch=="a" comparison will be evaluated to false because in this expression "a" will converted to pointer to its first element and of course that address is not a character but a hexadecimal number.
Change it to
if(ch=='a')

C: sizeof() related doubts?

#include <stdio.h>
#include <string.h>
main()
{
printf("%d \n ",sizeof(' '));
printf("%d ",sizeof(""));
}
output:
4
1
Why o/p is coming 4 for 1st printf and moreover if i am giving it as '' it is showing error as error: empty character constant but for double quote blank i.e. without any space is fine no error?
The ' ' is example of integer character constant, which has type int (it's not converted, it has such type). Second is "" character literal, which contains only one character i.e. null character and since sizeof(char) is guaranteed to be 1, the size of whole array is 1 as well.
' ' is converted to an integer character constant(hence 4 bytes on your machine), "" is empty character array, which is still 1 byte('\0') terminated.
Here in below check the difference
#include<stdio.h>
int main()
{
char a= 'b';
printf("%d %d %d", sizeof(a),sizeof('b'), sizeof("a"));
return 0;
}
here a is defined as character whose data type size is 1 byte.
But 'b' is character constant. A character constant is an integer,The value of a character constant is the numeric value of the character in the machine's character set. sizeof char constant is nothing but int which is 4 byte
this is string literals "a" ---> array character whose size is number of character + \0 (NULL). Here its 2
This is answered in Size of character ('a') in C/C++
In C, the type of a character constant like 'a' is actually an int, with size of 4 (or some other implementation-dependent value). In C++, the type is char, with size of 1. This is one of many small differences between the two languages.
The 'space', or 'any single character', is actually of type integer, equal to the ASCII value of that character. So it's size will be 4 bytes.
If you create a character variable and store a character in it, then only it is stored in 1 byte memory.
char ch;
ch=' ';
printf("%d",sizeof(ch));
//outputs 1
For anything to be a string, it must be terminated with a null character represented as '\0'.
If we write a string "hello", it is actually stored as 'h' 'e' 'l' 'l' 'o' '\0', so that the system knows string ends after the 'o' in "hello" and it stops reading when null character comes. The length of this string is still 5 if you use strlen() function but actually the sizeof(string) is 6 bytes.
When we create an empty string, like "", it's length is 0 but size is 1 byte as it must terminate where it starts, i.e. at 0th character.
Hence an empty string consists of only one character, that is null character, giving size 1 byte.
From C Traps and Pitfalls
Single and double quotes mean very different things in C.
A Character enclosed in single quotes is just a another way of writing the integer that corresponds to the given character in ASCII implementation. Thus ' ' means exactly same thing as 32.
On the other hand, A string enclosed in double quotes is a short-hand way of writing a pointer to the initial character of a nameless array that has been initialized with the characters between the quotes and an extra character whose binary value is zero. Thus writing "" that is empty string still has '\0' character whose size is one.
because of in 1st case there is a character that's why sizeof operator is take the SACII value of character and it's take as an integer so in 1st case it will give you 4.
in 2nd case sizeof operator take as a string and in string there is no data means it's understood NULL string , so NULL string size is 1, that's why it will give you answer as a 1.

Resources