This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 6 years ago.
#include <stdio.h>
int main(){
char *ch = "Hello, World";//character pointer pointing to a string without declaration.
printf("%s", ch);//printing the string without <i>dereferencing</i> it.
}
I saw an example in a book, with code as given above. I don't understand how a character pointer points to a string without declaring a string first.Also there is no dereference operator used to print the string.
As stated very well by #tryurbest, Why it works with pointers:
When you say char * ch in C, you are allocating a pointer in the memory. When you write char *ch = "Hello, World";, you are creating a string literal in memory and making the pointer point to it. When you create another string literal "new string" and assign it to ch, all you are doing is changing where the pointer points.
On the other hand, for added information, Why it doesn't work with arrays:
When you say char ch1 [] = "Hello, World", you are creating a string literal and putting it in the array during its definition. It is ok to not give a size, as the array calculates it and appends a '\0' to it. You cannot reassign anything to that array without resizing it.
Hope this helps to clarify some things.
"Hello, World" is a string literal or read only memory store in data block. A variable ch is pointer to char, which is initialized with the location of the first character.
That's simply how printf works with a const char* argument. (Your pointer actually points to const data.)
Starting at the memory location denoted by the pointer, it prints character by character until a NUL terminator is reached.
The C standard library string functions all work in this way. Simply put it's how the language models strings.
Related
This question already has an answer here:
Why can I not modify a string literal in c?
(1 answer)
Closed 4 months ago.
for example:
char stringer[]="hello";
stringer[2]='A';
The above works to change 'l' to 'A'. But if I do the following:
char *stringer="hello";
stringer[2]='A';
This doesn't work, is there a reason for this?
As answered by Some programmer dude in comments:
Literal strings are really non-modifiable arrays of characters. With char *stringer="hello"; you make stringer point to the first character of such an array. Attempting to modify its contents leads to undefined behavior.
That's why you should always use const char * when pointing to literal strings.
Strings can be modified when using pointer, if the pointer is pointing to something you're allowed to modify. For example
char stringer[] = "hello";
char *pointer = stringer;
pointer[2] = 'A';
This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 4 years ago.
char temp1[4] = "abc";
char *temp2 = "123";
strcpy(temp1,temp2);
if I want to copy a string literal to an array, it works well, but if I do it in the opposite way, I get an error:
char temp1[4] = "abc";
char *temp2 = "123";
strcpy(temp2,temp1);
The feedback from compiler is "Segmentation fault".
So what's the differences? Is there anyway to copy a string to a string literal?
Thx.
You need to understand the subtle difference between these 2 lines
char temp1[4] = "abc";
char *temp2 = "123";
The first one creates a 4 character variable and copies "abc\0" to it.
You can overwrite that if you want to. You can do e.g. temp1[0] = 'x' if you want.
The second one creates a pointer that points to the constant literal "123\0".
You cannot overwrite that, its typically in memory that is declared read only to the OS.
What you have is more complicated than a string literal and what you attempt to do cannot be described as "copying to string literal". Which is good, because copying to a string literal is literally impossible. (Excuse the pun.)
First, what you are successfully doing in the first code quote is copying from a string literal into an array of chars of size 4 (you knew that). You are however doing this with the added detail of copying via a pointer to that string literal (temp2). Also note that what the pointer is pointing to is not a variable which can be edited in any way. It is "just a string which the linker knows about".
In the second code quote you attempt to copy a string (strictly speaking a zero-terminated sequence of chars which is stored in an array, temp1, but not a string literal) to a place where a pointer to char (temp2) points to, but which happens not to be a variable which is legal to write to.
The types of the involved variables allow such an operation basically, but in this case it is forbidden/impossible; which causes the segmentation fault.
Now what IS possible and might be what you actually attempt, is to repoint temp2 to the address at the beginning of temp1. I believe that is what gives you the desired effect:
char temp1[4] = "abc";
char *temp2 = "123";
/* Some code, in which temp2 is used with a meaningful
initialisation value, which is represented by "123".
Then, I assume you want to change the pointer, so that it points
to a dynamically determined string, which is stored in a changeable
variable.
To do that: */
temp2=temp1;
/* But make sure to keep the variable, the name you chose makes me worry. */
Note that an array identifier can be used as a pointer to the type of the array entries.
This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 7 years ago.
I made the following little program:
#include <stdio.h>
void strncpy(char * s, char * t, int n);
int
main()
{
char string1[]="Learning strings";
char string2[10];
strncpy(string2,string1,3);
printf("string1:%s\nstring2:%s\n",string1,string2);
return 0;
}
void strncpy(char * s, char * t, int n)
{
int i;
for(i=0; i<n && t[i]!=0;i++)
s[i]=t[i];
s[i]=0;
}
I was trying to learn the difference between doing something like:
char greeting[]="Hello!";
And
char * farewell="Goodbye!";
And I thought my program would work with either of the two types of 'strings'(correct way of saying it?), but it only works with the first one.
Why does this happen? What's the difference between the two types?
What would I have to do to my program to be able to use strings of the second type?
The statement
char greeting[] = "Hello!";
causes the compiler to work out the size of the string literal "Hello!" (7 characters including the terminating '\0'), create an array of that size, and then copy that string into that array. The result of that greeting can be modified (e.g. its characters overwritten).
The statement
char * farewell="Goodbye!";
creates a pointer that points at the first character in the string literal "Goodbye!". That string literal cannot be modified without invoking undefined behaviour.
Either greeting or farewell can be passed to any function that does not attempt to modify them. greeting can also be passed to any function which modifies it (as long as only characters greeting[0] through to greeting[6] are modified, and no others). If farewell is modified, the result is undefined behaviour.
Generally speaking, it is better to change the definition of farewell to
const char * farewell="Goodbye!";
which actually reflects its true nature (and will, for example, cause a compilation error if farewell is passed to a function expecting a non-const parameter). The fact that it is possible to define farewell as a non-const pointer while it points at (the first character of) a string literal is a historical anomaly.
And, of course, if you want farewell to be safely modifiable, declare it as an array, not as a pointer.
The string literals "Hello" and "Goodbye" are stored as arrays of char such that they are allocated at program startup and released at program exit, and are visible over the entire program. They may be stored in such a way that they cannot be modified (such as in a read-only data segment). Attempting to modify the contents of a string literal results in undefined behavior, meaning the compiler isn't required to handle the situation in any particular way - it may work the way you want, it may result in a segmentation violation, or it may do so ething else.
The line
char greeting[] = "Hello";
allocates enough space to hold a copy of the literal and writes the contents of the literal to it. You may modify the contents of this array at will (although you can't store strings longer than "Hello" to it).
The line
char *farewell = "Goodbye";
creates a pointer and writes the address of the string literal "Goodbye" to it. Since this is a pointer to a string literal, we cannot write to the contents of the literal through that pointer.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between char s[] and char *s in C?
Question about pointers and strings in C
I'm reading about the strings in C and I'm confused. I can "declare" strings in two ways:
char *str = "This is string";
char str2[20] = "This is string";
What is the difference between the two declarations? When would char str2[20] be preferred over char *str?
In C, strings are represented as sequences of chars, with a NULL character (aka 0, '\0'). They are stored in memory and you work with a way of referencing it. You have identified the two ways of referencing it, a char *, which is a pointer to a sequence of chars and an array, which is an immediate string of chars as an actual variable. Be aware that the string "abc" is 4 bytes long as there is an additional NULL character to represent the end of the string.
In addition to this, you are actually assigning strings in the example, which also involves the strings to given at compile-time.
So two questions. First is about how you represent strings (char * vs char[]) the second is about compile-time strings.
To come to your examples:
The first one creates a constant string in the text of the program and a pointer to it. Depending on the compiler it may be stored anywhere. It is the equivalent of mallocing a string and storing a pointer to it, except you must not change the contents of the memory. It is a char *, so you can change the pointer to point to somewhere else, like another malloced string or to the start of an array that you defined in example 2.
The second creates a char array (which a way of representing a string). The array is stored and allocated on the stack for the duration of the function, and you may change the contents. Because it is not a pointer, you cannot change it to point to a different string.
char *str = "This is string";
Puts the string in the constant data section (also known as .rdata) of the program.This data can't be modified.
char str2[20] = "This is string";
In this type of declaration data is preferably stored in the stack area of the program, if declared inside the function scope and in data section if declared in global scope.This data can be modified.
So if you have a necessity to modify data then use the second approach.
C has no strings. All there is is char arrays. And arrays in C are just pointers to the first element.
The easiest way of doing it is in fact your first variant. Not specifying an explicit length of the array for literals will save you from accidentally doing something like
char[3] = "abc";
C strings are constant in memory, so:
char *str = "This is string";
Stores "This is string" in memory and it is not mutable, you can only assign another address to str.
However
char str2[20] = "This si string";
is a shorthand of
char String2[20]={'T','h','i','s',' ','s','i',' ','s','t','r','i','n','g','\0'};
which does not stores a string in memory, stores independent bytes.
If you want to use constant strings like messages, then use first line.
If you want to use and manipulate strings like in a word processor then use second.
Regards
char *str = "This is string"; - This will keep the string in text segment as a read only data and it will store the address in the local pointer variable str.
str[0] = 'a'; //This will leads to crash, because strings are in read only segment.
printf("%d",sizeof(str)); //This will print 4(in 32bit m/c) or 8(in 64 bit m/c)
char str2[20] = "This is string"; - This will keep the string as character array in local stack.
str2[0] = 'a'; //This will change the first character to a
printf("%d",sizeof(str2)); //This will print 20
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What is the difference between char s[] and char *s in C?
Why is:
char *ptr = "Hello!"
different than:
char ptr[] = "Hello!"
Specifically, I don't see why you can use (*ptr)++ to change the value of 'H' in the array, but not the pointer.
Thanks!
You can (in general) use the expression (*ptr)++ to change the value that ptr points to when ptr is a pointer and not an array (ie., if ptr is declared as char* ptr).
However, in your first example:
char *ptr = "Hello!"
ptr is pointing to a literal string, and literal strings are not permitted to be modified (they may actually be stored in memory area which are not writable, such as ROM or memory pages marked as read-only).
In your second example,
char ptr[] = "Hello!";
The array is declared and the initialization actually copies the data in the string literal into the allocated array memory. That array memory is modifiable, so (*ptr)++ works.
Note: for your second declaration, the ptr identifier itself is an array identifier, not a pointer and is not an 'lvalue' so it can't be modified (even though it converts readily to a pointer in most situations). For example, the expression ++ptr would be invalid. I think this is the point that some other answers are trying to make.
When pointing to a string literal, you should not declare the chars to be modifiable, and some compilers will warn you for this:
char *ptr = "Hello!" /* WRONG, missing const! */
The reason is as noted by others that string literals may be stored in an immutable part of the program's memory.
The correct "annotation" for you is to make sure you have a pointer to constant char:
const char *ptr = "Hello!"
And now you see directly that you can't modify the text stored at the pointer.
Arrays automatically allocate space and they can't be relocated or resized while pointers are explicitly assigned to point to allocated space and can be relocated.
Array names are read only!
If You use a string literal "Hello!", the literal itself becomes an array of 7 characters and gets stored somewhere in a data memory. That memory may be read only.
The statement
char *ptr = "Hello!";
defines a pointer to char and initializes it, by storing the address of the beginning of the literal (that array of 7 characters mentioned earlier) in it. Changing contents of the memory pointed to by ptr is illegal.
The statement
char ptr[] = "Hello!";
defines a char array (char ptr[7]) and initializes it, by copying characters from the literal to the array. The array can be modified.
in C strings are arrays of characters.
A pointer is a variable that contains the memory location of another variable.
An array is a set of ordered data items.
when you put (*ptr)++ you are getting Segmentation Fault with the pointer.
Maybe you are adding 1 to the whole string (with the pointer), instead of adding 1 to the first character of the variable (with the array).