Can someone please tell me, what in general, will the following do in C ?
H.L = new int* [H.n];
Does this command create L variable in structure H of integer type with size n?
It will create an array of H.n pointers to int. A pointer to the first array element will be stored in H.L.
If you wanted an array of ints, remove the asterisk.
On a side note, you may be happier using a vector<int*> instead.
It is much easier to use.
In the right side of the expression statement
H.L = new int* [H.n];
there is created an array of type int *[H.n] using unary operator new []. That is each element of the array has type int *.
Expression H.n used in square brackets specifies the number of elements of the allocated array and must be converted to type size_t. Usually it is some integral type as for example int.
According to the C+ Standard (5.3.4 New)
...If it is an array, the new-expression returns a pointer to the initial
element of the array.
So the left side lvalue H.L should have type int ** or some type (usually in rare cases) that can be converted from int **.
Related
Here is the context:
int *t[10];
int n;
I am being told that t-n is of the type int**.
I don't exactly get what int** means, is it a pointer of a pointer? Why would the subtraction of a table of pointers - int would give a pointer of pointer of an int? When we refer to *t[0] do we refer to int* p to the pointer itself because it is an element of the table or do we implicitly need a pointer to point at the slot than have the pointer point to the another place?
Thanks in advance for explaining this to me.
I don't exactly get what int** means, is it a pointer of a pointer?
Yes.
int = integer
int * = pointer-to-integer
int ** = pointer-to-(pointer-to-integer)
int *** = pointer-to-(pointer-to-(pointer-to-integer))
(and so on)
Why would the subtraction of a table of pointers - int would give a
pointer of pointer of an int?
Because in C (and C++), an array decays into a pointer to the first item when necessary. For example, int *t[10] is an array of 10 pointer-to-int items. t can decay into a pointer to t[0], ie a pointer-to-(pointer-to-int), int **. That pointer can then be used for pointer arithmetic (like subtraction).
So, subtracting n from t would give you an int ** that is pointing n items "before" the beginning of your 10-item array (which BTW would not be a safe pointer to use, unless n was zero or a small negative number, since it would be pointing outside the valid bounds of the array's memory).
When we refer to *t[0] do we refer to int* p to the pointer itself
because it is an element of the table or do we implicitly need a
pointer to point at the slot than have the pointer point to the
another place?
I'm not sure I understand this question. Since t[10] is an array of 10 pointers (i.e. 10 int *'s), that means that t[0] is a single item in that array and therefore has type int *. Therefore *t[0] dereferences the first pointer in the array, yielding the actual int value that the pointer is pointing to.
what int** means
It's the type of a pointer to a pointer to an int. If you dereference a variable t of this type (like this: *t), you get a pointer to an int. If you dereference it twice (like this: **t), you get an int.
If you have TYPE a[N];, the array expression a, if evaluated, produces a pointer of type T *, pointing to a[0]. This is sometimes called C's array-to-pointer "decay" rule.
If TYPE is int *, as in your case, then TYPE * is int **.
Since your array is of int * pointers, the pointer which indexes into the array is a necessarily pointer to that element type.
Here is the code I'm having trouble to understand:
char* myPtr = "example";
myPtr[1] = 'x';
How am I allowed to use myPtr[1]? Why can I choose positions like a do on arrays? myPtr is not even an array.
Obs. I know about lookup table, literal pooling and string literals, my concern is just how this even compile. I don't use pointers that much.
Can anyone help?
Apparently you made an assumption that applicability of [] operator to something necessarily implies that that "something" is an array. This is not true. The built-in [] operator has no direct relation to arrays. The [] is just a shorthand for a combination of * and + operators: by definition a[b] means *(a + b), where one operand is required to be a pointer and another is required to be an integer.
Moreover, when you apply the [] operator to an actual array, that array gets implicitly converted to a pointer type first, and only then the resultant pointer can act as an operand of [] operator. This actually means the opposite of what you supposedly assumed initially: operator [] never works with arrays. By the time we get to the [] the array has already decayed to a pointer.
As a related side-note, this latter detail manifests itself in one obscure peculiarity of the first C language standard. In C89/90 the array-to-pointer conversion was not allowed for rvalue arrays, which also prevented the [] operator from working with such arrays
struct S { int a[10]; };
struct S foo(void) { struct S s = { 0 }; return s; }
int main()
{
foo().a[5];
/* ERROR: cannot convert array to pointer, and therefore cannot use [] */
return 0;
}
C99 expanded the applicability of that conversion thus making the above code valid.
It compiles according to §5.2.1/1 [expr.sub] of the C++ standard:
A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type. The result is of type “T”. The type “T” shall be a completely-defined object type.
The expression E1[E2] is identical (by definition) to *((E1)+(E2)), except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.
Since "example" has type char const[8] it may decay to char const* (it used to decay to char* as well, but it's mostly a relict of the past) which makes it a pointer.
At which point the expression myPtr[1] becomes *(myPtr + 1) which is well defined.
Pointers hold the address of memory location of variables of specific data types they are assigned to hold. As others have pointed out its counter-intuitive approach take a bit of learning curve to understand.
Note that the string "example" itself is immutable however, the compiler doesn't prevent the manipulation of the pointer variable, whose new value is changed to address of string 'x' (this is not same as the address of x in 'example'),
char* myPtr = "example";
myPtr[1] = 'x';
Since myPtr is referencing immutable data when the program runs it will crash, though it compiles without issues.
From C perspective, here, you are dereferencing a mutable variable.
By default in C, the char pointer is defined as mutable, unless specifically stated as immutable through keyword const, in which case the binding becomes inseparable and hence you cannot assign any other memory address to the pointer variable after defining it.
Lets say your code looked like this,
const char *ptr ="example";
ptr[1] = 'x';
Now the compilation will fail and you cannot modify the value as this pointer variable is immutable.
You should use char pointer only to access the individual character in a string of characters.
If you want to do string manipulations then I suggest you declare an int to store each character's ASCII values from the standard input output like mentioned here,
#include<stdio.h>
int main()
{
int countBlank=0,countTab=0,countNewLine=0,c;
while((c=getchar())!=EOF)
{
if(c==' ')
++countBlank;
else if(c=='\t')
++countTab;
else if(c=='\n')
++countNewLine;
putchar(c);
}
printf("Blanks = %d\nTabs = %d\nNew Lines = %d",countBlank,countTab,countNewLine);
}
See how the integer takes ASCII values in order to get and print individual characters using getchar() and putchar().
A special thanks to Keith Thompson here learnt some useful things today.
The most important thing to remember is this:
Arrays are not pointers.
But there are several language rules in both C and C++ that can make it seem as if they're the same thing. There are contexts in which an expression of array type or an expression of pointer type is legal. In those contexts, the expression of array type is implicitly converted to yield a pointer to the array's initial element.
char an_array[] = "hello";
const char *a_pointer = "goodbye";
an_array is an array object, of type char[6]. The string literal "hello" is used to initialize it.
a_pointer is a pointer object, of type const char*. You need the const because the string literal used to initialize it is read-only.
When an expression of array type (usually the name of an array object) appears in an expression, it is usually implicitly converted to a pointer to its initial (0th) element. So, for example, we can write:
char *ptr = an_array;
an_array is an array expression; it's implicitly converted to a char* pointer. The above is exactly equivalent to:
char *ptr = &(an_array[0]); // parentheses just for emphasis
There are 3 contexts in which an array expression is not converted to a pointer value:
When it's the operand of the sizeof operator. sizeof an_array yields the size of the array, not the size of a pointer.
When it's the operand of the unary & operator. &an_array yields the address of the entire array object, not the address of some (nonexistent) char* pointer object. It's of type "pointer to array of 6 chars", or char (*)[6].
When it's a string literal used as an initializer for an array object. In the example above:
char an_array[] = "hello";
the contents of the string literal "hello" are copied into an_array; it doesn't decay to a pointer.
Finally, there's one more language rule that can make it seem as if arrays were "really" pointer: a parameter defined with an array type is adjusted so that it's really of pointer type. You can define a function like:
void func(char param[10]);
and it really means:
void func(char *param);
The 10 is silently ignored.
The [] indexing operator requires two operands, a pointer and an integer. The pointer must point to an element of an array object. (A standalone object is treated as a 1-element array.) The expression
arr[i]
is by definition equivalent to
*(arr + i)
Adding an integer to a pointer value yields a new pointer that's advanced i elements forward in the array.
Section 6 of the comp.lang.c FAQ has an excellent explanation of all this stuff. (It applies to C++ as well as to C; the two languages have very similar rules in this area.)
In C++, your code generates a warning during compile:
{
//char* myPtr = "example"; // ISO C++ forbids converting a string
// constant to ‘char*’ [-Wpedantic]
// instead you should use the following form
char myPtr[] = "example"; // a c-style null terminated string
// the myPtr symbol is also treated as a char*, and not a const char*
myPtr[1] = 'k'; // still works,
std::cout << myPtr << std::endl; // output is 'ekample'
}
On the other hand, std::string is much more flexible, and has many more features:
{
std::string myPtr = "example";
myPtr[1] = 'k'; // works the same
// then, to print the corresponding null terminated c-style string
std::cout << myPtr.c_str() << std::endl;
// ".c_str()" is useful to create input to system calls requiring
// null terminated c-style strings
}
The semantics of abc[x] is "Add x*sizeof(type)" to abc where abc is any memory pointer. Arrays variable behave like memory pointers and they just point to beginning of the memory location allocated to array.
Hence adding x to array or pointer variable both will point to memory which is same as variable pointing to + x*sizeof(type which array contains or pointer points to, e.g. in case of int pointers or int array it's 4)
Array variables are not same as pointer as said in comment by Keith as array declaration will create fix sized memory block and any arithmetic on that will use size of array not the element types in that array.
This question already has answers here:
C pointer to array/array of pointers disambiguation
(13 answers)
Closed 7 years ago.
I was programming a code in C++ when I accidentally put brackets to my pointer and my programs output changed.
Since I am new to programming I wanted to know the difference between these type of pointers:
int* A[n];
int (*A)[n];
int *(A[n]);
I have read in my textbook that arrays are also a type of pointers.
int* A[n];
A first and foremost is an array no matter what type the element is. After applying pointer *, we know A is an array of int pointers.
int (*A)[n];
By applying brackets, pointer * has higher precedence over array [] in this case. Then A is first and foremost a pointer no matter what it is pointing to. After applying array [], we know A is a pointer to an array of int.
int *(A[n]);
Brackets won't change any precedence order that would affect the array [], therefore removing brackets would yeild int* A[n] same as your 1st case.
Are array pointers?
No. Array is a datastructure that allocates memory pool and stores the data sequentially where as Pointer points to a particular index in memory pool and references the data stored at that memory location.
This article contains good examples in reading type declarations in C.
http://www.unixwiz.net/techtips/reading-cdecl.html
Basically, you can read out types according to the following precedence:
(Often parenthesized) Inner-most type
Right-most types (Mostly array types: [])
Left-most types, except the outer-most one (Mostly pointer types: *)
Outer-most types (Mostly primitive types: int, char..)
For example, the types you presented can be read out as follows:
int* A[n]; // An array ([n]) of pointer (*) of int.
int (*A)[n]; // A pointer (*) of array ([n]) of int.
int *(A[n]); // An array ([n]) of pointer (*) of int.
So basically, the first and third type are identical.
I, very occasionally, make use of multidimensional arrays, and got curious what the standard says (C11 and/or C++11) about the behavior of indexing with less "dimensions" than the one declared for the array.
Given:
int a[2][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
Does the standard says what type a[1] is, or a[0][1], is it legal, and whether it should properly index sub-arrays as expected?
auto& b = a[1];
std::cout << b[1][1];
m[1] is just of type int[2][2]. Likewise m[0][1] is just int[2]. And yes, indexing as sub-arrays works the way you think it does.
Does the standard define the type for a[i] where a is T [M][N]?
Of course. The standard basically defines the types of all expressions, and if it does not, it would be a defect report. But I guess you are more interested on what that type might be...
While the standard may not explicitly mention your case, the rules are stated and are simple, given an array a of N elements of type T, the expression a[0] is an lvalue expression of type T. In the variable declaration int a[2][2] the type of a is array of 2 elements of type array of two elements of type int, which applying the rule above means that a[0] is lvalue to an array of 2 elements, or as you would have to type it in a program: int (&)[2]. Adding extra dimensions does not affect the mechanism.
I think this example in C11 explained it implicitly.
C11 6.5.2.1 Array subscripting
EXAMPLE Consider the array object defined by the declaration int x[3][5]; Here x is a 3 × 5 array of ints; more precisely, x is an array of three element objects, each of which is an array of five ints. In the expression x[i], which is equivalent to (*((x) + (i))), x is first converted to a pointer to the initial array of five ints. Then i is adjusted according to the type of x, which conceptually entails multiplying i by the size of the object to which the pointer points, namely an array of five int objects. The results are added and indirection is applied to yield an array of five ints. When used in the expression x[i][j], that array is in turn converted to a pointer to the first of the ints, so x[i][j] yields an int.
The similar is in C++11 8.3.4 Arrays
Example: consider
int x[3][5];
Here x is a 3 × 5 array of integers. When x appears in an expression, it is converted to a pointer to (the first of three) five-membered arrays of integers. In the expression x[i] which is equivalent to *(x + i), x is first converted to a pointer as described; then x + i is converted to the type of x, which involves multiplying i by the length of the object to which the pointer points, namely five integer objects. The results are added
and indirection applied to yield an array (of five integers), which in turn is converted to a pointer to the first of the integers. If there is another subscript the same argument applies again; this time the result is an integer. —end example ] —end note ]
The key point to remember is that, in both C and C++, a multidimensional array is simply an array of arrays (so a 3-dimensional array is an array of arrays of arrays). All the syntax and semantics of multidimensional arrays follow from that (and from the other rules of the language, of course).
So given an object definition:
int m[2][2][2];
m is an object of type int[2][2][2] (an array of two arrays, each of which consists of two elements, each of which consists of two elements, each of which is an array of two ints).
When you write m[1][1][1], you're already evaluating m, m[1] and m[1][1].
The expression m is an lvalue referring to an array object of type int[2][2][2].
In m[1], the array expression m is implicitly converted to ("decays" to) a pointer to the array's first element. This pointer is of type int(*)[2][2], a pointer to a two-element array of two-element arrays of int. m[1] is by definition equivalent to *(m+1); the +1 advances m by one element and dereferences the resulting pointer value. So m[1] refers to an object of type int[2][2] (an array of two arrays, each of which consists of two int elements).
(The array indexing operator [] is defined to operate on a pointer, not an array. In a common case like arr[42], the pointer happens to be the result of an implicit array-to-pointer conversion.)
We repeat the process for m[1][1], giving us a pointer to an array of two ints (of type int(*)[2]).
Finally, m[1][1][1] takes the result of evaluating m[1][1] and repeats the process yet again, giving us an lvalue referring to an object of type int. And that's how multidimensional arrays work.
Just to add to the frivolity, an expression like foo[index1][index2][index3] can work directly with pointers as well as with arrays. That means you can construct something that works (almost) like a true multidimensional array using pointers and allocations of arbitrary size. This gives you the possibility of having "ragged" arrays with different numbers of elements in each row, or even rows and elements that are missing. But then it's up to you to manage the allocation and deallocation for each row, or even for each element.
Recommended reading: Section 6 of the comp.lang.c FAQ.
A side note: There are languages where multidimensional arrays are not arrays of arrays. In Ada, for example (which uses parentheses rather than square brackets for array indexing), you can have an array of arrays, indexed like arr(i)(j), or you can have a two-dimensional array, indexed like arr(i, j). C is different; C doesn't have direct built-in support for multidimensional arrays, but it gives you the tools to build them yourself.
I read a question earlier that was closed due to being an exact duplicate of this
When a function has a specific-size array parameter, why is it replaced with a pointer?
and
How to find the 'sizeof' (a pointer pointing to an array)?
but after reading this I am still confused by how sizeof() works. I understand that passing an array as an argument to a function such as
void foo(int a[5])
will result in the array argument decaying to a pointer. What I did not find in the above 2 question links was a clear answer as to why it is that the sizeof() function itself is exempt from (or at least seemingly exempt from) this pointer decay behaviour. If sizeof() behaved like any other function then
int a[5] = {1,2,3,4,5};
cout << sizeof(a) << endl;
then the above should output 4 instead of 20. Have I missed something obvious as this seems to be a contradiction of the decay to pointer behaviour??? Sorry for bringing this up again but I really am having a hard time of understanding why this happens despite having happily used the function for years without really thinking about it.
Because the standard says so (emphasis mine):
(C99, 6.3.2.1p3) "Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue."
Note that for C++, the standard explicitly says the size is the size of the array:
(C++11, 5.3.3p2 sizeof) "[...] When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n
elements is n times the size of an element."
sizeof is an operator, not a function. It's a specific one at that, too. The parentheses aren't even necessary if it's an expression:
int a;
sizeof (int); //needed because `int` is a type
sizeof a; //optional because `a` is an expression
sizeof (a); //^ also works
As you can see, it's on this chart of precedence as well. It's also one of the non-overloadable operators.