Why can a char pointer variable be initialized to a string but an int pointer variable can not be initialized to an array of integers?
a C-style string is simply an array of chars
Correct.
An array is simply a shorthand version of referring to the pointer (which stores the first value of the array) and an offset.
No, not really.
the method cout interprets the argument szstring as a string type and prints out all the characters until the NUL character
cout
is not a "method", but its operator<<
works this way yes.
Why can a char pointer variable be initialized to a string but an int pointer variable can not be initialized to an array of integers?
The simple answer is that string literals are special, otherwise we would not be able to use them.
In many ways, including this way, the language standards dictate special handling for both string literals and char*
s.
why can I not initialize an int type pointer to the first element in an array of integers
C++ could have ultimately extended the syntax of other pointer initialisations to do a similar thing, but it didn't actually need to because instead we have the far superior:
std::vector<int> myInts{1,2,3};
How can a char pointer be initialized with a string (Array of characters) but an int pointer not with an array of integer?
In case of you're trying to initialize an int *
with
{1,2,3,4,5};
it is wrong because {1,2,3,4,5};
, as-is, is not an array of integers. It is a brace enclosed list of initializer. This can be used to initialize an int
array (individual elements of the array, to be specific), but not a pointer. An array is not a pointer and vice-versa.
However, you can make use of a compound literal to initialize an int *
, like
int * a = (int []){1,2,3,4,5};
Pointer to Char Initialization in C
There is one thing you need to learn about constant string literals. Except when used to initialize an array (for example in the case of v1
in your example code) constant string literals are themselves arrays. For example if you use the literal "AB"
it is stored somewhere by the compiler as an array of three characters: 'A'
, 'B'
and the terminator '\0'
.
When you initialize a pointer to point to a literal string, as in the case of str1
and str2
, then you are making those pointers point to the first character in those arrays. You don't actually create an array named str1
(for example) you just make it point somewhere.
The definition
char *str1 = "AB";
is equivalent to
char *str1;
str1 = "AB";
Or rather
char unnamed_array_created_by_compiler[] = "AB";
char *str1 = unnamed_array_created_by_compiler;
There are also other problematic things with the definitions you show. First of all the arrays v3
, v4
, v5
and v6
. You tell the compiler they will be arrays of two char
elements. That means you can not use them as strings in C, since strings needs the special terminator character '\0'
.
In fact if you check the sizes of v1
and v2
you will see that they are indeed three bytes large, once for each of the characters plus the terminator.
Another important thing you miss is that while constant string literals are arrays of char
, you miss the constant part. String literals are really read-only, even if not stored as such. That's why you should never create a pointer to char
(like str1
and str2
) to point to them, you should create pointers to constant char
. I.e.
const char *str1 = "AB";
Different Types Of Initializing Character Arrays in C
- Pointers and Arrays/Strings have similar behaviours.
Actually, no, I wouldn't agree with that. It is an oversimplification that hides important details. The true situation is that arrays have almost no behaviors of their own, but in most contexts, an lvalue designating an array is automatically converted to pointer to the first array element. The resulting pointer behaves like a pointer, of course, which is what may present the appearance that pointers and arrays have similar behaviors.
Additionally, arrays are objects, whereas strings are certain configurations of data that char
arrays can contain. Although people sometimes conflate strings with the arrays containing them or with pointers to their first elements, that is not formally correct.
- array[] , *array , &array[0]. They all are one and the same.
No, not at all, though the differences depend on the context in which those appear:
In a declaration of array
(other than in a function prototype),
type array[]
declaresarray
as an array oftype
whose size will be determined from its initializer;type *array
declaresarray
as a pointer totype
; and&array[0]
is not part of any valid declaration ofarray
.
In a function prototype,
type array[]
is "adjusted" automatically as if it weretype *array
, and it therefore declaresarray
as a pointer totype
;type *array
declaresarray
as a pointer totype
; and&array[0]
is not part of any valid declaration ofarray
.
In an expression,
array[]
is invalid;*array
is equivalent toarray[0]
, which designates the first element ofarray
; and&array[0]
is a pointer toarray[0]
.
Now, you ask,
Why does the three statements in this code work, and char * help one does not ?
"Help_Me"
is a string literal. It designates a statically-allocated array just large enough to contain the specified characters plus a string terminator. As an array-valued expression, in most contexts it is converted to a pointer to its first element, and such a pointer is of the correct type for use in ...
// char *help = "Help_Me"; //Works
But the appearance of a string literal as the initializer of a char
array ...
// char help[] = "Help_Me"; //Works
... is one of the few contexts where an array value is not automatically converted to a pointer. In that context, the elements of the array designated by the string literal are used to initialize the the array being declared, very much like ...
// char help[] = {'H','e','l','p','_','M','e','\0'}; //Works
. There, {'H','e','l','p','_','M','e','\0'}
is an array initializer specifying values for 8 array elements. Note well that taken as a whole, it is not itself a value, just a syntactic container for eight values of type int
(in C) or char
(in C++).
And that's why this ...
char *help = {'H','e','l','p','_','M','e','\0'}; //Error
... does not make sense. There, help
is a scalar object, not an array or a structure, so it takes only one value. And that value is of type char *
. The warnings delivered by your compiler are telling you that eight values have been presented instead of one, and they have, or at least the one used for the initialization has, type int
instead of type char *
.
Why do strings work, but character and int arrays do not work in a pointer array?
This
int st[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int st2[]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
int *day_tab[]= {
st,
st2
};
Is three arrays: two of integers (with their own storage), and one array of two elements which are pointers to the first two arrays.
However, this is not valid:
int *day_tab[]= {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
As before you have declared an array of pointers to integers, but pointers to what? Those braced lists are not storage locations, they cannot be pointed to.
Your final example is basically valid but dangerous:
char *day_tab[]= {
"01",
"01"
};
It is an array of two pointers to characters, and those pointers are initialized with string literals. String literals are very special in that they are actually stored somewhere, usually in read-only memory, and they can be shared (so the "01" string used twice can be stored just once). Braced lists don't have this feature in C, it's only for string literals.
The reason the final code is dangerous is that it is char*
not const char*
. The non-const type is accepted for reasons of backward compatibility but is not a good idea because modifying the data in a literal string is not allowed. So you're setting yourself up for a potential disaster if you actually use those pointers to write to the "01" string storage.
Initializing a char pointer C++
String literals are really arrays of constant characters (with the including terminator).
When you do
const char *cp = "Hello world";
you make cp
point to the first character of that array.
A little more explanation: Arrays (not just C-style strings using arrays of char
but all arrays) naturally decays to pointers to their first element.
Example
char array[] = "Hello world"; // An array of 12 characters (including terminator)
char *pointer1 = &array[0]; // Makes pointer1 point to the first element of array
char *pointer2 = array; // Makes pointer2 point to the first element of array
Using an array is the same as getting a pointer to its first element, so in fact there is an address-of operator &
involved, but it's implied and not used explicitly.
As some of you might have noted, when declaring cp
above I used const char *
as the type, and in my array-example with pointer1
and pointer2
I used a non-constant plain char *
type. The difference is that the array created by the compiler for string literals are constant in C++, they can not be modified. Attempting to do so will lead to undefined behavior. In contrast the array I created in my latter example is not constant, it's modifiable and therefore the pointers to it need not be const
.
Why can you initialize a string pointer as a string literal, but not as an array?
Why can you initialize a string pointer as a string literal, but not as an array?
Because {'a', 'b', 'c', '\0'}
is not an array; it is a list of values to put in the thing being initialized.
The syntax {'a', 'b', 'c', '\0'}
does not stand for an array in C. People see it being used to initialize arrays, but, when used in that way, it is just a list of values. It could also be used to initialize a structure, because it is just listing values to put into the thing being initialized. It is not, by itself, an array.
In char *word2 = {'a', 'b', 'c', '\0'};
, it does not make sense to initialize word2
with the values 'a'
, 'b'
, 'c'
, and '\0'
. It is just one pointer and should be initialized with one value. Giving a list of four values to initialize one thing does not make sense.
In char *word2 = "abc";
, "abc"
is not a list of values. It is a string literal. A string literal defines a static array that is filled with the characters of the string. And then the string literal is automatically converted to a pointer to its first element, and it is this pointer that is used to initialize word2
.
So char *word2 = "abc";
does two things: The string literal defines an array, and the initialization sets word2
to point to the first element of that array. In contrast, in char *word2 = {'a', 'b', 'c', '\0'};
, there is nothing to define an array; the list of values is just a list of values.
Comparing this to array initializations, in char word2[] = {'a', 'b', 'c', '\0'};
, the array is initialized with a list of values, which is fine. However, in char word1[] = "abc";
, something special happens. C 2018 6.7.9 14 says we can initialize an array of character type with a string literal, and the characters of the string will be used to initialize the elements of the array.
Related Topics
Understanding Gsl::Narrow Implementation
How to Alter Qt Widgets in Winapi Threads
Dereferencing One Past the End Pointer to Array Type
Directx/C++ 3D Engine Programming: Learn Now, or Wait for Directx 12
Branch Prediction on a Function Pointer
What Are the Rules Governing C++ Single and Double Precision Mixed Calculations
Convert Hexadecimal String with Leading "0X" to Signed Short in C++
Multiple Classes in a Header File VS. a Single Header File Per Class
Why Are Pointers to a Reference Illegal in C++
When Does a Std::Vector Reallocate Its Memory Array
Do You Know Tool Building Tree of Include Files in Project\File
Remove Duplicates from a List<Int>
Why Is Copy Constructor Not Being Called in This Code
Why Does Rand() Return the Same Value Using Srand(Time(Null)) in This for Loop
What Is the Purpose of Forward Declaration
Using an Union (Encapsulated in a Struct) to Bypass Conversions for Neon Data Types
In C++ Why Can't I Write a For() Loop Like This: For( Int I = 1, Double I2 = 0;