| Cubbi (1927) | |||||
|
I am constantly surprised to see people who are supposedly learning C++ attempting to solve problems using arrays and pointers while being completely unfamiliar with vectors (or other containers) and iterators (or even with strings! Although I think I'm starting to see more student code that uses C++ strings for characters and C arrays for everything else). I think arrays are so much disconnected from the rest of C++ (despite C++11's special versions of swap(), begin(), end(), and unique_ptr), that learning them before any normal container is a serious setback. Nobody needs to deal with the compatibility compromises made between B and C in 1972 when learning C++ in 2012. Textbooks seem to agree: Good old Accelerated C++ (2000)
Equally old Thinking in C++ (2000)
Stroustrup's favorite Programming Principles and Practice (2006)
Shiny new C++ Primer (2012)
Opinions? Arguments to the contrary? | |||||
|
|
|||||
| cire (2354) | |
|
I can do nothing but agree. I wonder how long it will it be before we actually see "learners" post code using std::array. | |
|
|
|
| Disch (8617) | |
|
The problem is with the way C++ is taught in academia. That is... poorly. Often times by teachers who know much less about the language than they should. So I agree. Then again, the common counter-argument to this is that "it's better to learn from the bottom up". That is, you should learn lower level concepts first, so that you can truly understand how higher level containers work and use them effectively. Personally I don't agree with that approach and have had great success learning top-down. But in a way it's an equally valid approach. | |
|
|
|
| iseeplusplus (363) | |
|
I know how to use vectors, but I prefer to dynamically allocate on my own when I don't need the functionality. Maybe it's a bad habit. When a higher level feature doesn't have any advantages for a given use, I prefer to use the lower level way. Sometimes I feel like C++ programmers are a little over paranoid, or protective, or what have you. If your using vector, you using a dynamically allocated array anyways. You just don't see it. I'm sure if I ever work on a larger collaborative project, I'll use vector all the time; to make everyone comfortable, and to be extra careful I, or someone, doesn't accidentally mess things up and cause a memory leak. | |
|
Last edited on
|
|
| helios (10258) | ||
IMO, if you think phrases like "arrays are like vectors" aren't complete nonsense, you probably don't need C++, since the code you produce will be no faster than if you had written it in a higher level language. It'll just take you longer.
How are they disconnected? | ||
|
|
||
| Catfish3 (279) | ||
That's an important point. Being built-in makes a big difference in "feel", I believe. This is why D has built-in dynamic arrays and built-in maps (which they call "associative arrays"). To fix this education problem, we should write articles about proficient C++ style. | ||
|
Last edited on
|
||
| Cubbi (1927) | |||||
std::sort() over a vector is many times faster than qsort() over an array (granted, it's not array's fault, it's the function pointers that murder performance in C).
The first program people learn in either language relies on the library components for I/O. Unless you're writing a parser for C++, studying the library cannot be an afterthought.
non-copyable/movable/returnable, unlike the rest of the containers (unless wrapped in structs) confusing to the beginners due to array-to-pointer conversion (which other containers don't have), so much so that people equate them with pointers. size-unaware (dynamic array only), which means the programmers have to drag along another piece of information everywhere they take the array, which leads to "pointer + size" style of programming, while in C++ you would rather have "pointer + pointer" size is part of the type (non-dynamic arrays only), and can't be accessed the same way as the size of other containers. allocator-unaware (dynamic array only), that's a deal-breaker for me in particular (we don't use new, we have too many different kinds of memory -- how I have to drag around pointer, size, and the allocator object? I might as well write my own vector) what am I saying, dynamic arrays aren't even accessible and have no names, can't be referenced, and the language bends over backwards with special rules for the pointers to their first elements. (until C++11 for non-dynamic) non-swappable (until C++11 for non-dynamic) unusable in generic programming because there was no common way to obtain iterators or value type from arrays that would also work with the rest of the containers. | |||||
|
Last edited on
|
|||||
| ResidentBiscuit (2650) | |
|
Gotta say I fully agree with Cubbi here. The first book I read while learning taught C++ pretty much as C with I/O streams and I'd say that negatively effected me. Even still I find myself using C style arrays and having the issue of passing size a long with it when I could have just used vector and made life easier. Though having one more include can also be kind of irritating. I don't know about the rest of you, but I hate having a long list of includes in any given file. | |
|
|
|
| hamsterman (4435) | |
| std::vector is slower, array is uglier, so hooray for std::array. Is there anything else that needs to be said in this thread? | |
|
|
|
| helios (10258) | |||||
Second, can you clarify these points? * Not accessible. * Not referenceable. * Special rules. | |||||
|
|
|||||
| Cubbi (1927) | ||||||||||
Just responding to your idea that those who think "array is similar to vector" is the normal way to think about it aren't interesting in performance. I say they start off with faster code. But that is indeed a side track, the thread is about education trends.
No, I am talking about how they are disconnected from the rest of C++. The rest of the language and the library works together, more or less uniformly, except the arrays.
Say you have a function that prints a container,
This function can be used with a non-dynamic array (since c++11)
but it cannot be used with a new[]'d array:
By special rules I mean the double-duty of the pointer to the first element of the dynamic array: it's both the begin iterator, and (through special relationship known to delete[] but not to delete, made doubly special for char[] arrays) the dynamic lifetime handler. | ||||||||||
|
|
||||||||||
| helios (10258) | ||||||
If you want full genericity, just do it the STL way:
| ||||||
|
|
||||||
| kbw (5522) | |
|
On the point of teaching C++, I think it's a huge task. The language is one thing, it's just got more and more complicated, and then there's the standard library. You have to start somewhere, you can't expect students to start writing expert code. So what if they use arrays? | |
|
|
|
| ResidentBiscuit (2650) | |
| They can teach Java just fine. I'd say that has a much larger built in library than C++ does. Why should it be any different for C++? | |
|
|
|
| kbw (5522) | |
| It's different because you don't need to understand how Java libraries work to use them effectively, whereas you do in C and C++. | |
|
|
|
| ResidentBiscuit (2650) | |
|
How do you figure? Java and C++ have the same types of containers that operate in almost the same way. Both have iterators, both have file I/O classes. I'd say you're defining effectively here different for Java and C++. If we define effectively as in proper use in the proper situations, they're the same. The Java equivalents of C++ STL classes work in a pretty similar manner. To say you need to understand the deep workings of a library to use it is not a language fault. That's a library fault. All a programmer using a library should care about is the outside interface. | |
|
|
|
| chrisname (6191) | |
| I don't know about Java, but understanding how the platform, libraries and language works, and thus how you write your code, can definitely have a significant effect on the performance of C#. I imagine the same applies to Java, and it certainly applies to C++. | |
|
|
|
| ResidentBiscuit (2650) | |
| Well see I wouldn't call that just effective at that point. This is saying if someone doesn't understand the intricacies of what a library is doing underneath, then you are an ineffective programmer. This just isn't true. Sure, knowing exactly how a library is implement can't hurt your ability, but that's not the line of being effective/ineffective. | |
|
|
|
| kbw (5522) | |
| If you don't understand that certain containers are implemented with some kind of tree structure, or others with linear structures, you'll have to learn their characteristics by rote, and that can't be good. | |
|
|
|
| ResidentBiscuit (2650) | |
| But that's just computation theory. People should either 1) know this already or, 2) the library won't expect you to know and will interface in such a manner. | |
|
|
|