so I have:
char inBuf[80]
and then there's another line
inBuf+9
what does it mean when I add that +9 to the array's name?
It is same as referencing element number 9(0 based).
An equivalent notation would be:
&inBuf[9]
If you want to get the value, you could use *(inBuf+9)
This would point to the 10th element of the array. So for example:
*(inBuf + 9) = 10
would assign 10 to the 10th element.
Answer has been given already. I may only be repeating it.
This is called pointer arithmetic, because pointers are involved in the arithmetic operation. there are certain things only you can do with pointers. like you can add an integer to it, but you can subtract an integer only if pointer points to some array in the memory. also you can not subtract the pointers, because that may lead to some crucial memory location (for the OS).
addition in pointer arithmetic is special in a way that it takes care of the data type of the array elements, so when you say
char inBuf[80]
inBuf + 9
it advances 9 memory location sufficient enough to hold the 9 character (9*1 bytes typically)
int inBuf[80]
inBuf + 9
this will add 9 memory location sufficient enough to hold the 9 integers (9*4 bytes typically).
array and pointers are not always same, refer to "expert C programming" for that Also never use pointer arithmetic polymorphic-ally, refer "scott meyers book" for that
Using inBuf with no qualifier for an array index to use will be the same as seeing char *inBuf. inBuf + 9 would be the same as inBuf[9].
inBuf+9 means increasing the address of inBuf by 9.
inBuf refer the base address. but inBuf+ 9 locates the 10th element from the base address.
*(inBuf + 9) = 34;
This would assign the value 34 to the 10th element in the inBuf array.
When you perform addition with it, an array identifier such as your inBuf decays to a pointer to the first element in the array, and the number added is multiplied by the size of the array element (in this case char, which has size 1) to produce a new address.
So, inBuf + 9 is the address of the 10th element in the array, which could also be expressed as &inBuf[9]. You can use it as in:
*(inBuf + 9) = '\0'; // overwrite the 10th element in inBuf with a NUL
const char* p = strchr(inBuf + 9, ' '); // find space at or beyond 10th char
inBuf is like to write &inBuf[0].
So inBuf +9 means address of inBuf added with 9 chars length (&inBuf[9]).
Related
This question already has answers here:
Why does the indexing start with zero in 'C'?
(16 answers)
Closed 3 years ago.
Not really a code problem but a doubt, why do arrays on C and C++ start on 0? Does it have anything to do with some internal process?
int array[4]={1,2,3,4};
cout<<array[0];
cout<<array[1];
cout<<array[2];
cout<<array[3]; ///This prints 1234
But why that instead of
int array[4]={1,2,3,4};
cout<<array[1]; //as the first element
cout<<array[2];
cout<<array[3];
cout<<array[4];
?
Because the notation does pointer arithmetic. array[0] actually means the location of the array plus the size of 0 elements.
As always in C, you're working close to the hardware.
Consider int arr[i] elements.
arr[i] is interpreted as *(arr + i). Now, arr is the address of the array or address of the 0th index element of the array. So, address of next element in the array is arr + 1 (because elements in the array are stored in consecutive memory locations).
So if you do *(arr+0) it gives the starting memory location of the array.
and *(arr+1) gives next memory location. so this i i.e 0,1,..etc can use like offset.
As #ravnsgaard said in C, you're working close to the hardware.
I am bit confused after reading a text book. Consider a character array ar[10] in C++. In the text book it says that 10 bytes will be allocated for the array.
Starting from subscript ar[0], how many elements can I store in the given array? Is it 10? If yes can I store data at ar[10]? I want to know how many bytes will be allocated for the array in total since I came to know that every string ends with \0. Will overflow happen if I try to store a character into ar[10]?
If yes can I store data at ar[10]
No.
In your example, ar is an array with ten values. The first value is index #0, so you have ar[0] through ar[9], inclusively. That's the ten values in this array. Count them. Most of us conveniently have exactly ten fingers. Start counting on your fingers, starting with ar[0], and stop when you've used all your ten fingers. You'll stop on ar[9].
Attempting to access ar[10] is undefined behavior.
It will store 10 items in total, including the '\0'. So, 9 characters, and one '\0' null terminator at ar[9].
You can store ten values, from index 0 to index 9. This seems really wrong at first, but remember that 0 is technically a value and must be counted as one. It's sort of like how unsigned ints will hold 2^32 values, but the highest usable number is actually (2^32)-1.
Note that if you want to have the array be null-terminated you will only be able to store 9 characters, as ar[9] will hold '\0'. You could store another character there instead, but will have to write your code around the fact that your C-string is not null-terminated.
That all said, it's generally considered bad practice to use character arrays for strings in C++. It's a lot more error-prone than just using the string standard library.
More info: http://www.cplusplus.com/reference/string/string/
Hence, you have declared a[10] so it carries 10 values. As it is char array which contains string and string is terminated by '\0'. '\0' is also a value.
So if you string length is n then your array size will be n+1 to keep n length string. Otherwise, the overflow will occur.
Observe the following example
int main(){
char a[1], r, t;
printf("Size %d Byte\n", sizeof(a));
a[0] ='a';
a[1] ='b';
a[2] ='c';
printf("%c\n",r); //c
printf("%c\n",t); //b
}
As your array size is 1. Though you have not assigned value of r,t it is auto assigned by a[2] and a[1] respectively.
Here is the problem program:
#include <stdio.h>
int main()
{
int apricot[2][3][5];
int (*r)[5]=apricot[0];
int *t=apricot[0][0];
printf("%p\n%p\n%p\n%p\n",r,r+1,t,t+1);
}
The output of it is:
# ./a.out
0xbfa44000
0xbfa44014
0xbfa44000
0xbfa44004
I think t's dimension's value should be 5 because t is the last dimension,and the fact is matched(0xbfa44004-0xbfa44000+1=5)
But the r's dimension's value is 0xbfa44014-0xbfa44000+1=21,I think it should be 3*5=15,because 3 and 5 are the last two dimensions,then why the difference is 21?
r is a pointer to an array of 5 ints.
Assuming 1 int is 4 bytes on your system (from t and t+1), then "stepping" that pointer by 1 (r+1) means an increase in 5*4 = 20 bytes. Which is what you get here.
You get tricked by the C syntax. r is an array pointer to an array of int, t is a plain int pointer. When doing any kind of pointer arithmetic, you do it in the unit pointed at.
Thus t+1 means the address of t + the size of one pointed-at object. Since t points at int and int is 4 bytes on your system, you get an address 4 bytes from t.
The same rule applies to r. It is a pointer to an array of 5 int. When you do pointer arithmetic on it by r+1, you get the size of the pointed-at object, which has size 5*sizeof(int), which happens to be 20 bytes on your computer. So therefore r+1 gives you an address 20 bytes (==14 hex) from r.
I encountered the following line in a OpenGL tutorial and I wanna know what does the *(int*) mean and what is its value
if ( *(int*)&(header[0x1E])!=0 )
Let's take this a step at a time:
header[0x1E]
header must be an array of some kind, and here we are getting a reference to the 0x1Eth element in the array.
&(header[0x1E])
We take the address of that element.
(int*)&(header[0x1E])
We cast that address to a pointer-to-int.
*(int*)&(header[0x1E])
We dereference that pointer-to-int, yielding an int by interpreting the first sizeof(int) bytes of header, starting at offset 0x1E, as an int and gets the value it finds there.
if ( *(int*)&(header[0x1E])!=0 )
It compares that resulting value to 0 and if it isn't 0, executes whatever is in the body of the if statement.
Note that this is potentially very dangerous. Consider what would happen if header were declared as:
double header [0xFF];
...or as:
int header [5];
It's truly a terrible piece of code, but what it's doing is:
&(header[0x1E])
takes the address of the (0x1E + 1)th element of array header, let's call it addr:
(int *)addr
C-style cast this address into a pointer to an int, let's call this pointer p:
*p
dereferences this memory location as an int.
Assuming header is an array of bytes, and the original code has been tested only on intel, it's equivalent with:
header[0x1E] + header[0x1F] << 8 + header[0x20] << 16 + header[0x21] << 24;
However, besides the potential alignment issues the other posters mentioned, it has at least two more portability problems:
on a platform with 64 bit ints, it will make an int out of bytes 0x1E to 0x25 instead of the above; it will be also wrong on a platform with 16 bit ints, but I suppose those are too old to matter
on a big endian platform the number will be wrong, because the bytes will get reversed and it will end up as:
header[0x1E] << 24 + header[0x1F] << 16 + header[0x20] << 8 + header[0x21];
Also, if it's a bmp file header as rici assumed, the field is probably unsigned and the cast is done to a signed int. In this case it doesn't matter as it's being compared to zero, but in some other case it may.
In attempt to explain that arrays are just pointers (in C++) to our class, my professor showed us this:
array[5] // cout'ing this
*(array + 5) // would return the same value as this
I'm having a little trouble completely understanding it. Here's my thinking:
array is the address of the first location and so if we add 5 to that address, we move 5 addresses in memory. The pointer operator pulls the data from the memory location.
Is this the correct idea? The idea still feels foggy with me and just feel like I don't understand it completely. I think hearing someone else explain it might help me understand it more. Thanks in advance!
You've got the right idea.
Arrays implicitly cast to pointers. Interestingly, [] works on pointers, not arrays.
a[b] Subscript operator is defined as *(a + (b)). [] is used as syntactic sugar - it's much more pleasant to write array[5] instead of *(array + 5)
Pointer arithmetic with a pointer and an integer p + i increases the address at p by i * sizeof(*p) bytes.
char* p;
p + 5; // address increased by 5
int* p;
p + 5; // address increased by 20 as sizeof(*p) is 4
The * operator performs indirection. It will give you what the pointer is pointing to.
int x[2];
int* p = &x[0]; // could also be int* p = x;
*p = 5; // x[0] is now 5
*(p + 1) = 10; // x[1] is now 10
Your professor is correct that the two expressions will produce the same results. Your explanation of it leads me to believe you have a good grasp of the mechanics.
It is not quite correct to say an array is the same as a pointer. An array is very easily converted to a pointer, which leads to some confusion.
For example consider this code:
int array[5];
int * pointer = new int[5];
cout << sizeof(array); // outputs 5*sizeof(int), most probably 20
cout << sizeof(pointer); // outputs sizeof(int*), most probably 4 on a 32 bit OS
array[4] = 906;
pointer[4] = 906;
cout << *(array + 4) << *(pointer + 4); // outputs "906 906"
from memory arrays in c++ are sections of continuous memory the program. thats why you can go *(array + 5) as it is 5 from the front of the array.
Also keep in mind that arrays in C++ start # 0 so thus the 6th element in an array is array[5]
example
[0] [1] [2] [3] [4] [5] Array index
1 2 3 4 5 6 Item number
To access item 2 u would either
array[1]
*(array+1)
but please keep in mind array[index_number] is standard syntax for looking up an item in an array so make sure u use array[index_num] instead of *(array + index_num)
Yes, what your proffessor said is correct.
to explain it in detail
Consider your array,
int array[5]
here it takes 5 location in the memory say 0x00 0x04 0x08 0x0C and 0x10 0x14
Assuming integer takes 4 bytes, the locations are 4 bytes apart.
it this case 'array' represents the base address (pointer) to the array, that is 0x00. And the type of a would be int *. (since the type of the array elements is integer)
If you do array+1, it will be 0x04, since the increment of the pointer depends on the type of the pointer. If the pointer is integer, it will increment by 4 bytes. If the type of the integer is character, the pointer would increment by one bytes.
so if you do (array+5) it would point to the address 0x14 and
*(array+5)
returns the value of the location 0x14 which is the value at 5th location of array.
so in practical, array[5] is equal to *(array+5)
The compiler internally converts array[5] to *(array+5)
so even if we write 5[array], it will get converted it to *(5+array)
Though it seems strange, this is the reason why 5[array] works same as array[5]