passing a character to char * - c

i have this piece of code
int main()
{
char a[100];
a[0]='a';
a[1]='b';
fun(a[0]);
}
void fun(char *a)
{
printf("%c",a);
}
but im passing a character to a pointer.will the pointer not be expecting an address???

a[0] holds the value 97 ('a' in ASCII). fun will receive the value 97 in a but interpret it as an address. However, since you're only passing it to printf, and happen to incorrectly be using the %c formatter which will interpret a as a char, you'll end up printing a anyway.
Of course, on most compilers you should receive warnings that:
You are converting an integer into a pointer (when you call fun) without casting it to a pointer.
The %c formatter in printf should take a char, not a char *.

You're calling a function which has no prototype at the point of the call. C89 says this is allowed, but it's your problem to ensure that the function is called with arguments that are correct for the parameters it is eventually defined with. Since they don't match in this case, undefined behavior.
Turn on more compiler warnings (-Wall in the case of gcc).

You're not passing a character to a pointer.
fun() is expecting a pointer to a character, but you're passing a character. This should generate a syntax error. Or, at the very least, not work right if you really haven't declared the function fun().
Characters are integer types that are copied on assignment.

Solution 1: Don't use a pointer.
void fun(char a);
Solution 2: If you need to use a pointer for some reason not obvious here, use & to get a pointer and * to dereference the pointer.
void fun(char *a);
int main()
{
char a[100];
a[0]='a';
a[1]='b';
fun(&a[0]);
}
void fun(char *a)
{
printf("%c",*a);
}

Related

Why we didn't use * during dereferencing the pointer?

In the below code, we get a pointer from strdup(source) and we store it in a pointer named target.
Now, when we print the string using pointer, we don't add * at the beginning of the pointer: why is it so? As I studied whenever we want to dereference any pointer we use *pointer_name. If we add * in the below code, we get an error.
I am very beginner, so pls ans in easy words.
#include<stdio.h>
#include<string.h>
int main()
{
char source[] = "Programming";
char* target = strdup(source);
printf("%s\n",target);
return 0;
}
printf expects a char pointer in the place of the %s specifier.
https://en.cppreference.com/w/c/io/fprintf
char* target = strdup(source);
printf("%s\n",target);
Why we don't use *target in the code above?
The explanation is quite simple, as already stated in previous answers: target has type char pointer, which is exactly what printf() wants in the above call.
Now, printf() is a little complicated because its semantic is not simple - basically it accepts zero or more arguments after the first, of any type (possibly applying promotion). But if we use strdup() again, maybe it is simpler:
char* target2 = strdup(target);
Here, if you wrote strdup(*target), the compiler might warn that you are passing a char instead of a pointer to char.
strdup() returns a char*, hence the char* type of target. target holds a pointer to the first character in an array of chars. printf("%s", string) expects string to be a char*, so there’s no reason to do anything to target; just pass it to printf().
If you dereferenced target, you would get a single char (P in this case). printf() would then complain that you had supplied a character instead of a string (pointer to character). Even worse, the program could compile, and then printf() would try to print the string at address P (0x50), which would result in probably unwanted behaviour.
When working with arrays—a string is a type of array—you rarely want to dereference the array.

How to manipulate variable in function?

In the example below, I pass a char into a function as a pointer. When the function prints out the memory address of the char, it is a different address. Am I dealing with two different variables in this case? Isn't that the same result as if I didn't use a pointer in the function argument (same as pass by value)?
char a = 'a';
printf("a=%p\n", &a);
showString(a);
//function
void showString(char *c){
c='b';
printf("c=%p\n", &c);
}
c is assigned the value 'b'. But if I check a after the function call, it still has the value 'a'. How does the above need to change so the value assigned in the function carries over outside of the function?
You are not using the pointer correctly: rather than assigning a new value to the object the pointer points to, you assign the pointer itself.
The call should use the address-of operator, and the assignment should be with the dereference operator:
showString(&a);
printf("a=%p\n", (void*)&a);
...
void showString(char *c){
*c='b';
printf("c=%p\n", (void*)c);
}
Now both printouts will produce the same address, and the value of char a in the calling function should change.
Note 1: The reason the compiler allowed c = 'b' assignment is somewhat odd: 'b' is considered a character constant, char is considered an integral type, and C lets you assign integers to pointers with the assumption that you know what you are doing better than the compiler.
Note 2: When you print a pointer with %p, and the pointer type is neither void* nor char*, a cast to void* is required. You are printing char*, so it can go without a cast, but I added the cast anyway, in case you want to try this out with pointers of a different type.
Your function should look like
//function
void showString(char *c) {
*c = 'b';
printf("c=%p\n", &c); //<---to print the address of C
printf("c=%c\n", *c); //<---to print the value that C is pointing
}
and when you call it you should pass the Address of a
char a = 'a';
printf("a=%p\n", &a);
showString(&a); //<---&a and not a

