Clarification on why this C code works - c

I'm learning C today. I've been coding in managed languages (Java, C#, Python, etc.) for some time now. I thought I was understanding the details of pointers, but then I wrote the following code that worked as expected, but generated an 'incompatible pointer type' warning.
void setText(char* output) {
//code to set output to whatever, no problems here.
}
int main(int argc, const char* argv[]) {
char output[10];
setText(&output);
//[EDITED] ...other test code which printf's and further manipulates output.
return 0;
}
So I googled, and ended up changing the line
setText(&output);
to
setText(output);
which got rid of the warning. But now I don't know why the first one was working at all. I was sending the address of an address as far as I can tell (because char* x; is essentially the same as char x[];). What am I misunderstanding and why do both of these work?

The type of output is char [10], which decays to a char * in the context of a function call (which is why the second variant works).
The type of &output is char (*)[10], i.e. a pointer-to-array. This is not the same thing, hence the compiler warning. However, the value of &output (an address) is equivalent to the value of output (once it has decayed to a char *), so the end result is "as expected".
This may sound like pedantry, but there is a fairly important difference. Try the following:
void foo(const char *p)
{
printf("%s\n", p);
}
int main(void)
{
char output[][6] = { "Hello", "world" };
foo(output[0] + 1);
foo(&output[0] + 1);
}
Recommended reading is the C FAQ on arrays and pointers, in particular question 6.3 and 6.12.

Related

confuse about the pointer, and its usage for c language programming

I have just learned how to use the point, and very confused about why we need to use it. let me bring up an example:
#include <stdio.h>
int main(){
int a,b,*ptr;
a = 2;
ptr = &a;
*ptr = a;
b = *ptr // why not we assign the value of a to b directly (b = a;)
return (0);
}
above is one of example I saw on the video tutorial, I have not had any experience of using pointer. therefore I wonder why do we need it, can anyone show me the use of pointer? thank you
"can anyone show me the use of pointer?"
int main( int argc, char **argv ) ...
The 2nd parameter is a pointer to a (null terminated) array of pointers to char (recognised as being pointers to "null terminated strings".)
Conventionally, any C program's entry point is the function main() and most programs receive one or more parameters (as strings) when executed.
This is just one of many examples where you will encounter pointers in C source code.

puts() questions with const char

I'm having trouble understanding how c uses puts() to display parts of a message. Two ways which I would consider equivalent do not work the same way with the function. For example
void skippie(char *msg)
{
puts(msg + 6);
}
char *msg = "Don't call me!";
skippie(msg);
This compiles fine, however this does not
void skippie(char *msg)
{
puts(msg[6]);
}
char *msg = "Don't call me!";
skippie(msg);
how does puts() distinguish between the two and only compile for one? The compiler complains that it wants a "const" char but even if I try and use that syntax it fails. Can anyone explain this?
The index operator also dereferences the pointer, so
msg[6] is equivalent to *(msg + 6), not msg + 6.
Furthermore, you cannot pass a const char* to a function, while it expects a char*. i.e., you also have to update the function signature.
msg + 6 is not the same as msg[6].
As per your code, msg+6 is a char *, while msg[6] represents a char.
Quoting from the man page of puts(), the syntax is
int puts(const char *s);
so, the argument of puts() needs to be a const char *, not a char.

Pointer to string

Consider the following program:
#include <stdio.h>
void foo(char** string)
{
printf("%s", string[0]);
}
int main()
{
char* a = "blahblah";
foo(&a);
return 0;
}
It works fine as it is, but if I substitute
char* a = "blahblah";
with
char a[] = "blahblah";
it does not work.
I get the warning expected 'char **' but argument is of type 'char (*)[9]', and a segmentation fault.
I was under the impression that char[] and char* are the same thing, so a pointer to each of them would also be the same.
(windows with mingw, gcc 4.8.1)
Thank you
In most cases these two statements behave the same, with two exceptions. One exception is when applying the & operator. When you apply & to an array(e.g. a[]), you got the address of the whole array. This value is identical to the address of the first element of the array, so &a == a (their types are different tough). You can try a simple example here: http://ideone.com/96w3oa
Ok. Now we can see why you got a segmentation fault. Because &a is equal to a, your string[0] actually does an extra deference. The correct way would be:
printf("%s", string);
or
printf("%s", (&string)[0]);
if you use
char a[] = "blahblah";
For more information regarding the difference between the two statements you tried, please refer to this post (especially the post by John Bode): What is the difference between char s[] and char *s?.
Here is also a very good explanation:
http://publications.gbdirect.co.uk/c_book/chapter5/arrays_and_address_of.html
When you are passing the array to the foo function, you should do in this manner.
#include<stdio.h>
void display(char *);
int main()
{
char arr[]="Do something";
display(arr);
return 0;
}
void display(char *string)
{
printf("%s",string);
}
else you might be getting segmentation error.while using &array_name, you actually pass the address of the starting element.

pointers for getting elements of an array in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
pointer arithmetic in C for getting a string
I am a newbie in C and I would like to get the elements of an array with a function, I have tried different options, but I still do not get the elements.
My function is:
void getelements(int *a, int cl)
{
int *p;
for (p=&a[0];p<&a[cl];p++)
{
printf("%d\n",*p);
}
}
I know that the solution should work like that, but it only prints the first element and then memory positions. I am calling my function with:
int v={10,12,20,34,45};
getelements(&v,5);
Any help? I need to use arithmetic of pointers.
Thanks
First, Please don't update code to fix bugs while a question is open. It makes most of the current answers meaningless, doesn't grant credit where it is due to the person(s) that solved one or more issues in your prior code, and makes the casual reader looking for a related problem to their own completely confused by both the question and the answers therein. If you want to amend an update do so in addition to the original problem, but if it an entirely different issue, then mark as answered, give credit where it is due, and open a new question with your new code and different problem(s) (ideally, anyway).
As written now, your function is fine. But your real issue is this:
// compile with -Wall -Werror and look at the warning here
int v={10,12,20,34,45}; // <== WRONG
getelements(&v,5); // <== Harmless, but bad form.
This should be like this instead, assuming you want to print all elements in the array:
int v[] = {10,12,20,34,45};
getelements(v, sizeof(v)/sizeof(v[0]));
Note the [] following your array. Without it, the &v was masking what would have been a big-fat warning or error from the compiler that int is being passed as an int *. Furthermore, if you compile your prior code with full warnings treated as errors (-Wall -Werror for gcc) you will get an error like the following on your v declaration line:
main.c:116:15: Excess elements in scalar initializer
In other words, everything past the first element was ignored, and thus your pointer was running off into undefined behavior land. Changing the declaration and invocation to what I have above will address this as well as ensure you don't make that mistake again, since sizeof(v[0]) won't even compile unless v is an array or pointer type. The latter can still cause headaches when you use a pointer rather than an array with such a calculation, but thats something you just have to discipline yourself against doing in C.
try this and let me know if that works.
void getelements(int *a)
{
int *p;
int l=5;
for (p=a;p<a+l;p++)
{
printf("%d\n",*p);
}
}
It's best to pass in the length of the array along with the array itself.
#include <stdlib.h>
#include <stdio.h>
void get_elements(int* values, int length)
{
int i;
for (i = 0; i < length; ++i)
{
printf("%d\n", values[i]);
}
}
int main(int argc, char** argv)
{
int vals[3];
vals[0] = 0;
vals[1] = 1;
vals[2] = 2;
get_elements(vals, 3);
getchar();
return 0;
}
Using the code similar to your original post (before the addition of the array length as a method parameter), you could do the follow (which is a bit convoluted if you ask me).
void get_elements(int* values, int length)
{
int *p;
for (p = &values[0]; p < &values[length]; p++)
{
printf("%d\n", *p);
}
}
Actually you are passing array address in
getelements(&v,5)
in function
getelements()
you are treating it like an array!!!
void getelements(int *a, int cl)
{
int *p;
for (p=a;p<a+cl;p++)
{
printf("%d\n",*p);
}
}
Let me know if you are cleared conceptually!!!
As per my knowledge and seeing your code.you have hardcoded the length of array to 5. I think you can also pass array length as a parameter to function; or you can use this function and see if it gives the desired result
void getelements(int *a)
{
int *p;
int i = 0;
int l=5;
p = a
for (i = 0;i<l;i++)
{
printf("%d\n",*(p + i));
}
}

pointers in c (beginner)

I just started to look at C, coming from a java background. I'm having a difficult time wrapping my head around pointers. In theory I feel like I get it but as soon as I try to use them or follow a program that's using them I get lost pretty quickly. I was trying to follow a string concat exercise but it wasnt working so I stripped it down to some basic pointer practice. It complies with a warning conflicting types for strcat function and when I run it, crashes completly.
Thanks for any help
#include <stdio.h>
#include <stdlib.h>
/* strcat: concatenate t to end of s; s must be big enough */
void strcat(char *string, char *attach);
int main(){
char one[10]="test";
char two[10]="co";
char *s;
char *t;
s=one;
t=two;
strcat(s,t);
}
void strcat(char *s, char *t) {
printf("%s",*s);
}
Your printf() should look like this:
printf("%s",s);
The asterisk is unnecessary. The %s format argument means that the argument should be a char*, which is what s is. Prefixing s with * does an extra invalid indirection.
You get the warning about conflicting types because strchr is a standard library routine, which should have this signature:
char * strcat ( char * destination, const char * source );
Yours has a different return type. You should probably rename yours to mystrchr or something else to avoid the conflict with the standard library (you may get linker errors if you use the same name).
Change
printf("%s",*s);
to
printf("%s",s);
The reason for this is printf is expecting a replacement for %s to be a pointer. It will dereference it internally to get the value.
Since you declared s as a char pointer (char *s), the type of s in your function will be just that, a pointer to a char. So you can just pass that pointer directly into printf.
In C, when you dereference a pointer, you get the value pointed to by the pointer. In this case, you get the first character pointed to by s. The correct usage should be:
printf( "%s", s );
BTW, strcat is a standard function that returns a pointer to a character array. Why make your own?
Replacing *s with s won't append strings yet, here is fully working code :
Pay attention to function urstrcat
#include <stdio.h>
#include <stdlib.h>
/* urstrcat: concatenate t to end of s; s must be big enough */
void urstrcat(char *string, char *attach);
int main(){
char one[10]="test";
char two[10]="co";
char *s;
char *t;
s=one;
t=two;
urstrcat(s,t);
return 0;
}
void urstrcat(char *s, char *t) {
printf("%s%s",s,t);
}
pointers are variable which points to address of a variable.
#include "stdio.h"
void main(){
int a,*b;
a=10;
b=&a;
printf("%d",b);
}
in the follwing code you will see a int 'a' and a pointer 'b'.
here b is taken as pointer of an integer and declared by giving'' before it.'' declare that 'b' is an pointer.then you will see "b=&a".this means b is taking address of integer "a" which is keeping value 10 in that particular memory and printf is printing that value.

Resources