January 23rd, 2013, 03:32 AM
-
Working with strings!!!!
Hello guys i have 4 scenarios and I dont know exactly why this happens .......
SCENARIO 1: USING POINTERS....
Code:
#include<stdio.h>
#include<conio.h>
int main()
{
char* ch1="hello";
char* ch2={'h','e','l','l','o'};
printf("Size of string array is %d\n",sizeof(ch1));
printf("Size of character array is %d\n",sizeof(ch2));
getch();
return 0;
}
OUTPUT:
Size of string array is 4
Size of character array is 4
SCENARIO 2 : SOME MINOR CHANGE NOW ITS NOT A POINTER BUT WITH BRACES
Code:
#include<stdio.h>
#include<conio.h>
int main()
{
char ch1[]="hello";//* CHANGED TO []
char ch2[]={'h','e','l','l','o'};//* CHANGED TO []
printf("Size of string array is %d\n",sizeof(ch1));
printf("Size of character array is %d\n",sizeof(ch2));
getch();
return 0;
}
OUTPUT:
Size of string array is 6
Size of character array is 5
SCENARIO 3:USING STRLEN FUNCTION
Code:
#include<stdio.h>
#include<conio.h>
int main()
{
char *ch1="hello";
char *ch2={'h','e','l','l','o'};
printf("Size of string array is %d\n",strlen(ch1));
printf("Size of character array is %d\n",strlen(ch2));
getch();
return 0;
}
OUTPUT:
Size of string array is 5 //prints nothing after this...
SCENARIO 4:USING BRACES AND STRLEN
Code:
#include<stdio.h>
#include<conio.h>
int main()
{
char ch1[]="hello";
char ch2[]={'h','e','l','l','o'};
printf("Size of string array is %d\n",strlen(ch1));
printf("Size of character array is %d\n",strlen(ch2));
getch();
return 0;
}
OUTPUT:
Size of string array is 5
Size of character array is 5
Q2:
I need to know what exactly happens and when is '\0' used for.
can we also use '\0' like char ch[]={'h','h','h','\0'};
in some places i found they just used 0 ie char ch[]={'h','h','h','0'};
January 23rd, 2013, 03:34 AM
-
i thought int *ptr is same as ptr[]
ie all pointers are infact arrays......... is my assumption correct?
January 23rd, 2013, 04:09 AM
-
> i thought int *ptr is same as ptr[]
> ie all pointers are infact arrays......... is my assumption correct?
No, they are related, but they're not interchangeable.
http://c-faq.com/aryptr/index.html
> SCENARIO 1: USING POINTERS....
You're printing the size of a pointer, which disregards what it is pointing to.
You can have char *ch; or char *ch = NULL; and still get the same answer out of sizeof.
> SCENARIO 2 : SOME MINOR CHANGE NOW ITS NOT A POINTER BUT WITH BRACES
Now you have an array, whose size is determined by the number of initialisers.
"hello" returns 6 because of the implied \0 at the end.
A char array filled one char at a time has no \0.
> SCENARIO 3:USING STRLEN FUNCTION
strlen relies on a \0 at the end to mark the end of the string.
Initialising a char pointer with character literals should have gotten you a load of error messages. Running it would just crash/lockup or something.
> SCENARIO 4:USING BRACES AND STRLEN
The fact that char ch2[]={'h','e','l','l','o'}; results in 5 being printed is down to pure dumb luck. There is no explicit \0, so strlen will just keep going until it finds one or the OS kills the program.
> I need to know what exactly happens and when is '\0' used for.
\0 marks the end of character strings.
As you've seen, the most convenient way of doing this is to put your "string" in double quotes.
> can we also use '\0' like char ch[]={'h','h','h','\0'};
Yes you can (and you should if you want to use str... functions on such an array).
> in some places i found they just used 0 ie char ch[]={'h','h','h','0'};
Maybe they really wanted an array of 4 chars with no \0 at the end, containing "hhh0".
Or it's a bug waiting to happen (something assumes a \0 and there isn't one).
Or you mis-read and it really was \0
Comments on this post
January 23rd, 2013, 06:40 AM
-
nicely answered ...
1 question:
from scenario 1 do you mean that every pointer has size of 4 bytes ... whatever type it maybe ,int,float,char or double??????
January 23rd, 2013, 07:09 AM
-
> from scenario 1 do you mean that every pointer has size of 4 bytes ... whatever type it maybe ,int,float,char or double??????
It's common, but not guaranteed.
Pointers are 8 bytes on my 64-bit machine.
Also, the standard only guarantees the conversion T* -> void* -> T*
That is, you can cast any pointer to void* and back again.
But try char* to int* and you're on your own.
January 23rd, 2013, 07:57 AM
-
when i say char *ch2={'h','e','l','l','o'};
as you said it will not have null terminator right? so it does not end?
when i use strlen there it breaks program.... does that mean we cannot apply string functions to it?
January 23rd, 2013, 08:20 AM
-
> when i say char *ch2={'h','e','l','l','o'};
This won't even compile, so running is a meaningless question.
January 23rd, 2013, 08:26 AM
-
it works bro i have used it in all programs ... it compiled only it didnt work for strlen....even if it compiled
January 23rd, 2013, 08:36 AM
-
Your crappy TurboC might compile it, but any decent compiler will complain about everything.
Code:
$ cat bar.c
#include<stdio.h>
int main()
{
char *ch1="hello";
char *ch2={'h','e','l','l','o'};
printf("Size of string array is %d\n",strlen(ch1));
printf("Size of character array is %d\n",strlen(ch2));
return 0;
}
$ gcc -W -Wall bar.c
bar.c: In function ‘main’:
bar.c:6:1: warning: initialization makes pointer from integer without a cast [enabled by default]
bar.c:6:1: warning: (near initialization for ‘ch2’) [enabled by default]
bar.c:6:1: warning: excess elements in scalar initializer [enabled by default]
bar.c:6:1: warning: (near initialization for ‘ch2’) [enabled by default]
bar.c:6:1: warning: excess elements in scalar initializer [enabled by default]
bar.c:6:1: warning: (near initialization for ‘ch2’) [enabled by default]
bar.c:6:1: warning: excess elements in scalar initializer [enabled by default]
bar.c:6:1: warning: (near initialization for ‘ch2’) [enabled by default]
bar.c:6:1: warning: excess elements in scalar initializer [enabled by default]
bar.c:6:1: warning: (near initialization for ‘ch2’) [enabled by default]
bar.c:8:1: warning: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
bar.c:8:39: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
bar.c:8:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat]
bar.c:9:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat]
A lack of error messages is not a proof of correctness.
A lack of crashing is not a proof of correctness.
The code is plain and simple broken.
January 23rd, 2013, 11:15 AM
-
Originally Posted by swapy
it works bro i have used it in all programs ... it compiled only it didnt work for strlen....even if it compiled
I have to remember back about 20 years, but as I recall Turbo C gave you the option to turn warnings on or off and might have even allowed you to filter them so that only the most dire warnings would show.
Here are some absolutely essential rules to live by:
Always turn warnings on and up!
Never ignore warnings!
Warnings are much more important than error messages!
Just because you get no errors does not mean that your program compiled cleanly. If you write something really stupid, the compiler might still be able to generate some code, but it most likely won't be what you intended! If you write something stupid, it will confuse the compiler and force the compiler to make assumptions. A confused compiler that's making assumptions is a very dangerous beast indeed! Because the executable that it creates will do something, but it won't do what you wanted it to do.
Always turn warnings on and up (meaning to display all warnings, not just the most dire warnings; IOW, do not filter warnings). Never ignore warnings. Always remember that warnings are much more important than error messages are.