can a character be pointed by a pointer in c - c

Though we can use a pointer to point an array of characters i.e. strings but can a single character be pointed by a pointer in C?
E.g. Is this code valid?
char *p='a';

Yes, of course you can use a pointer to point to a single character, but you can't go about it in the way that you propose.
char* p = 'a';
is just as incorrect as
int* q = 5;
You're assigning a character value to a pointer. Remember that a pointer is a memory address, so char* p = 'a'; means that you think that there's a char in the memory address 'a'. That's probably not what you want, and conceptually it makes no sense.
You can accomplish what you want like this:
char c = 'a';
char* p = &c;

char *p=&a; is valid, where a is a single character. It's a char * that points to a constant of a single character.
[Corrected per #RedAlert's comment]

Related

Is there any benefit of using pointer arithmetic on character array in C?

I have a question regarding the operation on character array.
I was inspired by This answer here that discusses char* vs char[]. In this answer, it says considering a case where we want to cut off the first character of a word,
char* p = "hello";
p++;
is a much faster operation, than if we declared using character array, and therefore had to index into every element.
char s[] = "hello";
s[0] = 'e';
s[1] = 'l';
s[2] = 'l';
s[3] = 'o';
s[4] = '/0';
But my question is, in the second case, cannot I just use another pointer that points to the start of s, i.e.
char* ptr = s;
and then treat it the same as char* p? Would it be as fast?
You mean something like this?
char s[] = "Hello";
char *ptr = s+1;
Yes, you can do that, and it results in ptr pointing to the string "ello". It is just as fast; like the other example, it should be simple arithmetic and not require any copying of data.
I think it is a misconception to think of this as a "pointer versus array" issue. Pointers and arrays in C are inseparable. Both examples involve an array, and two different pointers into that array. In the first example, the array is created by the string literal "Hello" and doesn't have a name; the values of p before and after p++ both point into that array. In the second example, the array is named s, and the expression s decays into a pointer to the zeroth element of that array; s+1 is a pointer to the first element.
The main difference is that in the second example, the array can be modified, and may have a finite lifetime. So your program now has to manage issues of aliasing and ownership. Suppose one part of the code accesses the string through s, and another part accesses it through ptr. Are you prepared for the fact that if the first code modifies the string, the second code will see it change? Does your code correctly keep track of when the lifetime of s ends (e.g. the end of the block where it's defined), and does it make sure not to use ptr beyond that point?
By contrast, the string literal in the first example has static lifetime, and survives until the end of the program; so ptr = p+1 remains valid indefinitely. It also must not be modified at all, or undefined behavior results. So if your program is otherwise bug free, you don't have to worry about some other part of your code changing the string behind your back.
The way I understand these things:
char *p = "hello";
Six bytes (including terminating '\0') are put in READ ONLY memory, and the address of the first byte is put into the variable p that has the datatype char *. Yes, the code can increment/decrement p to point further into the string.
char s[] = "hello";
Six bytes (including terminating '\0') are put in READ/WRITE memory, and referring to s means referring to the initial byte of the string. Yes, another pointer can be declared: char *p = s; And, yes, the code can manipulate the data stored in those six bytes.
char *p = &s[1]; // don't need to increment.
If you want to really play with things:
printf( "%.3s\n", &"Hi there"[3] );
will print "the". There is no name and no pointer, but there is an unnamed READONLY array that can be (carefully!) accessed.
Consider the following example that 'decorates' up to the 31 day of a month with the correct 'ordinal' suffix:
for( int DoM = 1; DoM <= 31; DoM++ ) {
int i = DoM;
if( i > 20 ) i %= 10; // Change 21-99 to 1-10. Don't wanna think about 100+
if( i > 3 ) i = 0; // Every other one ends with "th"
// 0 1 2 3
printf( "%d%s\n", DoM, &"th\0st\0nd\0rd"[ i * 3 ] );
}

why there is no use of & in case of adding pointer to array of character? [duplicate]

This question already has answers here:
What is array to pointer decay?
(11 answers)
Closed 2 years ago.
When we want to have a pointer for integer we add &(int *p = &n)
int n=50;
int *p = &n;
, so similarly in case of a string shouldn't it be the same as this,
char name[] = "Hello"
char *s = &name;
or like this code below,
char *s= &"Hello";
rather than like this,
char *s= "Hello";
OR
char name[] = "Hello";
char *ptr=name;
OR
char name[] = "Hello";
char *ptr;
ptr= name;
I don't think the last two codes are different.
In this version:
int n = 50;
int *p = &n;
you have a single int n. To make a pointer to it, you need to take its address with &.
On the other hand, in this version:
int n[50];
int *p = n;
the variable n is an array of int. This has the property that the name of the array actually refers to the first element (i.e. the array decays to a pointer when used like this). So no & is needed to refer to the address.
The exact same logic applies to the char case:
char name[] = "Hello";
char *ptr = name;
where name is an array, so you can take a pointer to the first element by just using the variable name without using &.
char *s = &name; does not work because the pointer types do not match. When you apply the "address of" operator to an array, what you get is a pointer to an array. But the pointer variable that you are initialising is not a pointer to an array. It is a pointer to a char.
You can use the exactly same pattern that you used with integer to get a pointer to an array:
char (*s)[6] = &name;
Alternatively, when you want a pointer to an element of an array, you can use the subscript operator to get the element, and apply addressof on that element:
char *s = &name[0];
But char *s = name; also works because the array implicitly converts to pointer to first element. This implicit conversion is called decaying.
Given char name[] = "Hello";, if you want the address of name, you should use &name. That provides a pointer to an array of six char.
The compiler should warn about char *s = &name; because it uses a pointer to an array for a pointer to a char, and those are different (and incompatible) types of pointers.
In C, we generally do not work with arrays. Instead, we work with pointers to array elements. To assist with this, C automatically converts an array to a pointer to its first element, except in certain situations.
Thus char *s = name;, name is automatically converted to a pointer to its first element, which is a char. This is the reason we do not need to use & with arrays, even though we need to use & to take the address of a non-array—with an array, C automatically gives us an address, so we do not need to use &.
Although &name points to the start of the array and name points (after conversion) to the first character of the array, which starts in the same place, the pointers have different types.

manipulating what the pointer is pointing at

This is probably a really easy question but I can not seem to find an explicit answer online. Say a had a pointer to an array declared as:
static char newMessage[400];
char *p = &newMessage;
(I don't know if this is right) How would I go about manipulation the newMessage array using only the pointer. I am doing this because a C cannot return an array but can return a pointer to an array. please be gentle, I'm new
Your code is almost right; the only problem is that you have mismatched pointer types. You want:
char *p = newMessage;
Not:
char *p = &newMessage;
The latter tries to initialize p, a char * variable, with a value of type char (*)[400], which isn't valid C.
After you've created and initialized p, you can just use it however you'd like:
p[6] = 12;
Or something like that.
Just point the pointer to the array
char* p = newMessage ;
And return it from a function.
You use it the same as you would use the array it points to.
newMessage[2] = '\0'
p[2] = '\0'
When you declare an array like static char newMessage[400], the identifier newMessage is substituted by the address of the first element of the array, and it behaves like a pointer.
char* p= newMessage;
char* q= "Hi, world";
newMessage[4]= 'x';
p[4]= 'x';
*(newMessage + 2)= 0;
*(p+2)= 0;
strlen(newMessage);
strlen(q);
strcmp(newMessage, "Hi world");
strcmp(p, q);
are all valid expressions.
Note that in the last four function calls, you are not passing arrays, but pointers to the first character of the string. And by convention, the functions scan the memory until they find a null byte terminator.
Actually, it should be char *p = newMessage; .The char[] behaves similar to char*.
You'll later modify it by how you usually modify any pointer.
BTW, this is very basic so it's better you read a tutorial.
Also, since you asked this, if you're planning to return a pointer to the array, the array better not be allocated on the stack. It should be heap-allocated (it's in your case since static)
You cannot actually manipulate the array, as arrays are no first class type in c.
Almost anything you care to do with the array name, will make it degenerate to a pointer. The exception being sizeof, so you can get the element count using sizeof array/sizeof *array.
What you can do, is change the values of the array elements. Use pointer arithmetic and dereferencing *. The index operator a[b] is syntactic sugar for *(a+b).
Also, you can use library functions (or your own), which accept pointers.

pointer to address using another pointer C

I've got a function which receives a pointer to a string.
Now I want to duplicate this pointer, so I could run on the string with one pointer, and have another pointer which saves the beginning of the string. I hope my question is clear, I don't want to create a pointer to the pointer (which points to where the first pointer points and changes with it), I want a pointer which will point to the address of which the first pointer points.
I tried many different ways but none of them worked, this is my latest try, I keep getting
"initialization makes pointer from integer without a cast"
int move_chars (char *str, int start, int end, int dist){
int strsize = end - start + 1;
char *p = *str;
Since p is of type char * and str is also of type char *, you just need to do:
char *p = str;
To make p point to the same memory location as str.
Your code:
char *p = *str;
Attempts to copy into p the value of the first char at the memory location that str points to, and since p is expecting another memory location and not a char, you get an error.
Your error says that "initialization makes pointer from integer without a cast". This is telling you what's happening: The compiler thinks you are manually pointing p to a specific memory location, using the value of the char *str returns as an integer. This is technically doable, but you are required to manually cast the integer into a pointer, just so it's clear you're doing what you intended, and it's not a bug like in your case.
Use
char *p = str;
to declare a pointer to a char and initialise it with the value of another char pointer.
char *p = str
This will declare a pointer to character and makes p point to the memory location where str points

Character Pointers in C

#include <stdio.h>
int main(void){
char *p = "Hello";
p = "Bye"; //Why is this valid C code? Why no derefencing operator?
int *z;
int x;
*z = x
z* = 2 //Works
z = 2 //Doesn't Work, Why does it work with characters?
char *str[2] = {"Hello","Good Bye"};
print("%s", str[1]); //Prints Good-Bye. WHY no derefrencing operator?
// Why is this valid C code? If I created an array with pointers
// shouldn't the element print the memory address and not the string?
return 0;
}
My Questions are outlined with the comments. In gerneal I'm having trouble understanding character arrays and pointers. Specifically why I can acess them without the derefrencing operator.
In gerneal I'm having trouble understanding character arrays and pointers.
This is very common for beginning C programmers. I had the same confusion back about 1985.
p = "Bye";
Since p is declared to be char*, p is simply a variable that contains a memory address of a char. The assignment above sets the value of p to be the address of the first char of the constant string "Bye", in other words the address of the letter "B".
z = 2
z is declared to be char*, so the only thing you can assign to it is the memory address of a char. You can't assign 2 to z, because 2 isn't the address of a char, it's a constant integer value.
print("%s", str[1]);
In this case, str is defined to be an array of two char* variables. In your print statement, you're printing the second of those, which is the address of the first character in the string "Good Bye".
When you type "Bye", you are actually creating what is called a String Literal. Its a special case, but essentially, when you do
p = "Bye";
What you are doing is assigning the address of this String literal to p(the string itself is stored by the compiler in a implementation dependant way (I think) ). Technically address to the first element of a char array, as Richard J. Ross III explains.
Since it is a special case, it does not work with other types.
By the way, you should likely get a compiler warning for lines like char *p = "Hello";. You should be required to define them as const char *p = "Hello"; since modifying them is undefined as the link explains.
As to the printing code.
print("%s", str[1]);
This doesnt need a dereferencing operation, since internally %s requires a pointer(specifically char *) to be passed, thus the dereferencing is done by printf. You can test this by passing a value when printf is expecting a pointer. You should get a runtime crash when it tries to dereference it.
p = "Bye";
Is an assignment of the address of the literal to the pointer.
The
array[n]
operator works in a similar way as a dereferrence of the pointer "array" increased by n. It is not the same, but it works that way.
Remember that "Hello", "Bye" all are char * not char.
So the line, p="Bye"; means that pointer p is pointing to a const char *i.e."Bye"
But in the next case with int *
*z=2 means that
`int` pointed by `z` is assigned a value of 2
while, z=2 means the pointer z points to the same int, pointed by 2.But, 2 is not a int pointer to point other ints.So, the compiler flags the error
You're confusing something: It does work with characters just as it works with integers et cetera.
What it doesn't work with are strings, because they are character arrays and arrays can only be stored in a variable using the address of their first element.
Later on, you've created an array of character pointers, or an array of strings. That means very simply that the first element of that array is a string, the second is also a string. When it comes to the printing part, you're using the second element of the array. So, unsurprisingly, the second string is printed.
If you look at it this way, you'll see that the syntax is consistent.

Resources