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 C programming language works by writing your code into an executable file. The C compiler will take that executable and convert it in its entirety into machine code that will then be executed by your computer at runtime.
The biggest reason to learn C over assembly is because it's much easier and faster to write code in C than in assembly for a given programming task. With C, you will write far fewer lines of code, complete the job much quicker, and with far less mental effort than if you wrote it in assembly.
The C programming language is a procedural and general-purpose language that provides low-level access to system memory. A program written in C must be run through a C compiler to convert it into an executable that a computer can run.
C may be best for systems programming because of its low-level hardware access features. C may be best because it underpins most of the IT industry; without C, we wouldn't have Windows, macOS, Linux, Android, iOS, etc.; without C, we wouldn't have most of our language compilers.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With