|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
Prillan, your last question. No it's just my lack of understanding.
Current C project I am having to do right now is most confusing one yet.
Boiled down it's essentially it's manipulating a structure that holds an array of linked lists of another structure. Which probably sounds easy to most of you but it is hell for me 
edit, question:
accessing field of struct pointer, you can do
(*struct).field
or
struct->field
accessing field of struct double pointer
(**struct).field
or
(*struct)->field
or
??
how do I do it with just the arrows?
|
With just the arrows would it not be ((struct)->field)->field? It should just be the same thing each time.
|
No. It's a pointer to a pointer to an element that has a member called field.
|
That. You can't. Pointers have no fields to dereference with an -> So you'll need to dereference the first pointer with a *
|
For the first time in this class, I don't think I can actually figure out this function on my own. Is anyone willing to get on skype with me to help me figure it out? It's C.
|
On April 02 2017 05:04 Acrofales wrote: That. You can't. Pointers have no fields to dereference with an -> So you'll need to dereference the first pointer with a * So, to make sure, the correct way is:
(*(struct)->field)->field
or do I need to toss another pair of brackets in like
(*((struct)->field))->field
and this could all just be avoided by
(struct->field).field
|
On April 02 2017 00:09 travis wrote:Prillan, your last question. No it's just my lack of understanding. Current C project I am having to do right now is most confusing one yet. Boiled down it's essentially it's manipulating a structure that holds an array of linked lists of another structure. Which probably sounds easy to most of you but it is hell for me  edit, question: accessing field of struct pointer, you can do (*struct).field
or
struct->field
accessing field of struct double pointer (**struct).field
or
(*struct)->field
or
??
how do I do it with just the arrows?
If you have typedef struct clazz { type field; } clazz_t;
int main() { clazz_t** var;
// all at once, brackets are important (*var)->field;
// equivalently (*(*var)).field;
// conceptually it helps to use an intermediate variable, dereferencing the 'outer' pointer clazz_t* inter = *var;
// you learned this as a short-hand inter->field;
// equivalent to this (*inter).field; }
|
On April 03 2017 00:33 WarSame wrote:Show nested quote +On April 02 2017 05:04 Acrofales wrote: That. You can't. Pointers have no fields to dereference with an -> So you'll need to dereference the first pointer with a * So, to make sure, the correct way is: (*(struct)->field)->field or do I need to toss another pair of brackets in like (*((struct)->field))->field and this could all just be avoided by (struct->field).field No. To all of that. In fact, I'm not even quite sure what those are supposed to be.
Lets start with getting some things out of the way. struct is a terrible terrible terrible name for a variable, so can we please stop calling the variable that? Lets call it foo instead.
foo is a pointer to a pointer to a struct. In other words, a double pointer to a struct. Lets call that struct bar.
so we have
bar** foo;
Now lets unpack that a bit.
Does something of the type bar* have any fields? Of course not. It's a pointer. So foo->myfield will break, because it is simply shorthand for (*foo).myfield, and *foo has type bar*.
So at some point you'll actually have to dereference foo. Because you can write, equivalently:
mytype myvar = (*foo)->myfield; mytype myvar = (**foo).myfield;
E: ninja'd
|
so I have a double pointer
and I want to do:
(double pointer + 1) = another pointer
but I can't do this... "lvalue required as left operand of assignment"
so wtf do I do
I understand that I could assign a NEW pointer to (double pointer + 1), but this new pointer would be a local variable which would go away when my function is over.
I guess i have to like, assign the value instead of directly assigning pointers? I hate pointers
|
(double pointer + 1) = another pointer
This doesn't mean anything. You can't assign "double pointers" to regular pointers.
*(double pointer + 1) = another pointer // set the value at double pointer[1] to another pointer
You're overcomplicating this for yourself. If you're feeling frustrated with coding problems, I would suggest taking a break and doing other non-academic activities if you haven't already. It helps a bunch.
Break apart what you want to do into steps and figure out those steps. Avoid shortening code like above. Write out each line.
A variable with type "double pointer" can mean two things: an array of pointers (which can also be arrays) or a pointer to a pointer. Since it doesn't make sense to +1 a pointer to a pointer, I'm assuming you have an array of pointers.
clazz_t** arr = ...; clazz_t** iter = arr; // get a pointer to the first array element, iter variable to avoid modifying original iter = iter + 1; // move the pointer to the second array element (next index in the array)
clazz_t* ele = *iter; // get the second element in the array *ele = <new_value>; // change the value of the second array element
*iter = <new_element>; // change the second array element to another pointer (different than above)
I understand that I could assign a NEW pointer to (double pointer + 1), but this new pointer would be a local variable which would go away when my function is over.
I guess i have to like, assign the value instead of directly assigning pointers? I hate pointers
You're misunderstanding how pointers and scope works.
void func(int** ptr) { *ptr = 4; }
int main() { int* a = nullptr; func(&a); // a is now 4 }
Do you understand why a is 4?
void func(int** ptr) { ptr = 4; }
int main() { int* a = nullptr; func(&a); // a is still 0 }
Do you understand the difference between the 1st and 2nd example?
|
On April 03 2017 00:54 Blisse wrote:Show nested quote +On April 02 2017 00:09 travis wrote:Prillan, your last question. No it's just my lack of understanding. Current C project I am having to do right now is most confusing one yet. Boiled down it's essentially it's manipulating a structure that holds an array of linked lists of another structure. Which probably sounds easy to most of you but it is hell for me  edit, question: accessing field of struct pointer, you can do (*struct).field
or
struct->field
accessing field of struct double pointer (**struct).field
or
(*struct)->field
or
??
how do I do it with just the arrows?
If you have typedef struct clazz { type field; } clazz_t;
int main() { clazz_t** var;
// all at once, brackets are important (*var)->field;
// equivalently (*(*var)).field;
// conceptually it helps to use an intermediate variable, dereferencing the 'outer' pointer clazz_t* inter = *var;
// you learned this as a short-hand inter->field;
// equivalent to this (*inter).field; }
Ok, I see what I was doing wrong.
I was thinking more along the lines of #include <iostream>
using namespace std;
struct Y { int F; };
struct X { Y* pY; };
int main(int argc, char** argv) { Y y; y.F = 5; Y * pY = &y; X x; x.pY = pY; X * pX = &x; cout << (pX->pY)->F; return 0; }
All of this pointer practice is pretty useful, so thanks for the questions Travis. You're getting me to look more into this, and be more careful.
|
I seriously need help  my brain is dying, you guys wouldn't believe how long I have been working on one function
I am supposed to sort an array of lists of structures based on a comparing function and for some reason, clearly my lack of understanding of pointers, the changes are not sticking
they stick when I put them in order
new = malloc(whatever) //assign some stuff to new curr->next = new;
Then it effects the original array(double pointer) I was passed.
But when I have to put it in some other kind of order, say
new = malloc(whatever) //assign stuff to new new->next = curr; curr = new;
this DOES NOT stick
And I don't understand why. I am actually going crazy.
|
Take a step back and think about how pointers work when you're making calls to functions.
so you've got some block of memory that is referenced by the current pointer. When you pass this pointer to a function what happens?
void travis(int * a1) { *a1 = 6; a1 = void; }
int main() { int *curr = 1; travis(curr); }
So here's the stack. We've got a reference to curr which is some piece of memory.
[curr] 1
Then I call my travis function and this happens...
[curr] <---------- [a1] 1
a1 is a reference to the location in memory that is the curr pointer that has a value of 1. The first thing the function does is deference that pointer and set the value to 6. Because we're dereferencing the pointer this change in state will outlive the function.
[curr] <----------- [a1] 6
Next we're going to set the a1 pointer to void. This doesn't change where curr points. It only effects the pointer in the local scope because we're not dereferencing the pointer.
[curr] [a1] -> void 6
When the function ends we end up with
[curr] 6
Your bottom block is doing the void thing assuming that you're passing curr. If none of this makes sense I suggest reading up on pass by value/reference and what happens when you make a function call in terms of the stack.
|
On April 03 2017 06:29 travis wrote:I seriously need help  my brain is dying, you guys wouldn't believe how long I have been working on one function ... I am actually going crazy.
Avoid pointers if you don't understand them. There are only a few common usages:
1. arrays. Instead of writing arr, arr+1, ..., refer to their elements and take their address. &a[0], &a[1], etc. And don't use pointer arithmetic, no p++, no p+i, etc. Keep these for later when you are more comfortable with pointers. 2. passing parameters 'out'.
void f(int a); // modifications to 'a' inside f do not affect the caller
void f(int* a) { int x = *a; //read to local var ... // do stuff - no pointers in here *a = x; // update caller }
3. structs. Everything is a value type in C, including structs. You can do
void f(struct S s) { ... }
The structure is copied on the stack and given to f (same logic as any value). It may be expensive to do so if S is large. Instead using (2), you can pass a pointer to S. However, assigning to a local variable could be an issue (if S is large). Therefore, the -> shortcut was created. a->x is the same as (*a).x
+ Show Spoiler + Modern compiler will probably eliminate the temporary variable though.
That's why there is no special shortcut for (**pp).x. There is no penalty in doing p = *pp; p->x
but there used to be a performance penalty for doing a = *p a.x vs p->x
4. trees and complex data structures. Use typedefs and they reduce to one of the above cases.
Though you should not skip on getting a good understanding of value, memory location, variable, address, pointers and reference , specially if you intend to have a career in C.
It will only get harder and you'll end up with memory corruptions, leaks, etc.
|
professor says not to use goto
but I have a while loop inside of a for loop and when my while loop hits it's condition I want to end the for loop
I could make some stupid boolean but that seems clunky and goto(outside the for loop) seems really elegant what's the problem?
|
On April 04 2017 02:03 travis wrote: professor says not to use goto
but I have a while loop inside of a for loop and when my while loop hits it's condition I want to end the for loop
I could make some stupid boolean but that seems clunky and goto(outside the for loop) seems really elegant what's the problem? There are many ways of doing this without using goto, most rely on refactoring your code so your outer loop exits naturally when your condition is met, or so that you can return immediately. Flags are the next option (as you say, it's clunky) and goto is the nuclear option. The problem with goto is not that it is not elegant in some specific cases, it's that it breaks the control flow of your program.
Imagine this:
void* dosomething() { blablabla foo: bla blablabla }
void* dosomethingelse() { blabla if(condition) { goto foo; } blabla }
This is the kind of goto that will cause your code to break in unexpected and mysterious ways. And if you start getting used to using goto in nested for loops, you might get tempted to use goto in other cases too where you "just want to avoid repeating code".
But yes, nested loops is one of the very very few (if not only) places where goto is a good solution. But if your professor has forbidden it, then either find a way to refactor your code or use a flag.
Oh, and also note that some more modern languages have numeric or labeled breaks. E.g. in java and javascript if you use a labeled break to break out of the outer loop:
loop1: for(somestuff) { while(true) { break loop1; } }
PHP has numeric breaks (in other words, "break 2;" would break out of 2 loops (or a switch statement and a loop)).
Python doesn't have anything like it, because in the words of the Python god: https://mail.python.org/pipermail/python-3000/2007-July/008663.html which I mostly agree with. There are almost always perfectly good alternatives that don't require you break out of a nested loop.
|
hmmm, so, using return
then i suppose a good solution is to put the loops into a function and then return the function though that could be a bit annoying in C if you are changing a bunch of local variables, because you have to use a bunch of pointers in your parameters
|
On April 04 2017 02:55 travis wrote: hmmm, so, using return
then i suppose a good solution is to put the loops into a function and then return the function though that could be a bit annoying in C if you are changing a bunch of local variables, because you have to use a bunch of pointers in your parameters Correct. That's one way of doing it.
|
Hyrule18974 Posts
You could also use break 2; in the while
|
On April 04 2017 03:23 tofucake wrote: You could also use break 2; in the while Downvote. Can't in C.
|
|
|
|