The discussion revolves around understanding pointers in C programming, specifically the validity of various pointer expressions involving integer pointers and integer variables. Participants are exploring the nuances of pointer arithmetic and memory addressing.
Participants are analyzing specific expressions involving pointer arithmetic, questioning the validity of adding pointers and the implications of incrementing pointers. There is also discussion about the understanding of pointers as variables that hold memory addresses.
Discussion Status
Some participants have provided clarifications and examples to illustrate their points, while others are seeking further understanding of pointer behavior in C. There is an ongoing exploration of concepts without a clear consensus on all aspects discussed.
Contextual Notes
Participants are addressing potential misconceptions about pointers and their operations, including the implications of pointer addition and subtraction. There is an emphasis on understanding the size of data types and how it affects pointer arithmetic.
I have run into a little bit of confusion working with pointers and I am trying to figure out which of the expressions below from my assignment are valid. My definition of a pointer is that it is a variable that contains a memory address, so I get confused about whether I am modifying a location or the value stored at the location. Could someone please look at my responses to the assignment below and straighten me out? Thanks!
Given that pi and pj are pointers to int, and ii and ij are ints, which of the following expressions are valid?
a) pi + ii I think this is valid. But I am not sure if the address that pi points to is getting the int added to it or the value at the address.
b) pi + pj I think this might be invalid. I don't think you can add a pointer to a pointer.
c) pi++ I think this is valid. pi points to a machine address, if pi isincremented by one, pi will point to one unit past that machine address.
a) is valid. You're essentially incrementing the pointer by ii memory spaces. If it pointed at location 0x100 before, and ii were 0x10, it now points at location 0x110.
b) is not valid, as you suspect. The resulting pointer might well lie outside the memory space of the computer.
c) is valid for the same reason as a. Keep in mind that pi++ is literally just a syntactic shortcut for pi = pi + 1, and is equivalent to it in every way.
Thanks, Warren. I guess I need to create some little programs and practice working with pointers to understand them better.
#4
faust9
690
2
First off, do you understand this?
Code:
int *pInteger, someVariable;
pInteger = &someVariable;
*pInteger=32;
The above indirectly relates to your questions because you have to truly understand what a pointer is and does.
I'm going to move on, but if you don't understand the above say so and all will be explained.
You are correct in saying that a pointer is a variable but sying that alone means that you understand what a variable is--which most people have a misconception here. A variable is not simply a container for data but rather a container for a specific type of data which by definition occupies a set amount of memory depending on the type of data. I know what I said was wordy so I'll simplify if I can. Most people have multiple cups in their cupboards. Measuring cups, coffee cups, drinking glasses, wine glasses, etc. Each cup was designed for a different purpose and to hold a different amount of liquid. Most coffee cups hold about the same amount of liquid(there are a few general sizes though small, mediau, large, and coffee addict size). Most measuring cups measure the same volume of liquid as do most wine glasses. What I'm getting at is that each cup holds a certain amount of data which is dictated by its intended use. When you ask for a cup of coffee you know what to expect. When you go to McDonalds, or Wendys you know to expect a 24oz medium(or something like that).
Variables in c are like cups because the compiler knows how much memory each data type occupies.
a) You are correct. When you add an integer to a pointer (not a pointer reference mind you) then the compiler knows to jump to the next block of memory, and not the next memory location.
example (using above code}:
lets say someVariambe resides at memory location 32000 (decimal)
if we say
pInteger+1;
the compiler doesn't assign 32001 to pInteger rather the compiler assigns 32004 because integers occupy 32 bits (4 bytes).
To recap, you are correct in thinking that adding an integer to a pointer is a valid operation.
b) Again here you are correct. adding a pointer to a pointer yields no valid useful information. If we look to the above where pInteger is stored at 32000. If we said pInteger+=pInteger then pIntegre "would" equal 64000. What's stored at 64000? Who knows. That's why pointer + pointer is invalid because it would simply move the location of the pointer to some memory location.
Here's the crazy bit---You can subtract pointers! That's right subtraction is legal and provides important information when working with arrays. If you point to two elements within an array using two seperat pointers. Subtracting one pointer from another tells you how far apart the elements are from each other within the array.
It works like this: if a row of houses where sitting on 75 foot wide lots and each lot was numbered sequentially then knowing any two addresses on the street would allow you to find the distance between those houses and the number of houses between the houses.
c) You are correct because pInteger++ is the concise form of pIntegre = pInteger +1. We've already said that adding integers to pointers is valid thus so is this.
Well, hope this helped, good luck.
[edit] I see that while I was entering my long explanation that you were blessed with another more concise response.
faust9 brings a point I didn't wish to bring up, but it is important: when you work with pointers, adding 1 to them actually adds 1 * the size of the type of the pointer. As faust9 says, when you're working with int pointers (ints are 4 bytes long), adding 1 actually moves the pointer 4 bytes.
If you wanted to suppress this compiler convenience, you could cast your array to a void*. Adding one to a void pointer actually just adds one to the memory address. Normally the convenience is... convenient, however.
Yes, I actually was just replying to that comment faust9 made regarding that 4-byte increment for integers. My book doesn't illustrate this point well. That was very helpful, faust9. Thank you.
int *pInteger, someVariable;
pInteger = &someVariable;
*pInteger=32;
well... you tell me. This is how I interpret the lines:
first line: declares pInteger, a pointer to an int variable. Also declares an int variable called someVariable
second line: assigns the memory address of someVariable to pInteger
third line: changes the value at the address held by pInteger to 32 (so someVariable will now have the value 32)
faust9 said:
Variables in c are like cups because the compiler knows how much memory each data type occupies.
yes, I'm pretty clear on variables and data types.
faust9 said:
Here's the crazy bit---You can subtract pointers! That's right subtraction is legal and provides important information when working with arrays. If you point to two elements within an array using two seperat pointers. Subtracting one pointer from another tells you how far apart the elements are from each other within the array.
It works like this: if a row of houses where sitting on 75 foot wide lots and each lot was numbered sequentially then knowing any two addresses on the street would allow you to find the distance between those houses and the number of houses between the houses.
Then, referecing my previous examples, would this be a valid expression:
pi - pj
??
because I had assumed not before reading your post above!
faust9 said:
Well, hope this helped, good luck.
yes. Very much. Thank you.
#8
faust9
690
2
Math Is Hard said:
well... you tell me. This is how I interpret the lines:
first line: declares pInteger, a pointer to an int variable. Also declares an int variable called someVariable
second line: assigns the memory address of someVariable to pInteger
third line: changes the value at the address held by pInteger to 32 (so someVariable will now have the value 32)
Yep that's what's going on. I's not that tough once you get the hang of it but many people (I was just helping someone last night with this) get lost with * and &.
Then, referecing my previous examples, would this be a valid expression:
pi - pj
??
because I had assumed not before reading your post above!
Yep, subtraction is valid. Using pointer subtraction is fairly important when working with arrays especially when sorting the data stored within an array. Subtraction of pointers (when they point to elements within the same array) is used as a means of indexing elements of the array.
This makes things much clearer. Just one small point I am confused on, and I think it's the term "valid".
If I add two pointers together I will get information that I can't use for indexing, that's quite clear, but is it truly "invalid"? When I hear "invalid", it sounds like if I attempt such an operation I'll get hit with an error message or my compiler will holler at me or something...
thanks
It is physically possible, since pointers are just numbers, and you can add any two numbers you like. Your compiler may emit a warning or even an error, however, depending on how it is configured.
Thanks, chroot. I am curious to see what will happen if I try it now.
#12
faust9
690
2
I can't recall if pointer addition is specifically disallowed in the standard, but it seems to ring a bell as being so. Pointer addition could lead to some serious problems if allowed. Anywho, I use GCC 3 and I get an error "invalid operands to binary +" when I compiled the below program.
Code:
#include <stdio.h>
int main (int argc, const char * argv[])
{
//the following is a test of the validity of adding pointers.
int *pInteger, someVariable;
pInteger = &someVariable;
printf("Stored in pInteger: %d", pInteger);
pInteger+=pInteger; //is this "valid"?
printf("\nStored in pInteger += pInteger: %d", pInteger);
return 0;
}
I would just like to point out that this is also a compiler dependancy, although it will be true on most modern desktops. Don't be surprised when things don't work out when you're programming a Cray!
Adding one to a void pointer actually just adds one to the memory address.
I think this is also a compiler dependancy; I'm pretty sure I've had at least one compiler refuse to let me add to a void pointer.
Anyways, I'm pretty sure it is a requirement that the char type be exactly one byte, so you can use that if you like.
I tried to do the pointer addition and my compiler also balked. In fact it very specifically said that pointer addition wasn't allowed (I use Visual C++).
I also experimented a little with pointer subtraction:
#include <stdio.h>
int main (void)
{
int *pInteger,*pInteger2, someVariable, someVariable2, diff;
printf("Stored in pInteger: %d \n", pInteger);
printf("Stored in pInteger2: %d \n", pInteger2);
printf("The difference is %d \n",diff);
return 0;
}
I was suprised to get this result:
Stored in pInteger: 1245044
Stored in pInteger2: 1245040
The difference is 1
only because I thought that pInteger would have the value 1245040
and pInteger2 would have the value 1245044
p.s. I am looking for a tutor to help me through my last few chapters of this course. I am getting really bogged down and frustrated by some of this stuff and it's taking me hours and hours to finish the assignments. I am doing an online course so I don't have a lot of interaction with my teacher and I think I frequently misinterpret the book. If anyone is interested or knows a good C tutor, please PM me. thx.
I agree, chroot - you folks are THE BEST! I am so grateful for all the help I have gotten.
But I think I feel guilty about "over-posting" because I have so,so many questions. I just didn't want to become a nuisance.
I am just going to post this one back in the same thread since we're talking about arrays and pointers. I would like someone to check my work. I am not sure I implemented the instructions correctly where it asks me to use array notation and then pointer notation. Thanks for your help.
assignment: Write a program that initializes an array of double
and then copies the contents of the array into two other arrays.
(All three arrays should be declared in the main program.)
To make the first copy, use a function with array notation.
To make the second copy, use a function with pointer notation and
pointer incrementing. Have each function take as arguments, the name
of the target array, and the number of elements to be copied, that is,
the function calls would look like this given the following declarations:
Indenting will also put a blank line between what you indent and the rest, and you can't go around this. What you should be doing is placing your code in [ code ] [ / code ] tags or even better [ php ] [ / php ] tags. Those php tags will do the same as code tags, with the added benefits of colouring things like data types, comments, etc. It knows what's a comment, and colours it orange. Here's an example:
This is the code without any tags around it. Note that I've put spaces and indentation manually, but it won't show up:
int main (void) {
int x, y = 7;
x = 5;
for (int i = 0; i < x; i++) {
y += i; // this does some stuff
}
return 0; // this does other stuff
}
Now, using [ code ] tags:
Code:
int main (void) {
int x, y = 7;
x = 5;
for (int i = 0; i < x; i++) {
y += i; // this does some stuff
}
return 0; // this does other stuff
}
(Of course, you won't have the spaces when you write "[ code ]"). Now, with the [ php ] tags:
PHP:
int main (void) {
int x, y = 7;
x = 5;
for (int i = 0; i < x; i++) {
y += i; // this does some stuff
}
return 0; // this does other stuff
}
1) Just use the [ code ] tags for formatting. They preserve indentation.
2) Your copy_arr looks good. Your copy_ptr doesn't. You're using pointer notation on the right hand side of the assignment, but not on the left. Each time you go through the while loop, just increment both pointers.
Remember, with the php and code tags, you can indent manually. Look at my post. All three things were written the same. The stuff in normal text was written with spaces in front of the appropriate lines, they just don't show up. Put those in code or php tags and the spaces show up.