why can't we use indirection operator with array name?

In the below code , why can't I dereference the array name ,since when an array is passed as an argument to a function , it becomes pointer to first element of the array , so why can't we dereference it then ?
#include <stdio.h>
int main(void) {
char s[] = "radha";
int a[2] = {0,1};
printf("%s ", *s);
printf("%d", *a);
return 0;
}
​
I am getting segmentation fault for the above code , what's the reason here , when I use a[0] ,it is internally converted as *(a+0) , so what's the issue in simply doing *a or *S ,please clarify .
printf("%s ",*s); expects second argument to be a pointer to string while you are passing char 'r' (dereferencing s gives you first array item as expected).
I have two suggestions of your,
Read the documentation.
The "%s" specifier expects a pointer of char, you are passing a char which is then considered an integer and dereference as if it were a pointer causing UNDEFINED BEHAVIOR.
If you read the documentation, and understand that char[] is converted to char * also that dereferencing a char * poitner will give you a char, then you would understand why this is wrong.
Enable compiler warnings. If you do so, then a warning telling you that you are passing the wrong type would save you a lot of time and let you learn more about how to invoke a given function.
If you ignored the warning, it's even worse. You should never ignore a warning unless you know beforehand that the compiler will complain about something. If the warning was not expected, then it's very likely an error instead.

%d specifier for an uninitialized character array

#include <stdio.h>
int main()
{
char a[8];
printf("%d\n",a) ;
return 0;
}
For the above code the output was this :- 2686744
What is the reason behind this output?
I found that the output doesn't depend on the content of the array, but on the size of the array.I just want the explanation.
char a[8];
printf("%d\n",a);
This code has undefined behavior.
The array expression a is implicitly converted to a char* value, equivalent to &a[0]. That value is then passed to printf -- but since the %d format requires an int argument, the behavior is undefined.
If int and char* happen to have the same size, and if they're passed as function arguments using the same mechanism, then it will likely print a decimal representation of the address of (the initial element of) the array.
But don't do that. If you want to print the address:
printf("%p\n", (void*)a);
You are printing the address of the array as an integer.
If you compile with -Wall to enable warnings your compiler should complain about that.

Alternate pgm for the given pgm without using function

#include <stdio.h>
void lower_string(char*);
int main()
{
char string[100];
printf("Enter a string to convert it into lower case\n");
gets(string);
lower_string(string);
printf("Entered string in lower case is \"%s\"\n", string);
return 0;
}
void lower_string(char *string)
{
while(*string)
{
if ( *string >= 'A' && *string <= 'Z' )
{
*string = *string + 32;
}
string++;
}
}
In this program what if i replace *string with string[]?
can anyone help me in writing the above program without using any function?
And please explain what does this mean while(*str) ?
void lower_string(char *string);
and
void lower_string(char string[]);
are equivalent in C. A parameter of type char [] is adjusted to type char *.
Of course when string is the operand of the * operator like in:
while (*string)
then you cannot change it to string[] as * here is the indirection operator and not a part of a type name.
There is no difference between the two, because when an array is passed to a function, it decays adjusts to a pointer.
I wouldn't write such code and then tag it C++, because string is a standard library class name.
C-FAQ: Q-6.4:
Since arrays decay immediately into pointers, an array is never actually passed to a function. You can pretend that a function receives an array as a parameter, and illustrate it by declaring the corresponding parameter as an array:
void f(char a[])
{ ... }
Interpreted literally, this declaration would have no use, so the compiler turns around and pretends that you'd written a pointer declaration, since that's what the function will in fact receive:
void f(char *a)
{ ... }
There's nothing particularly wrong with talking about a function as if it ``receives'' an array, if the function is traditionally used to operate on arrays, or if the parameter is naturally treated within the function as an array.
This conversion of array-like declarators into pointers holds only within function formal parameter declarations, nowhere else.
The symbol [] is basically equivalent to * in some way.
You can accept char[] and still treat it as a pointer with * and you can accept a char* as a parameter and access it with [] as a regular array - it's exactly the same.
You're always getting a pointer to that spot in memory, when it's an array defined with [] though, the pointer will be constant (can't deference it, only access where it's pointing to).
When you're declaring an array using char str[100]; you're actually declaring a const char* named str and pointing to a memory area in the stack.
They are pretty much the same thing. For example,
sz[x];
is short for
*(sz + x);
However, when you write char *sz;, all yau are getting is a pointer. Wen you write char sz[size];, you are getting an array also. See haccks' answer.

Resources