Reputation: 981
I am currently learning C with http://c.learncodethehardway.org/book/ and we are supposed to figure out some weird things on our own.
First of all I found this webpage that has already helped me understand some things about functions and function definitions and pointers and their use. Now the problem comes to when I see some "string" definitions.
Please correct me if these assumptions I am going to make are wrong:
char name[] = "John"; // creates an array of characters with these four letters + '\0'
A "string" is just an array of characters ending with '\0'
.
I also read that a *
before an identifier usually means that it is a pointer. For example:
int myNum = 18;
int *myNum_pointer = &myNum; // do I need the '&'?
If those assumptions are right, I don't understand what is going on here:
char *name = "John";
Is that a pointer to a string? Or is it another way of defining a string?? If so, is
char *name[] = "John";
the actual pointer to the "string"? (which is just an array of characters?).
EDIT
Reading all your answers and comments I must ask another thing. "type char *
" is a pointer to a char, right?
Upvotes: 2
Views: 190
Reputation: 3653
Let's look at the line:
int myNum = 18;
In that line, you define a variable which has several properties:
myNum
int
0xa1
, but it could be any value of the sort.18
In order to get a variable's address, you use the &
operator. In this case, the line:
int *myNum_pointer = &myNum;
On the right hand side, &myNum
returns the address of myNum
, which in our case evaluates to 0xa1
. And we are storing that in a variable called myNum_pointer
, which has the type pointer-to-int, which means that it stores the address of an int variable. Because myNum_pointer
is a variable in it's own right, it also has it's own properties:
myNum_pointer
int*
(pointer-to-int)0xa2
.0xa1
(the address of myNum
).So, yes, you do need the &
operator.
As for the part about the string: Don't define a string in C in this way.
char name[] = "John"; // Good
char *name = "John"; // Bad
This is because although arrays and pointers are related, they are not the same thing. Some compilers will warn you that the second statement is deprecated in C.
And finally,
char *name[] = "John";
Is incorrect. Because here you are saying the name is an array of pointers to characters, when it's just an array of characters.
"John"
is actually a string literal, which is an array of {'J', 'o', 'h', 'n', 0}
, where 0
is the null-termination character which signifies the end of a string in C. In fact, without the last 0
, {'J', 'o', 'h', 'n'}
would simply be an array of characters, and not a proper string, which is another important distinction.
Upvotes: 1
Reputation: 25865
int myNum = 18;
int *myNum_pointer = &myNum; // do I need the '&'?
The type of myNum
is int
, which contains integer.
The type of myNum_pointer
is int *
, which contains address of integer variables.
-----------------------------------------------------
variables: | myNum | myNum_pointer |
-----------------------------------------------------
address : | 0x12341234 | 0x12341238 |
-----------------------------------------------------
the &
operator gets the address of operand. So, &myNum
is equal to 0x12341234
So the variables are initialized like this:
variables: | myNum | myNum_pointer |
---------------------------------------------
address : | 0x12341234 | 0x12341238 |
---------------------------------------------
value : | 18 | 0x12341234 |
---------------------------------------------
Now
char *name = "John";
defines name as a pointer to the first character in the string. The assignment means that as soon as the program loads, the pointer is set to hold the address of where the string is stored. It put string literal in read only part. pointers only hold an address, they cannot hold all the characters in a character array. This means that when we use a char * to keep track of a string, the character array containing the string must already exist.
EX>
char name[] = "John";
char *name2;
name2=name;
name @2000
----------------------
| j | o | h | n | \0 |
----------------------
name2 @3000
--------
| 2000 |
--------
Also
For pointer to string array you can define it like
char * mystr[10];
After that you can initilize it by like
mystr[i]="john";
OR at define time also you can initialize like
const char *digitnames[] = {"zero", "one", "two", "three",
"four", "five", "six", "seven", "eight", "nine"};
Upvotes: 2
Reputation: 310930
This statement
char name[] = "John";
means that name
is an array of characters that will contain the following sequence
{ 'J', 'o', 'h', 'n', '\0' }
In fact you could write
char name[] = { 'J', 'o', 'h', 'n', '\0' };
These records are equivalent.
As for this statement
char *name = "John";
then there are the following actions made by the compiler. It creates an array of type char[5]
to store the string literal and then assigns the address of the first character of this array to pointer name
. So name
will contain the address of the first character of the string literal. Though string literals in C has types of non-const arrays you may not change them. So it would be better to write
const char *name = "John";
For this statement
char *name[] = "John";
the compiler shall issue an error becuase to initialize an array (except character arrays) there must be used a brace-init list. The valid record will look as
char *name[] = { "John" };
In this case the array would have only one element of type char *
that would point to the first character of the string literal. The string literal itself would be placed in memory as an array of type char[5]
by the compiler.
As for the difference between records
int myNum = 18;
int *myNum_pointer = &myNum; // do I need the '&'?
and
char *name = "John";
then in the first record there is a scalar object myNum
, You have to apply operator &
that to get its address.
While in the second record the string literal is an array. In expressions such this it is adjasted by the compiler to a pointer to the first element of the array. So you have no apply operator &
for the string literal. The expression in the right side has already type char *
.
Upvotes: 4
Reputation: 1100
To answer your question of:
int myNum = 18;
int *myNum_pointer = &myNum; // do I need the '&'?
Yes, you need the & (which is the Address-of operator). This assigns the pointer myNum_pointer the address of myNum. If you take out the &, you are assigning the number in myNum directly to the pointer, which is a bad thing, and not what is intended. The problem would occur when you later use myNum_pointer, and it points to memory address 18 instead of the memory address of the myNum variable (if the compiler even accepts it). This would likely cause a segmentation fault at run time, which can be tricky to debug.
Upvotes: 0
Reputation:
I guess that this is a duplicate of hundreds of other qustions, but I'hm going to answer it anyway.
First, the '&' is a unary operator for the adress of a variable. So, for example, &foo could be an adress like 0xffff. So you definitely need the '&', because otherwise, if foo==1, your pointer would be on the adress 0x0001, and if you wanted to change the value, you would get a segfault (I guess it wouldn't even compile).
Second:
char* name="John";
does two things. It allocates an unchangable part in the memory and writes "John\0" into it. You have a pointer to that memory, but you can't change it, e.g write "john\0".
Third:
char* name[]
is a pointer to an array of chars. it can also be written like this:
char** name
or this:
char name[][]
It is actually an array of strings.
Fun fact: a '*' in front of a pointer gives back the value of the object the poiner points to. E.g:
int i=0;
int* pi;
pi=&i;
i==*pi //this is true
Upvotes: 0
Reputation: 363517
char *name = "John";
defines an anonymous, statically allocated array of five bytes holding {'J', 'o', 'h', 'n', 0}
, and declares a pointer name
which initially points to the first element of the aforementioned array. That's the rule in C: an array "decays" into a pointer to its first element.
char *name[] = "John";
is invalid. It defines an array of char
as before, but then tries to assign it to an array of char
pointers, which makes no sense. The use case for char *[]
is to store (pointers to the first char
of) multiple strings:
char *names[] = {"John", "Mary"};
Read as: names
is an array ([]
), each element of which is a char*
; this array we initialize with the elements "John"
and "Mary"
, and since we're initializing pointers, these char
arrays decay into pointers to their first elements.
Upvotes: 1