The discussion centers on understanding pointers in C programming, particularly regarding their validity in various expressions. It clarifies that adding an integer to a pointer is valid, as it adjusts the pointer by the size of the data type it points to, while adding two pointers together is invalid and may lead to compiler errors. Subtracting pointers is valid and useful for determining the distance between elements in an array. The conversation also emphasizes the importance of grasping how pointers work, including the distinction between modifying memory addresses and the values stored at those addresses. Overall, the participants encourage practical experimentation with pointers to solidify understanding.
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.
oops! sorry- I think I got carried away with the formatting fun stuff! so, I should use ++ for "pointer incrementing"?
using + i won't move to the correct position in the array?
Remember the three qualities of a good programmer:
1) Laziness. No one should have to do much work, so a good programmer should strive to make the user's life utterly push-button easy.
2) Impatience. No one should ever have to wait for a computer to do anything, so programmers should be careful with their algorithm designs to make sure their users never have to wait for anything.
3) Hubris. Programmers should take excessive pride in their work, and should strive to make every program they write complete, totally functional, and elegant.
The PHP tags are really an example of some programmer on the vBulletin team demonstrating quality number one.
oops! sorry- I think I got carried away with the formatting fun stuff! so, I should use ++ for "pointer incrementing"?
using + i won't move to the correct position in the array?
Your code using pointer arithmetic (the + signs) will certainly work, but it might not be the best way to meet the specification. The specification said to use pointer incrementing. Normally, I associate the ++ operator with the word "incrementing," but it may just be a semantic issue.
Remember the three qualities of a good programmer:
1) Laziness. No one should have to do much work, so a good programmer should strive to make the user's life utterly push-button easy.
2) Impatience. No one should ever have to wait for a computer to do anything, so programmers should be careful with their algorithm designs to make sure their users never have to wait for anything.
3) Hubris. Programmers should take excessive pride in their work, and should strive to make every program they write complete, totally functional, and elegant.
Wow - who knew?? I promise to try my best to acquire these ..uh.. virtues!
Remember the three qualities of a good programmer:
1) Laziness. No one should have to do much work, so a good programmer should strive to make the user's life utterly push-button easy.
2) Impatience. No one should ever have to wait for a computer to do anything, so programmers should be careful with their algorithm designs to make sure their users never have to wait for anything.
3) Hubris. Programmers should take excessive pride in their work, and should strive to make every program they write complete, totally functional, and elegant.
The PHP tags are really an example of some programmer on the vBulletin team demonstrating quality number one.
- Warren
You forgot 4)
4) Once you land a job as a programmer learn to obfuscate as much as possible so that you are the only programmer able to maintain certain chuncks of code thus ensuring job security.
4) Once you land a job as a programmer learn to obfuscate as much as possible so that you are the only programmer able to maintain certain chuncks of code thus ensuring job security.
OMG! I had a job once where ALL the programmers lived religiously by that guideline. Not even the tiniest cryptic comment was ever written. My job? To go around to the programmers and produce documentation on what they were coding. Since they all refused to document or comment my boss thought I should be the one to do it. He wanted to farm out some of the work overseas so he wanted to create a guidebook for these contracted developers who would write new modules of the app.
It was horrible. The programmers were really protective and defensive about showing anyone their code or explaining to anyone what it did.
And what a mess. By the time I came to work their the application was three fourths done and there was no formal spec - just shoe boxes full of meeting notes and emails from the client.