|
Twiggy Johnson posted:My google-fu is failing me for this one:
|
# ? Nov 16, 2011 22:38 |
|
|
# ? Jun 8, 2024 08:07 |
|
In c wouldn't the struct need to be extern? edit: Nevermind. Wasn't reading closely. RichardA fucked around with this message at 23:57 on Nov 16, 2011 |
# ? Nov 16, 2011 23:53 |
|
Basic programming questions: I'm trying to write a function (12 months of the year) that takes an enumeration constant and returns the next month in the year, and a second function that takes an enumeration constant and an int and increments the months by the int (figure it'd just use the function to get the next month int number of times) and returns the new month. How do I get it to wrap around back to January? I have a function already that accepts an enumeration constant and prints the month that it corresponds to. --- Also, with the same months, if I'm writing an application to compare two months and tell which is later in the year (user inputs two months, if the same nothing happens, if one is later in the year it says so, and january > december), what's the most efficient way to do the comparisons? A massive if/else or switch statement seems clumsy. Thank you!
|
# ? Nov 17, 2011 00:47 |
|
The modulus operator is good for both of these tasks, and would mean you don't need to call your "add one month" function a bunch of times. The percent sign is what you use for a modulus. To convert to months, you'd use it like n%12 - zero would be January, 11 would be December, you should probably force the enumerated constants into being that sequence of numbers. (12%12 would loop back to zero, as would 24%12.) If you can't rely on the enumerated values being sequential then you'd be stuck with a lot of if/else or a switch - the only thing you could do to keep from a hundred "add one month" calls then would be that you could mod-12 the number of months you need to add before you start. It sounds like you haven't got a very well defined criterion for "later in the year" if January>December (Is June>December? July?). You need to decide on the logic before you worry about the programming. roomforthetuna fucked around with this message at 01:06 on Nov 17, 2011 |
# ? Nov 17, 2011 01:03 |
|
Thank you, the modulus operator is what I needed for the first part. I had only used it to find only even or odd numbers before, didn't think to use it like this. Any input on the second question?
|
# ? Nov 17, 2011 01:16 |
|
It's a straightforward numerical comparison unless the month is December.
|
# ? Nov 17, 2011 01:22 |
|
http://codepad.org/6FjaPoJd Completely butchering this, I know. How would I apply the modulus operator and/or un**** this code?
|
# ? Nov 17, 2011 03:25 |
|
Damiscus posted:http://codepad.org/6FjaPoJd You can fix the code by understanding that enums are implicitly cast to ints. So the next day function could be code:
code:
|
# ? Nov 17, 2011 03:36 |
^^ I knew someone would write a shorter answer first Damiscus posted:http://codepad.org/6FjaPoJd First, that code can't work as it is, there are a few problems, mainly in many_days(). You never initialize the currentday variable before you pass it into next_day(), and you never feed the value returned from next_day() back into the loop, it just gets discarded after every loop. The result is that you continually take the next day of the same uninitialized value. You also declare the argument of the function as d_t although it can clearly be values outside the enumeration, from how the function is used. A better way to design the many_days() function would be to have it take two parameters: a d_t telling the current day of the week, and an int telling how many days to travel, then return a d_t telling the new day of the week. It may not have been covered (yet) in your classes or book, or whatever you are learning from, but in C, you can also explicitly declare the integral values of names in an enum, like this: code:
code:
|
|
# ? Nov 17, 2011 03:47 |
|
I've been programming in C# for a while now. Not professionally (well, it gets used for automation tasks, but I'm not a developer). That said, I've been meaning to dive into C++ a bit to expand horizons / understand more / work with some lower level stuff. 1) Is there a good C++ primer for people who understand OOP and general programming concepts? (specifically .net, but whatever) 2) Is there a good moderate (one to two days) sized project someone can recommend as a good introductory thing to C++? 3) Is it just me, or does intellisense for C++ suck in VS2010, coming from C#? God drat. I mean, it's there, but drat. Walked fucked around with this message at 15:20 on Nov 17, 2011 |
# ? Nov 17, 2011 14:41 |
|
Walked posted:3) Is it just me, or does intellisense for C++ suck in VS2010, coming from C#? God drat. I mean, it's there, but drat.
|
# ? Nov 17, 2011 15:30 |
|
roomforthetuna posted:How did you try accessing it? The three-dimensional declaration should be fine if you access it in the same manner. (eg. pltstore[0][0][0]=0.0f;) Unless the fortran array is not the same size. Whoops, turns out the segmentation fault was being caused by something else. The 3D indexing was working as expected. Thanks.
|
# ? Nov 17, 2011 15:53 |
|
Plorkyeran posted:It's terrible compared to C#. Visual Assist X makes it significantly less bad. Sadly, intellesense is better in visual studio then similar features are in most other C++ IDEs.
|
# ? Nov 17, 2011 17:02 |
|
C++ question this time:code:
|
# ? Nov 18, 2011 03:17 |
|
The stats object you're working with is corrupted. It's probably a dangling pointer to an object from a vector that was resized or destroyed.
|
# ? Nov 18, 2011 04:06 |
rjmccall posted:The stats object you're working with is corrupted. It's probably a dangling pointer to an object from a vector that was resized or destroyed. This is likely. It's very risky to use pointers into vectors that change. Step through it with a debugger, preferably use a debugging memory allocator (that writes specific patterns to freshly allocated memory and others to deallocated memory) so you can easily tell what is being pointed to.
|
|
# ? Nov 18, 2011 04:14 |
|
The object's getting corrupted because I'm trying to write and read a struct with an embedded vector to a binary file. This is the second time I've learned that doesn't work.
|
# ? Nov 18, 2011 05:43 |
|
I've got a C question about Linked Lists. What does the "nested functions are disabled, use -fnested-functions to re-enable" error mean in C? I'm trying to return a copy of a linked list. The copy function should take in no arguments but return a copied list. It doesn't seem to like me setting the first variable to NULL when I create a new linked list to store the copied LL in. But I don't know how else to do it. Probably something to do with pointers. I'm not good with pointers. code:
|
# ? Nov 20, 2011 01:36 |
|
It means you are missing a brace somewhere and you are defining a function inside another function, which is an error in standard C.
|
# ? Nov 20, 2011 01:48 |
Super Ninja Fish posted:I've got a C question about Linked Lists. Super Ninja Fish posted:
I'm not sure how GCC actually decides you are trying to define a nested function here, but fact is that you're completely messing up variable declarations, initialisation and struct member access. (Nothing to do with linked lists per se.) First line there declares result as a pointer to a node struct, and initialises it to NULL. Then the second line declares a node... wait what no it tries to do member access in result what no, you can't do member access while declaring something, that doesn't make sense. Besides, you just initialised result to NULL so trying to dereference it and access any members would result in an access violation error at runtime. Tell me, when result points to nothing, when you assign something to result->first where did you intend it to be stored? I think the compiler might have thought you were defining a function because you named a type and then went on to do something more complex than declaring a variable of it.
|
|
# ? Nov 20, 2011 01:55 |
|
That makes sense, result shouldn't start as null, but I'm not sure what it should point to because I want it to be an empty list that didn't have any elements added yet.code:
set7.c:273: error: invalid initializer set7.c:274: error: nested functions are disabled, use -fnested-functions to re-enable set7.c:274: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘->’ token set7.c:274: error: expected expression before ‘->’ token To get the main link list started, all I had to do was type struct node *first = (struct node *) NULL; struct node *last = (struct node *) NULL; int size = 0; at the top of the program, right after I defined the node structure. I was just trying to duplicate that in copy. What's the right way to make a copy then? Edit: Nevermind, seems to work now with code:
some bust on that guy fucked around with this message at 03:53 on Nov 20, 2011 |
# ? Nov 20, 2011 03:19 |
|
Super Ninja Fish posted:
|
# ? Nov 20, 2011 04:03 |
Okay, I'm guessing at what you mean by the fields in your node structure here. element would be the data value. next would point to the next element in the list, or NULL if this is the last element. first and last would point to the first and last element in the list. This is bad. If you have every element in a linked list point to the first and last element in the list, you lose most of the advantages of using linked lists. One of the major advantages of linked lists is that you can insert new elements at either end or even in the middle without having to touch every element of the list. If you suddenly make every element carry "data structure global" data such as pointers to the start and end of the list, you suddenly need to update every element of the list whenever you add or remove elements from the start or end of the list. This is very bad. Because they add lots of unneeded (and undesirable) complexity, I'll remove the first and last fields of the node struct, simplifying it to: code:
code:
code:
How would a single element list look? It would have one ListNode allocated somewhere, and a struct ListNode * variable pointing to that memory. The ListNode would have a next pointer of NULL, because it's the last element in the list, and it would have its data member set to something. So how do you create such a list? You need to allocate the appropriate amount of memory and set up the pointers. code:
code:
code:
Now that we can create lists, let's do something. How about counting the number of elements? code:
code:
code:
type_of_variable variable_name [= initial_value]; The problem is that foo->next is not a variable name, it's an expression! It's an expression that says, "take the pointer at foo, dereference it, then access the field named next in the structure that was pointed to." You can't (and wouldn't need to) declare fields of a structure like that, you just access them. Consider this statement: code:
In this case, our lvalue is result->data, the field data in the structure pointed to by the result variable. The rvalue is simply the local variable named data. Note that the data field and the local variable data are not related at all, their names don't clash because the field's name lives inside the structure type declared. I hope this has been helpful. Edit: quote:
What you are doing here: You declare a pointer variable. Then you calculate the size of the node structure. Then you tell the compiler that this size of the structure is in fact a valid pointer to a node structure, which I can tell you it most likely is not. You then proceed to write to the memory pointed to by that bogus pointer, which will cause a crash by access violation (segmentation fault). nielsm fucked around with this message at 04:14 on Nov 20, 2011 |
|
# ? Nov 20, 2011 04:09 |
|
nielsm posted:I hope this has been helpful. Yeah, that helped out incredibly, thanks a lot for taking the time. I would have never figured that out on my own. I would have probably went on trying to do linked lists nodes with first and last forever. quote:
After 30 minutes of looking at this part and trying it out with just using result, I see that current_destination at the only refers to the last element while result still refers to the first. So I can tell if I have this straight, current_destination->next = create_node(current_source->data); The above changes both result and current_destination, due to "next" being a pointer, while the below changes only current_destination. current_destination = current_destination->next; Wow, I'm glad I came here and asked. I thought I knew what I was doing when it came to linked lists, but I didn't.
|
# ? Nov 20, 2011 11:00 |
Super Ninja Fish posted:Yeah, that helped out incredibly, thanks a lot for taking the time. I would have never figured that out on my own. I would have probably went on trying to do linked lists nodes with first and last forever. It would, however, make sense to have a "master" structure that represents the list as a whole, and that structure then refers to the first and last elements, and whenever you want to manipulate the list, you need to reference that "master" as well as possibly a node to work on. That allows you to access both ends of the list directly as well as e.g. keeping a count of elements. If you don't keep explicit end pointers and counts you have to iterate through the entire list every time you need to either know the count or do something on the other end of it. Super Ninja Fish posted:After 30 minutes of looking at this part and trying it out with just using result, I see that current_destination at the only refers to the last element while result still refers to the first. This type of list is also called a singly linked list, because each node only links in one direction. You can also create doubly linked lists, where each node links to both its successor and its predecessor. It uses a bit more memory per node (because you need two pointers instead of just one), but it can be walked in both directions. On a side note, the std::list data structure in C++ is a doubly linked list with a "master". Continuing with the singly linked structure above, what happens here and why is it bad? code:
|
|
# ? Nov 20, 2011 17:11 |
|
Gonna re-ask this: Good C++ primer/book/material for a guy who knows OOP/programming basics of higher level languages (C#, python) but wants to elarn C++?
|
# ? Nov 20, 2011 18:14 |
Walked posted:Gonna re-ask this: Try Stroustrup's The C++ Programming Language, it's written for programmers. You can read some excerpts from it at Stroustrup's website. (He writes a 4th edition which covers C++11 is in the works, but finished at earliest summer 2012. The current Special Edition is still good )
|
|
# ? Nov 20, 2011 18:42 |
|
nielsm posted:Try Stroustrup's The C++ Programming Language, it's written for programmers. You can read some excerpts from it at Stroustrup's website. (He writes a 4th edition which covers C++11 is in the works, but finished at earliest summer 2012. The current Special Edition is still good ) Thank you. The excerpts are awesome. Going to pick this up.
|
# ? Nov 20, 2011 20:14 |
|
I am having another battle with Visual Studio 2010 over porting a project. In this case, there is a unit_tests.cpp file sprinkled throughout a project in different subdirectories, testing stuff relevant to that subdirectory. I am getting a lot of this when trying to link:code:
Edit: Oh well I guess I see what I could do: http://stackoverflow.com/questions/3695174/visual-studio-2010s-strange-warning-lnk4042 Rocko Bonaparte fucked around with this message at 07:19 on Nov 21, 2011 |
# ? Nov 21, 2011 07:17 |
|
Rocko Bonaparte posted:Edit: Oh well I guess I see what I could do: http://stackoverflow.com/questions/3695174/visual-studio-2010s-strange-warning-lnk4042 If you are attached to using VS, another option is to split the project into multiple projects all under one top-level "solution". VS flattening a project's build space into one object directory makes some sense since everything that gets statically linked together ultimately can't have conflicting symbols anyways, and symbols tables do not care at all about the structure of your source tree.
|
# ? Nov 21, 2011 09:39 |
|
nielsm posted:
Yo, nielsm, your post was great in general, but "struct ListNode *node1, node2;" declares node1 as a pointer-to-ListNode and node2 as a ListNode. See: http://codepad.org/cPWA3Jca
|
# ? Nov 21, 2011 19:08 |
TasteMyHouse posted:Yo, nielsm, your post was great in general, but "struct ListNode *node1, node2;" declares node1 as a pointer-to-ListNode and node2 as a ListNode. See: Turns out I didn't proof-read everything! If I was writing that for my own use I would have made a typedef struct ListNode *PListNode; or similar, maybe I should have done that anyway.
|
|
# ? Nov 21, 2011 23:47 |
|
nielsm posted:Turns out I didn't proof-read everything! I generally don't like typedefs for pointer types because they become misleading when combined with const. For example: code:
Mr.Radar fucked around with this message at 04:17 on Nov 22, 2011 |
# ? Nov 22, 2011 04:15 |
|
I'm tooling around with C++, mostly trying to learn stuff. Suppose I would want to test if I'm out of bounds of my allocated array, is this ok? code:
code:
edit: I could of course check for the last position in the allocated array instead but I'm curious.
|
# ? Nov 22, 2011 12:41 |
You can calculate and compare pointers all you want, things can only go wrong when you go about dereferencing them. After all, pointers are just numbers the compiler assigns a special meaning. Trying to access one element past the end of an array may not trigger a runtime error, but it is an error nonetheless. You may get lucky and hit a page not allocated by the OS, which gives you an access violation, but you may just as well hit some memory the runtime library's allocator has obtained from the OS but not allocated to you yet, or you may hit data from a different allocation. But having a pointer one past the end of the allocation is basically what the STL container types do with their iterators, giving the idiom: for (iterator bar = foo.begin(); bar != foo.end(); ++bar)
|
|
# ? Nov 22, 2011 12:58 |
|
You're allowed to offset up to one element past the array, and you're still guaranteed to get a valid pointer. So your proposed usage of having a pointer one past the end so that you know when to stop works fine. Actually dereferencing the pointer, on the other hand, is not guaranteed to work. In fact, the standard explicitly calls out that there might only be a single byte at that point, and that byte might be used by some other object - all that's required is that the pointer itself be "valid".
|
# ? Nov 22, 2011 13:07 |
|
Allright, thanks!
|
# ? Nov 22, 2011 14:09 |
|
nielsm posted:Trying to access one element past the end of an array may not trigger a runtime error, but it is an error nonetheless. You may get lucky and hit a page not allocated by the OS, which gives you an access violation, but you may just as well hit some memory the runtime library's allocator has obtained from the OS but not allocated to you yet, or you may hit data from a different allocation. Or worse, you might write to the allocator's internal data structures.
|
# ? Nov 22, 2011 19:53 |
|
Jabor posted:You're allowed to offset up to one element past the array, and you're still guaranteed to get a valid pointer. So your proposed usage of having a pointer one past the end so that you know when to stop works fine. What does it mean for the pointer to be "valid" if it's not dereferencable?
|
# ? Nov 22, 2011 20:58 |
|
|
# ? Jun 8, 2024 08:07 |
|
GrumpyDoctor posted:What does it mean for the pointer to be "valid" if it's not dereferencable? It means the pointer's okay but you can't dereference it. Basically, code:
|
# ? Nov 22, 2011 21:05 |