Experts I've some doubts in this programme.
#include<stdio.h>
void main() {
char str1[] = "Hello";
char * p = "Hello", * s, * q;
p = "Bye";
printf("%s", p);
s = p;
printf("%s", s);
q = str1;
printf("\n%s", q);
}
Here p,s and q are character pointers. As we know pointers store the address of a variable and suppose if we used p=str1 then it should store the base address of array str1. Then here how p is acting like an array itself which is storing a string? I've not really understood what's character pointer. Is it not really a pointer? Because we are not using & and neither are we getting the address as an output. Please help. Thank you.
You are very much correct here:
As we know pointers store the address of a variable and suppose if we used p=str1 then it should store the base address of array str1.
Your first question:
Then here how p is acting like an array itself which is storing a string?
You can say p is acting like an array but in reality, it is just a pointer which is pointing to the base address of string str1 which is a null-terminated string.
Your second question:
I've not really understood what's character pointer. Is it not really a pointer?
A character pointer is again a pointer like the pointers to other types in C.
But there is catch here. when you do:
char a = 'A';
char *ptr = &a; // ptr points to character 'A'
Here ptr is pointer to a character.
But when you do:
char *str = "Hello";
char *ptr = str; // ptr points to first character of string str
Here ptr is pointer to a string
A point to note here is - pointer to a character is different from the pointer to a string.
In C, strings are defined as an array of characters. The difference between a character array and a string is the string is terminated with a special character ‘\0’.
So,
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str[] = "Hello";
Both are same but there is a difference in the way they have been initialized.
Wherever in the program, we use str, this will give the base address of string "Hello". Similarly, string literals are also an array of characters with an exception that they can not be changed because the compiler may put them read-only data section.
So, if we have char *ptr = str then
ptr[0] == str[0]
ptr[1] == str[1]
.....
..... and so on
Because,
ptr[0] is *(ptr + 0) which is character at 0th location of string str and can also be written as *ptr and
ptr[1] is *(ptr + 1) which is a character at the 1st location of string str.
When we increment a pointer, it gets incremented in steps of the object size that the pointer points to. Here, ptr is pointer to char so, ptr+1 will give address of next character and *(ptr + 1) give the character at that location. That's why to the user it looks like its acting like an array.
Your third question:
Because we are not using & and neither are we getting the address as an output.
If I am getting it correctly you want to print the base address of the string, the pointer is pointing to.
In order to get the base address of string a pointer is pointing to you need to use %p. Like this:
#include<stdio.h>
int main() {
char str1[] = "Hello";
char * ptr = str1;
printf ("%s\n", str1);
printf ("%s\n", ptr);
printf ("%p\n", ptr);
printf ("%p\n", str1);
printf ("%p\n", &str1[0]);
return 0;
}
Output on my system:
Hello
Hello
0x7fff5e997b46
0x7fff5e997b46
0x7fff5e997b46
Here you can see - ptr, str and &str[0] giving same address.
Related
char* const p="C language\n";
printf("%s", p);
*p = "Change";
printf("%s", p);
Expected to print something like:
C language
Change
It's const char* p = "C language";, not char* const. They have different meanings: const char* p means that the chars to which p points to, cannot be modified; while char* const p means that the pointer p itself cannot be modified.
*p = "Change"; is not the correct way to change string's content. Even when the string is not read-only. One way to modify a string's content is to use: strcpy(p, "Change")
You cannot modify string literals because they are read-only by definition. However, you can declare "char arrays", and they can be modified:
char s[] = "C language";
printf("%s\n", s);
strcpy(s, "Change");
printf("%s\n", s);
There are two ways to change what printf( "%s", p ); prints:
Change where p points to: p = .... This does not work as p is a constant pointer.
Change the contents of the memory p points to. With *p = ... you change the one character at address p. If you want to change the string starting at address p, you need one of the many functions from <string>, or sprintf(), or similar. However, in this case that would not work either, because the memory occupied by string literals ("C language\n", which p points to in your example) is read-only as well.
Hint: char p[20] = "C language\n"; defines 20 bytes of writeable memory initialized to the value of the string literal.
probably a dumb question but how do you access a specific character in a char pointer?
I've tried following...
char *pointer = "Hello";
printf("%s", pointer); // prints "Hello"
printf("%s", &pointer[0]); // also prints "Hello"
But what I want is printf(???) => "H". A single character. Or the "e". How is that possible?
pointer is a pointer to char, also called a char *.
After char *pointer = "Hello";, pointer points to the “H”.
When printf is given %s, it takes a char * and prints all the characters it finds starting at that location, until a null character is seen.
To tell printf to print a single character, pass it the actual character value (not a pointer) and use %c:
printf("%c", *pointer);
or:
printf("%c", pointer[0]);
or, for the “e” instead of the “H”:
printf("%c", pointer[1]);
char* pointer = "Hello";
Creates a pointer and assigns it to the base address of "Hello".
pointer and &pointer[0] are the same thing.
pointer[n] takes the address of "Hello" and offsets it by the number 'n', be sure not to index of the end of the address or you will read rubbish.
So:
pointer[0] = 'H'
pointer[1] = 'e'
pointer[2] = 'l'
pointer[3] = 'l'
pointer[4] = 'o'
pointer[5] = 0
You want to access the char of char* simply use [] operator, just like arrays.
char *pointer = "Hello";
printf("%s", pointer); // ok
printf("%s", &pointer[0]); // wrong way of accessing specific element (it is same as the base address.., thus %s prints the whole thing)
Instead you're accessing the address of the first element of char* or string literal.. why!
printf("%c", pointer[0]); // use this one
Just like arrays, access the required element.
However, to get it better, notice here:
#include <stdio.h>
int main() {
char *pointer = "Hello";
printf("%s\n\n", pointer); // ok
printf("%c", pointer[0]);
printf("%p == %p\n", (void *)&pointer[0],(void *)pointer);
// cast to void * to avoid undefined behavior
// pointed out by #ex nihilo
printf("%p", pointer+1);
return 0;
}
Output:
Hello
H0x55da21577004 == 0x55da21577004
0x55da21577005
as you can see, the pointer holds the address of the first element which is: &pointer[0] thus you get the same output.
Hi I'm new to programming.
In the following code str is a pointer to a character, so str should contain the address of the character 'h'. Therefore %p should be used to print that address. But I don't understand how %s is used for printing a pointer parameter.
#include<stdio.h>
int main (){
char s[] = "hello";
char *str = s;
int a[] = {1, 2, 3, 4, 5};
int *b = a;
printf("%s\n", str); // I don't understand how this works ?
printf("%c\n", *str); // This statement makes sense
printf("%c\n", *(str + 1)); // This statement also makes sense.
printf("%p\n",str); // This prints the address of the pointer str. This too makes sense.
printf("%d\n",*b); // makes sense, is the same as the second print.
// printf("%d",b); // I don't understand why str pointer works but this gives a compile error
return 0;
}
char s[] = "hello";
Declares an array of zero-terminated characters called s. Its the same as writing
char s[6] = { 'h', 'e', 'l', 'l', 'o', '\0' };
As you can see, the quotation marks are a shorthand.
char *str = s;
This declares str to be a pointer to a character. It then makes str point to the first character in s. In other words, str contains the address of the first character in s.
int a[] = {1, 2, 3, 4, 5};
Declares an array of integers. It initializes them to the values 1-5, inclusive.
int *b = a;
Declares b to be a pointer to an int. It then makes b point to the first int in a.
printf("%s\n", str);
The %s specifier accepts the address of the first character in the string. printf then walks from that address, printing the characters it sees, until it sees the \0 character at the end.
printf("%c\n", *str);
This prints the first character in str. Since str is pointing to a character (the first character in the string), then *str should obtain the character being pointed at (the first character in the string).
printf("%c\n", *(str + 1));
This prints the second character in str. This is the long way of writing str[1]. The logic behind this is pointer arithmetic. If str is the address of a character, then str + 1 is the address of the next character in the array. Since (str + 1) is an address, it may be dereferenced. Thus, the * obtains the character 1 character past the first character of the array.
printf("%p\n",str);
The %p specifier expects a pointer, just like %s would, but it does something else. Instead of printing the contents of a string, it simply prints the address the pointer is containing, in hex.
printf("%d\n",*b);
This prints the first int in the array pointed to by b. This is equivalent to writing b[0].
printf("%d",b);
b is an int *, not an int, which is what %d expects. If you were trying to print the address of the first element of the array, the specifier would be %p, not %d. Also, this line should not generate a compiler error. Instead, it should have been a runtime undefined behavior, since the compiler does not know what a printf format string is.
I'm little bit confused about usage pointer arithmetic. I ask confusing question in the code as comments. I think when it is increased, the other also must be increased. Can someone explain?
#include <stdio.h>
int main()
{
const char *str = "abcde";
const char *temp = str; // str is pointer to address of first element of temp isn't it?
printf("%d\n", temp - str); // zero okey
printf("temp str\n");
printf("%d %d\n", temp, str); // shows same adresses
str++; // hard to understand a point is here
printf("%d %d\n", temp, str); // why weren't also temp increased?
temp++;
printf("%d %d\n", temp, str); // why weren't also str increased?
temp++;
printf("%d %d\n", temp, str); // why weren't also str increased?
return 0;
}
temp and str both are different pointer variables. Modifying any of them will not cause the modification of other but modifying the data they point to will have effect.
You should keep in mind that in your case you can modify str and temp but can't modify the string literal they points to because string literals are not modifiable.
Also note that for pointer data type %p is used as format specifier in printf to print the address they point to.
temp won't be increased by increasing str just as b won't be increased by increasing a in int a=0, b=0;. They are independent variables.
str is pointer to address of first element of "abcde" and it won't have any relationships with temp because it is defined before temp is defined.
By the way, do not try to print pointers with %d. This is undefined behavior because the types don't match.
#include <stdio.h>
int main(void)
{
const char *str = "abcde";
const char *temp = str; // str is pointer to address of first element of temp isn't it?
printf("%ld\n", (long)(temp - str)); // zero okey
printf("temp str\n");
printf("%p %p\n", (void*)temp, (void*)str); // shows same adresses
str++; // hard to understand a point is here
printf("%p %p\n", (void*)temp, (void*)str); // why weren't also temp increased?
temp++;
printf("%p %p\n", (void*)temp, (void*)str); // why weren't also str increased?
temp++;
printf("%p %p\n", (void*)temp, (void*)str); // why weren't also str increased?
return 0;
}
In your code, temp and str are themselves two different variable, however, the data they point to, are same.
If you modify the content pointed by either of them, you can see the change reflected through other.
Also, FWIW, for printing address, change
printf("%d %d\n", temp, str);
to
printf("%p %p\n", (void *) temp, (void *)str);
otherwise, by violating the requirement of appropriate type of parameters to the format specifier, you'll invoke undefined behavior.
const char *temp = str;
means temp pointer takes value of str pointer.
They are not linked.
you can change str without changing temp because it's like
*temp = &(str[0]);
*temp value is the address of 'a' from string "abcde"
if you str++
*temp value is the address of 'a' from string "abcde" and *str is the 'b'
i don't know what more i wan do for you.
This declaration
const char *str = "abcde";
means the following. There is allocated memory for variable str and it is initialized by the address of the first character of string literal "abcde"
In this declaration
const char *temp = str;
there is allocated memory for another pointer with name temp and the pointer gets a copy of the value stored in variable str.
So now you have two cells of memory each of them contains the address of the first character of the string literal.
This statement
str++; // hard to understand a point is here
means that the value stored in str was increased. The previous value was the address of the first character of the string literal. After increasing the value now it is equal to the address of the second character of the string literal.
You can check this by executing statements with a call to function printf before this statement and after it
printf( "%s\n", str );
str++; // hard to understand a point is here
printf( "%s\n", str );
The value stored in variable temp was not changed.
After this statement
temp++;
the both variables have equal values that are pointers to the second character of the string literal. The values stored in different cells of memory named str and temp.
After the second statement
temp++;
variable temp will have the value that equal to the address of the third character of the string literal. The value stored in variable str was not changed.
As you should know string literals include a terminating zero. You can output all characters of a string literal until the terminating zero will be encountered.
Consider the following code snippet
const char *str = "abcde";
const char *temp = str;
while ( *temp != '\0' ) printf( "%s\n", temp++ );
After the loop variable temp will have value that points to the terminating zero of the string literal. At the same time value stored in str will not be changed and will point to the first character of the string literal as before.
Why am I'm getting this error "Segmentation fault (core dumped)" while running this program, what is wrong with it?
#include <stdio.h>
int main() {
char *p = "Sanfoundry C-Test";
p[0] = 'a';
p[1] = 'b';
printf("%s", p);
return 0;
}
String literals are unmodifiable in C:
char *p = "Sanfoundry C-Test";
p[0] = 'a';
The last statement invokes undefined behavior.
Use a character array initialized with a string literal to have a defined behavior:
char p[] = "Sanfoundry C-Test";
p[0] = 'a';
As others have said, that should not be done that way, since you are modifying something that is supposed to be (and often is) unmodifiable.
char *p = "Sanfoundry C-Test";
This declares a pointer and points it to (sets the address contained in the pointer to the start of) the literal text (which is constant and should not be modified and probably can't be modified without an error anyway) "Sanfoundry C-Test".
But AFAIK, you are asking what the rest of the code means, so let's first correct the problem:
char p[] = "Sanfoundry C-Test";
That declares an array of char with the given contents (the characters 'S', 'a', 'n', etc., followed by a 0 character). Such an array is treated as a text string, by C. Now
p[0] = 'a';
Changes the first character of that array (arrays "start counting" at 0), so the 'S' in the string is changed to an 'a'.
p[1] = 'b';
This changes the second character into 'b'. So now the string is "abnfoundry C-Test". The final printf() then displays that value in a console.
This is the difference between a char array and a char pointer.
char p[]="Sanfoundry C-Test";
Then you can do
p[0]='a';
p[1]='b';
But you cannot do it if p is a pointer which is in your case.
For more information, see the link provided below
What is the difference between char s[] and char *s?