Different uses of pointers(*) in C - c

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?

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 *.

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"};

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.

Let's look at the line:
int myNum = 18;
In that line, you define a variable which has several properties:
Identifier : the variable name myNum
Type : int
Address : this is it's location in memory. For the purpose of this explanation, I'm giving it a value of 0xa1, but it could be any value of the sort.
Value: 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:
Identifier : the variable name myNum_pointer
Type : int* (pointer-to-int)
Address : it's own location in memory. let's say it's 0xa2.
Value: 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.

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

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.

Related

Why i can init char pointer but not int pinter?

I'm recollecting my C programming skills after 1 year. So I decided to start from scratch. I got stuck with poineters
why i can do :
char *string="Hello";
printf ("%s",string);
But i can't do :
int *pt=23;
printf("%d",*pt);
Doesn't the pointer need to be an address ? but why the first example works?
Because using string literals to initialize a character pointer or array is a special allowed syntax, with specific rules. In your case you set a pointer to point at a string literal's address, the string literal itself having type char[] and existing in read-only memory.
For the integer case, yes it needs to be an address, or more specifically another integer pointer. You can't initialize a pointer with an integer. See:
"Pointer from integer/integer from pointer without a cast" issues
The string literal "Hello" is stored in memory as a character array like
char unnamed_literal[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
So in this declaration
char *string="Hello";
the pointer string is assigned with the address of the first character of the already existent array. It can be imaging like
char unnamed_literal[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char *string = unnamed_literal;;
As for this declaration
int *pt=23;
then the value 23 is not a valid address that points to a valid object defined in your program. The compiler should issue a message that you are trying to assign an integer to a pointer. Thus this call
printf("%d",*pt);
invokes undefined behavior.
To make an analogy with the initialization of a pointer by string literal you could write for example
int a[] = { 1, 2, 3 };
int *pt = a;
This is syntaxic sugar from standard C:
What is actually stored in your char pointer is the address at which the string is loaded in memory when starting the program.
For an integer however, it will try to set the address of the pointer to 23 which is (and should be) invalid.
For example an integer, like:
int VAL = 10;
int *ptr = &VAL; /* ptr now points to val */
*ptr = DESIRED_VALUE; /* *(asterisk) here means dereference, meaning that the value of VAL will change */
or
int *&VAL = DESIRED_VALUE;
int variable_1 = 23;
int *pointer_to_int = &variable_1;
The first line is an integer variable, initialized to an integer value.
The second line is a pointer to integer variable, initialized to an address of an integer variable (the address of the variable variable_1, defined in the previous declaration.
char *p = "Charles Dickens";
This is a char pointer variable, initialized to the address of a string literal, which is a constant array of characters, composed of the characters between the quotes, plus an aditional \0 character, that represents the end of the string literal.
char c = 'a'; /* char variable initialized to value 'a' */
char *pointer_to_c = &c;
Probably you will find this last declaration very similar to the one above. The different thing is that in C you can use string literals, but a single character is similar to an integer, and this is the way pointer variables initialize: with variables addresses.

How can a character pointer without any address specification hold data?

The following C program is not supposed to work by my understanding of pointers but it does.
#include<stdio.h>
main() {
char *p;
p = "abcdefghijk";
printf("%s", p);
}
Outputs:
abcdefghijk
The char pointer variable p is pointing to something random as I have not assigned any address to it like p = &i; where i is some char array.
That means if I try to write anything to the memory address held by the pointer p it should give me segmentation fault since it is some random address not assigned to my program by the OS.
But the program compiles and runs successfully. What is happening?
In this expression statement
p="abcdefghijk";
the pointer p is assigned with the address of the first character of the string literal "abcdefghijk" that the compiler stores as a zero-terminated character array in the static memory area.
Thus in this statement there are two things that happen. At first the compiler creates an unnamed character array with the static storage duration to hold the string literal. Then the address of the first character of the array is assigned to the pointer. You can imagine it the following way
char unnamed[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', '\0' };
p = unnamed;
or
p = &unnamed[0];
Take into account that though string literals in C have types of non-constant character arrays opposite to C++ where they have types of constant character arrays nevertheless you may not change string literals. Any attempt to change a string literal results in undefined behavior.
So this code snippet is invalid
char *p = "abcdefghijk";
p[0] = 'A';
But you could create your own character array initializing it with the string literal and in this case you can change the array. For example
char s[] = "abcdefghijk";
char *p = s;
p[0] = 'A';
From the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
Pay attention to this part of the quote
It is unspecified whether these arrays are distinct provided their
elements have the appropriate values.
It means that for example if you will write
char *p = "abcdefghijk";
char *q = "abcdefghijk";
then it is not necessary that this expression yields true (integer value 1)
p == q
and the result depends on compiler options whether the same string literals are stored as one array or as distinct arrays.
In C a string literal like "abcdefghijk" is actually stored as an (read-only) array of characters. The assignment makes p point to the first character of that array.
I note that you mention p = &i where i would be an array. That is in most cases wrong. Arrays naturally decays to pointers to their first element. I.e. doing p = i would be equal to p = &i[0].
While both &i and &i[0] would result in the same address, it is semantically very different. Lets take an example:
char array[10];
With the above definition doing &array[0] (or just plain array as explained just above) you get a pointer to char, i.e. char *. When doing &array you get a pointer to an array of ten characters, i.e. char (*)[10]. The two types are very different.
"abcdefghijk" is a string constant, and p="abcdefghijk"; will give to p adress of this string.
So it's normal that printf("%s",p); display this string without error.
p="abcdefghijk";
You are creating a string literal in code segment and assigning the address of first character of the literal to the pointer, and as the pointer is not constant you can assign it again with different addresses.
The string literal "abcdefghijk" is compiled by putting the characters in a block in the program's datatext segment. Then your assignment of it to the pointer assigns the address of its location in the data segment to the pointer.

character pointer takes the address of what

I read that:
char a[] = "string";
is a: "string"
whereas
char *ptr = "string"
is ptr: [__] ---> "string"
I am little confused. One thing I know is that pointers always store the address. In case of character pointer what address does it store? What does this block represent (block which I made pointing to string). Is it the starting address of the "string".
And in case of array? How can I clearly differentiate between char pointer and char array?
Diagrams may help.
char *ptr = "string";
+-------+ +----------------------------+
| ptr |--------->| s | t | r | i | n | g | \0 |
+-------+ +----------------------------+
char a[] = "string";
+----------------------------+
| s | t | r | i | n | g | \0 |
+----------------------------+
Here, ptr is a variable that holds a pointer to some (constant) data. You can subsequently change the memory address that it points at by assigning a new value to ptr, such as ptr = "alternative"; — but you cannot legitimately change the contents of the array holding "string" (it is officially readonly or const, and trying to modify it may well crash your program, or otherwise break things unexpectedly).
By contrast, a is the constant address of the first byte of the 7 bytes of data that is initialized with the value "string". I've not shown any storage for the address because, unlike a pointer variable, there isn't a piece of changeable storage that holds the address. You cannot change the memory address that a points to; it always points to the same space. But you can change the contents of the array (for example, strcpy(a, "select");).
When you call a function, the difference disappears:
if (strcmp(ptr, a) == 0)
…string is equal to string…
The strcmp() function takes two pointers to constant char data (so it doesn't modify what it is given to scrutinize), and both ptr and a are passed as pointer values. There's a strong case for saying that only pointers are passed to functions — never arrays — even if the function is written using array notation.
Nevertheless, and this is crucial, arrays (outside of paramter lists) are not pointers. Amongst other reasons for asserting that:
sizeof(a) == 7
sizeof(ptr) == 8 (for 64-bit) or sizeof(ptr) == 4 (32-bit).
In case of character pointer what address does it store? What does this block represent (block which I made pointing to string). Is it the starting address of the "string".
This blocks represents a WORD or DWORD (achitecture dependant), the content of this block is a memory address, a random location defined at compile time. That memory address is the address of first character of the string.
In practice, the difference is how much stack memory it uses.
For example when programming for microcontrollers where very little memory for the stack is allocated, makes a big difference.
char a[] = "string"; // the compiler puts {'s','t','r','i','n','g', 0} onto STACK
char *b = "string"; // the compiler puts just the pointer onto STACK
// and {'s','t','r','i','n','g',0} in static memory area.
Maybe this will help you understand.
assert(a[0] == 's'); // no error.
assert(b[0] == 's'); // no error.
assert(*b == 's'); // no error.
b++; // increment the memory address, so points to 't'
assert(*b == 's'); // assertion failed
assert(*b == 't'); // no error.
char a[] = "string"; initializes the value of the array of chars called a with the value string. And the size of a.
char *a = "string"; creates an unnamed static array of chars somewhere in memory and return the address of the first element of this unnamed array to a.
In the first one, a stores the address of the first element of the array. So when we index something like a[4], this means 'take' the 4th element after the begin of the object named a.
In the second, a[4] means 'take' the 4th element after the object that a points to.
And for your last question:
A char array is a 'block' of contiguous elements of type char. A char pointer is a reference to an element of the type char.
Due to pointer arithmetics, a pointer can be used to simulate (and access) an array.
Maybe those 3 links help make the difference more clear:
http://c-faq.com/decl/strlitinit.html
http://c-faq.com/aryptr/aryptr2.html
http://c-faq.com/aryptr/aryptrequiv.html
You may find it useful to think of:
char * a = "string";
as the same as:
char SomeHiddenNameYouWillNeverKnowOrSee[] = "string"; /* may be in ReadOnly memory! */
char * a = &SomeHiddenNameYouWillNeverKnowOrSee[0];
Did you ever tried to open some executabe file with a text editor ? It appears merely as garbage, but in the middle of the garbage you can see some readable strings. These are all the litteral strings defined in you program.
printf("my literal text");
char * c = "another literal text"; // should be const char *, see below
If your program contains the above code you may be able to find my literal textand another literal text in program's binary (actually it depends on the details of the binary format, but it often works). If you are Linux/Unix user you can also use the strings command for that.
By the way, if you write the above code, C++ compilers will emit some warning (g++ say: warning: deprecated conversion from string constant to ‘char*’ because such strings are not of type char * but const char [] (const char array) which decay to const char * when assigned to a pointer.
This also is the case with C compilers, but the above error is so very common that this warning is usually disabled. gcc does not even include in -Wall, you have to explicitely enable it through -Wwrite-strings. The warning is warning: initialization discards ‘const’ qualifier from pointer target type.
It merely reminds that you are theoretically not allowed to change the literal texts through pointers.
The executable may loads such strings in a read only part of Data segment memory. If you try to change the content of string it can raise a memory error. Also the compiler is allowed to optimise literal text storage by merging identical strings for instance. The pointer just contains the address in (read only) memory where the literal strings will be loaded.
On the other hand
char c[] = "string"; is mere syntaxic sugar for char c[7] = {'s', 't', 'r', 'i', 'n', 'g', 0}; If you do sizeof(c) in your code it will be 7 bytes (the size of the array, not the size of a pointer). This is an array on stack with an initialiser. Internally the compiler can do wathever it likes to initialize the array. It can be characters constants loaded one by one in the array, or it can involved a memcpy of some hiden string literal. The thing is that you have no way to tell the difference from your program and find out where the data comes from. Only the result matters.
By the way a thing that is slightly confusing is that if you define some function parameter of the type char c[], then it won't be an array but an alternative syntax for char * c.
In your example, ptr contains the address of the first char in the string.
As for the difference between a char array and a string, in C terms there is no difference other than the fact that by convention what we call "string" is a char array where the final char is a NULL, to terminate the string.
i.e. even if we have an array of char with 256 potential elements, if the first (0th) char is null (0) then the length of the string is 0.
Consider a variable str which is a char array of 5 chars, containing the string 'foo'.
*ptr => str[0] 'f'
str[1] 'o'
str[2] 'o'
str[3] \0
str[4] ..
A char *ptr to this array would reference the first element (index = 0) and the 4th element (index = 3) would be null, marking the end of the 'string'. The 5th element (index = 4) will be ignored by string handling routines which respect the null terminator.
If you are asking what a contains in each case then:
char a[] = "string";
// a is a pointer.
// It contains the address of the first element of the array.
char *a = "string";
// Once again a is a pointer containing address of first element.
As rnrneverdies has explained in his answer, the difference is in where the elements are stored.

C: Behaviour of arrays when assigned to pointers

#include <stdio.h>
main()
{
char * ptr;
ptr = "hello";
printf("%p %s" ,"hello",ptr );
getchar();
}
Hi, I am trying to understand clearly how can arrays get assign in to pointers. I notice when you assign an array of chars to a pointer of chars ptr="hello"; the array decays to the pointer, but in this case I am assigning a char of arrays that are not inside a variable and not a variable containing them ", does this way of assignment take a memory address specially for "Hello" (what obviously is happening) , and is it possible to modify the value of each element in "Hello" wich are contained in the memory address where this array is stored. As a comparison, is it fine for me to assign a pointer with an array for example of ints something as vague as thisint_ptr = 5,3,4,3; and the values 5,3,4,3 get located in a memory address as "Hello" did. And if not why is it possible only with strings? Thanks in advanced.
"hello" is a string literal. It is a nameless non-modifiable object of type char [6]. It is an array, and it behaves the same way any other array does. The fact that it is nameless does not really change anything. You can use it with [] operator for example, as in "hello"[3] and so on. Just like any other array, it can and will decay to pointer in most contexts.
You cannot modify the contents of a string literal because it is non-modifiable by definition. It can be physically stored in read-only memory. It can overlap other string literals, if they contain common sub-sequences of characters.
Similar functionality exists for other array types through compound literal syntax
int *p = (int []) { 1, 2, 3, 4, 5 };
In this case the right-hand side is a nameless object of type int [5], which decays to int * pointer. Compound literals are modifiable though, meaning that you can do p[3] = 8 and thus replace 4 with 8.
You can also use compound literal syntax with char arrays and do
char *p = (char []) { "hello" };
In this case the right-hand side is a modifiable nameless object of type char [6].
The first thing you should do is read section 6 of the comp.lang.c FAQ.
The string literal "hello" is an expression of type char[6] (5 characters for "hello" plus one for the terminating '\0'). It refers to an anonymous array object with static storage duration, initialized at program startup to contain those 6 character values.
In most contexts, an expression of array type is implicitly converted a pointer to the first element of the array; the exceptions are:
When it's the argument of sizeof (sizeof "hello" yields 6, not the size of a pointer);
When it's the argument of _Alignof (a new feature in C11);
When it's the argument of unary & (&arr yields the address of the entire array, not of its first element; same memory location, different type); and
When it's a string literal in an initializer used to initialize an array object (char s[6] = "hello"; copies the whole array, not just a pointer).
None of these exceptions apply to your code:
char *ptr;
ptr = "hello";
So the expression "hello" is converted to ("decays" to) a pointer to the first element ('h') of that anonymous array object I mentioned above.
So *ptr == 'h', and you can advance ptr through memory to access the other characters: 'e', 'l', 'l', 'o', and '\0'. This is what printf() does when you give it a "%s" format.
That anonymous array object, associated with the string literal, is read-only, but not const. What that means is that any attempt to modify that array, or any of its elements, has undefined behavior (because the standard explicitly says so) -- but the compiler won't necessarily warn you about it. (C++ makes string literals const; doing the same thing in C would have broken existing code that was written before const was added to the language.) So no, you can't modify the elements of "hello" -- or at least you shouldn't try. And to make the compiler warn you if you try, you should declare the pointer as const:
const char *ptr; /* pointer to const char, not const pointer to char */
ptr = "hello";
(gcc has an option, -Wwrite-strings, that causes it to treat string literals as const. This will cause it to warn about some C code that's legal as far as the standard is concerned, but such code should probably be modified to use const.)
#include <stdio.h>
main()
{
char * ptr;
ptr = "hello";
//instead of above tow lines you can write char *ptr = "hello"
printf("%p %s" ,"hello",ptr );
getchar();
}
Here you have assigned string literal "hello" to ptr it means string literal is stored in read only memory so you can't modify it. If you declare char ptr[] = "hello";, then you can modify the array.
Say what?
Your code allocates 6 bytes of memory and initializes it with the values 'h', 'e', 'l', 'l', 'o', and '\0'.
It then allocates a pointer (number of bytes for the pointer depends on implementation) and sets the pointer's value to the start of the 5 bytes mentioned previously.
You can modify the values of an array using syntax such as ptr[1] = 'a'.
Syntactically, strings are a special case. Since C doesn't have a specific string type to speak of, it does offer some shortcuts to declaring them and such. But you can easily create the same type of structure as you did for a string using int, even if the syntax must be a bit different.

Strings in c programming

why am i unable to compile the program containing the code
char name[10];
name= "Rajesh";
While i am able to compile a program with
char name[10]="Rajesh";
That's because your code snippet is not performing declaration, but assignment:
char name[10]; // Declaration
name= "Rajesh"; // Assignment.
And arrays are not directly assignable in C.
The name name actually resolves to the address of its first element (&name[0]), which is not an lvalue, and as such cannot be the target of an assignment.
String Variable Declarations and Assignments
String variables can be declared just like other arrays:
char phrase[14];
String arrays can be initialised or partially initialised at the same time as being declared, using a list of values enclosed in "{}" braces (the same is true of arrays of other data types). For example, the statement
char phrase[14] = {'E','n','t','e','r',' ','a','g','e',':',' ','\0'};
both declares the array "phrase" and initialises it to the state. The statement
char phrase[14] = "Enter age: ";
is equivalent. If the "14" is omitted, an array will be created just large enough to contain both the value ""Enter age: "" and the sentinel character "'\0'", so that the two statements
char phrase[] = {'E','n','t','e','r',' ','a','g','e',':',' ','\0'};
char phrase[] = "Enter age: ";
are equivalent both to each other and to the statement
char phrase[12] = "Enter age: ";
However, it is important to remember that string variables are arrays, so we cannot just make assignments and comparisons using the operators "=" and "==". We cannot, for example, simply write
phrase = "You typed: "; //Wrong way
Instead, we can use a special set of functions for string assignment and comparison.
Edited :
And other way is to do that, using pointer : -
Declare variable
char const *phrase; /* a pointer to type character */
And initialize variable as where you want, as
phrase = "Test string";
You cannot assign values to string arrays by using assignment.
In C, You can only initialize arrays not assign them, a array of characters is no exception for this rule.
You will need to use string copying functions like strcpy or strncpy and so on.
However you can encapsulate a string in a struct and simulate this:
typedef struct Yourstring Yourstring;
struct Yourstring
{
char a[24];
};
Yourstring a = { "abcd" };
Yourstring b = a;
Yourstring c = { 0 };
c = b;
char name[10];
In this first example, you're declaring name to be an array of ten characters. The symbol name is now interpreted as the starting address of this array, but while you can write into the array, you can't move the symbol name.
So, this:
name= "Rajesh";
would mean pointing name away from the array you declared and at the location of the string literal "Rajesh" which is stored elsewhere in memory. You just can't do this.
What you can do is either:
strcpy(name, "Rajesh");
which copies your string literal from it's immutable location in your executable, into the char array you declared, or:
char const *pointer_to_name = "Rajesh";
which doesn't copy anything, but merely stores the address of your immutable string literal into a variable where you can use it, or your second example:
char name[10]="Rajesh";
which declares name to be an array of 10 characters and initialises it.
char name[10];
name= "Rajesh";
Here name is an array of characters.
The simple name is basically pointer to first element of array and it cannot be assigned with some value like it's done in above statement.
My point is
char name[10];
name= "Rajesh";
Explanation:
This is not the correct declaration of array. Strings are nothing but collection of characters terminated with '\0' operator. So, the array index (which in this case is 'name', basically points to address of 1st character in array i.e name holds the address of character 'R' in 'Rajesh'.
If you want to initialize like as mentioned above, the better approach could have been:
char name[10];
*name= "Rajesh";
Now, the above declaration won't throw any error, but still it will throw warning, like:
assignment makes integer from pointer without a cast [-Wint-conversion]
*name = "Rajesh"
AS char name[10]="Rajesh" is definition compiler understands what are you trying to do and corrects your mistake. In c++ strings written in "" are constant and some compilers put them to stringpools to save space. name="...." means that you are trying to assign a constant to a non-constant pointer which is not allowed.
you should use strcpy to copy a string into an array.
char name[10] ="Rajesh";
This one is an array initialization. The compiler knows of it. It's a one-shot trick. You can use it only when you define your variable. It would be equivalent to:
char name[10] = { 'R', 'a', 'j', 'e', 's', 'h', '\0' };
The other one is illegal, because you can't use array initialization outside of array definition.
I dont remember where exactly i read it but C standard says, you can assign a string value for an array at the defination but not after the defination.
char a[10]="rajesh" its a defination hence works
char a[10];a="rajesh"; fails its not a defination
rather you need to use strcpy(a,"rajesh") to assing a value for a string, if its not a defination

Resources