6
$\begingroup$

Before I ask my question, some background may be apposite to provide context. Please indulge me.

At the institute I teach, our Intro to Programming. It involves a coverage of C language. We believe C is the most foundational and least verbose of most of the popular and heavily used modern languages, such as C++, C#, Java, Python etc. (you may not agree with our position, but that’s a discussion for another day).

Our institute trains people in various trades and skill areas including programming. We try to attract people to programming, by allowing them to take our Intro to Programming course regardless of what they registered to learn.

Our Intro to Programming class thus is a mix of different students from different backgrounds and at different levels of education (O’ level students looking to prepare for exams or learn a skill, under- and post grads, self-taught people, professional programmers crossing over to C who feel they need a sound foundation, our registered programming trainees etc.)

We attempt to give them sound fundamentals covering history of programming, basic concepts, variables, i/o, sequential, branching and looping constructs, doing maths with C, functions, data structures fundamentals, arrays and pointers. After covering up to arrays and pointers, we teach them C-structs.

My experience has been: the students learn up to arrays easily, get some trouble with pointers but get by after a lot of scaffolded and non-scaffolded exercises. However, when it comes to C-structs, it takes a lot of effort to get them to understand even the basic concepts of C-structure members and struct variables. They confuse struct members with variables and try to declare or access members the way they would an ordinary variable as I would show below.

Though I try to make the concept of structs as intuitive as possible, I run regularly in to this confusion in students. Consider this snippet below, as a typical example of what I use to introduce structs. The example, struct MyshoppingCart has 3 members (orangeNos, grainKgs & meatKgs) and 3 variables: my cart content for Monday (cartM), for Wednesday (cartW) and my cart contents for Sunday (cartS).

struct MyshoppingCart   // struct definition
{
  int orangeNos;
  float grainKgs;            // struct members
  float meatKgs;
} cartM, cartW;     // struct variables declaration type 1

int main()
{
    struct MyshoppingCart cartS;  // struct variable declaration type 2
}

With a simple struct like this, students show three difficulties.

  1. If you tell them cartM and cartW in the example above are struct variables, they ask why then are they not declared inside as members like int orangeNos; and double grainKgs; If I explain they are not inside because they represent an instance of the structure, they get more confused.

  2. If I try to explain different ways to declare struct variables i.e. method 1: right after and following the closing brace of the struct definition and method 2: inside main using the name of the structure as prefix, the confusion increases.

    It takes lengthy explanation and many examples to get some semblance of understanding from many of the students.

  3. When you get to accessing members of the structure and you tell the students, we can do this by using the dot notation as in:

(Code example)

cartM.orangeNos = 5;
cartS.meatKgs   = 3.7;
printf("No of oranges in my Monday cart is %d\n",  cartM.orangeNos);
printf("Mass of Meat in my Sunday cart is %.2f\n", cartS.meatKgs);

A student will just go ahead in accessing say orangeNos; to write something like:

printf("No of oranges in Monday cart is %d \n", orangeNos);

You tell him/her it’s wrong and: All hell just gets foot lose! They… just…. don’t …. get it …..EASY! He/she gets more confused!

My Question is:

Are these difficulties symptoms of cognitive overload? Or what could be the likely problem?

I have tried questioning students, but I have not gotten answers that may give me insight to the root of the problems.

Has anyone encountered similar problems teaching C-structs and how did you overcome it; getting students to learn it like a breeze? Please share your experiences or even suggestions you think might help me make learning structs easier and less herculean for my students.

$\endgroup$
6
  • 2
    $\begingroup$ Your example combines a type definition and the declaration of 2 variables. And for your students, it is probably the first occurrence of a "User Defined Datatype". $\endgroup$ Oct 25, 2019 at 11:55
  • 1
    $\begingroup$ Also, why should your students buy cartW.orangeNos instead of the int cartW_orangeNos variable they already can think of? A good motivation would be a function with a cart as an argument (say, void print_cart(struct ShoppingCart * c)). $\endgroup$ Oct 25, 2019 at 12:01
  • $\begingroup$ The topic is structs. The example is to illustrate structs. Are you suggesting making a function a member of the struct to handle the shopping cart data? That would introduce more complications don't you think? $\endgroup$ Oct 25, 2019 at 18:53
  • 2
    $\begingroup$ I suggest you make functions with structs as parameters. I definitely not recommend you to use functions as members at this stage of learning C. C is not C++. $\endgroup$ Oct 26, 2019 at 12:36
  • $\begingroup$ I see. Awesome! Your suggestion will help me kill 2 birds with one stone. It will consolidate learning of functions and at the same time underline the value of struct as a data structure. Oh thanks bro! You made my day $\endgroup$ Oct 26, 2019 at 15:06

5 Answers 5

3
$\begingroup$

I'm not convinced that the issue is necessarily related to using a language like C, or even cognitive overflow. I think that students often need a number of examples to illustrate a concept to be able to find the paradigm that works for them. Sometimes aspects of the example themselves use things that they cannot immediately relate to from the real world.

I see that @ErikEidt suggested using X,Y co-ordinates. This is one example that would work if the students have used graphical co-ordinates. Another one that is based on mathematics would be complex numbers.

Examples that I have often used is a library catalogue entry where books are described by author and title, and another one is a bank account record where information like customer name, address and account number are used, then again online customer records with name, address, item and so on.

Some students just learn by repetition repetition. Just showing them one example and then asking for an assessment will only work for the most quick minded students in the class who may have understood the concept already.

It is not about C per-se, or any language, but showing enough examples of a concept in use until the average (or even below average) student manages to grasp the concept.

$\endgroup$
2
  • $\begingroup$ Yes, examples galore. I do that. Class coding galore too l do. I appreciate especially your use of complex nos, bank account & library catalogue examples. You folks are really widening my repertoire of example concepts. Thanks. Keep them coming. $\endgroup$ Oct 26, 2019 at 18:27
  • $\begingroup$ How do you get to Carnegie Hall? Practice, practice. $\endgroup$
    – Scott Rowe
    Jan 13, 2020 at 2:17
5
$\begingroup$

First off, if your students are truly mastering pointers on their first course, hats off to you. That's quite a lot of material to pack into a semester.

Structs involve a mess of abstractions not present in anything you mentioned before in your course. What you are doing involves:

  • user-defined types
  • instances,
  • dot-notation, which is syntactically inconsistent with array notation (i.e. arr[7] vs arr.7), but otherwise essentially identical.
  • A side effect statement in which you declare your type and your variables together, in one statement.

I suspect that each one of these requires breaking down and practice. The last on, in particular, might not be worth the time. You don't actually need it, and side-effects should be approached with caution in any case. They cause confusion even for experienced programmers.

One intuitive case to practice is with some simple geometry and a point struct. For some reason, my students find p1.x - p2.x intuitive, and this gives them a bit of practice using instances without a lot of struggle. This understanding doesn't always translate to other structs, however. Instances really are a strange concept, and, at least in my classroom, it takes a while to hammer it home.

$\endgroup$
3
  • $\begingroup$ I like that idea of breaking up each part and drilling + using point struct. I have a feeling that should help.. Will try using that and see if it heThanks $\endgroup$ Oct 25, 2019 at 18:55
  • $\begingroup$ Yea, Pointers presents lot of challenges too but not as bad as structs $\endgroup$ Oct 26, 2019 at 1:19
  • $\begingroup$ Anyway in C you have to come to pointers rather quickly because of 1) strings 2) lack of parameter passing by reference. But dynamic allocation and linked structures - often presented under the name "teaching pointers" - can be safely seen much later. $\endgroup$ Oct 27, 2019 at 8:59
4
$\begingroup$

Try explaining to your students the concept of a product type using a simple notion of an x,y-coordinate.

We can illustrate a notion of pair of (integer) coordinates as an integer array of size 2.  Whenever we need to access the x-coordinate, we access [0] element and y-coordinate, the [1] element, for example.

A struct also does this — however, introducing a name for each position, and syntax for these accessing elements instead of using subscripting (while in C the struct construct also removes the ability to index by number).

A struct also has the following differences from an array:

  • A struct can have different members of different data types, whereas an array has all the same members.

  • A struct variable can be assigned and passed by value like a primitive type, whereas there is no notion of assigning or passing an array by value in C.

  • A struct will fail type match with another struct of the same composition but different type name — structs in C use nominal type matching, whereas arrays of same (element) declaration will succeed in type matching (they use structural type matching).

$\endgroup$
6
  • $\begingroup$ The curriculum requires I teach struct as a separate topic after earlier treating arrays, functions & pointers. So like you said I have to teach it's own syntax. Also bear in mind it is an intro course-. $\endgroup$ Oct 26, 2019 at 1:30
  • $\begingroup$ I don't understand your points. x,y coordinate is a simple concept at least in the real world. comparing structs to arrays to build on existing knowledge would probably best be done after learning arrays. $\endgroup$
    – Erik Eidt
    Oct 26, 2019 at 1:59
  • $\begingroup$ Yea, was just telling you I got more insights from your suggestion. I did an edit that didn't come on that comment that's why you didn't see where I'm heading. I'll retry see if it will show. $\endgroup$ Oct 26, 2019 at 2:19
  • $\begingroup$ The example of 2D or 3D coordinates automatically calls for the remark : why don't we use an array of 2 of 3 numbers? Better choose a struct with members of different types. $\endgroup$ Oct 26, 2019 at 12:40
  • $\begingroup$ I add the edit I made on my first comment that did not show up below... Your suggestion and that of @Ben I. have spinned off in my mind this example. (code sample) struct Point { int x, y; }; int main() { struct Point p1 = {1, 2}; //initialize var. // p2 is a pointer to structure p1 struct Point *p2 = &p1; //create pointer // Accessing structure members using structure pointer printf("%d %d", p2->x, p2->y); return 0; } $\endgroup$ Oct 26, 2019 at 15:17
3
$\begingroup$

You are teaching a fundamentally low level language. It is intentionally close to the hardware. Initially it was intended as a high level assembly language for one of the early computers of the Digital Equipment Corporation (a PDP-7).

So, having chosen that, you might as well teach it according to its design. A struct, fundamentally, is a "structured value", a complex sort of thing with named parts. It represents a contiguous block of bits with entries at various points. So a value of type MyShoppingCart is a block of (say) 80 bits where various parts of it are named. So orangeNos is a name for the first (say) 16 bits of that block, etc. Those are the members: parts of the whole. A float is a a simpler sort of value, having only one part visible in C (though internally it is also structured.

Now a struct valued variable, such as cartM or cartF, is a block of all (say) 80 bits. A given program might have several of these. But orangeNos has no independent meaning other than as part of some particular block of bits: the orangeNos "section" of that block. So, orangeNos, itself, has no value, but cartM.orangeNos does. cartM is a block of bits. cartM.orangeNos is an entry point into that block. But orangeNos itself has no meaning since no particular block is being referenced.

If you want to get even closer to the machine, cartM is actually the machine memory address of a block of bits. cartM.orangeNos is a machine address of a location within the block that "starts" at address cartM.

I'll note that other, higher level, languages don't need to be explained in terms of machine code, but since C is already at that level, you might just as well point out the, rather simple, mappings.


An array is also a structured value. It is homogeneous in structure, so each part has the same size, enabling indexing. A struct is heterogenous, so indexing doesn't work (not simply, at least).

$\endgroup$
2
  • $\begingroup$ Thanks, never thought of approaching the topic close to the metal like that. Interesting. $\endgroup$ Oct 25, 2019 at 18:46
  • 1
    $\begingroup$ You'll need such considerations when describing "bit-fields" members, and unions. $\endgroup$ Oct 26, 2019 at 12:42
3
$\begingroup$

@Ben said most of what I was about to write. However I have one more thing.

The example is terrible. A shopping cart for a shop that sells exactly 3 things, nothing more and nothing less, and never will it change. This is an alien enough concept, to confuse them. They know what a shop is, and this type of shop does not exist. They will try to match the code to what they know about shops and fail.

Therefore chose a different model.

$\endgroup$
4
  • 1
    $\begingroup$ I wanted to say that, but I was just being more tactful in my answer as part of the "be nice" policy. $\endgroup$ Oct 27, 2019 at 16:36
  • $\begingroup$ @BrianTompsett-汤莱恩 I love feedback so always assume that it if with love (unless proved otherwise). However I can get overwhelmed if there is too much. $\endgroup$ Oct 27, 2019 at 17:20
  • $\begingroup$ The shopping cart is a hypothetical person's shopping in a week. On Mondays, cartM, Wednesday, cartW, Sunday, cartS. The goods were limited to 3 for simplicity. Remember I am teaching a first course to non-CS people. $\endgroup$ Oct 28, 2019 at 1:40
  • $\begingroup$ @MallamAwal Yes I know that. What I am saying is that it is not a good example: Not because it is simplified, but because it can not work if extended (Try it), pupils will puck up on this. However they will not say to them-selves, "This is a bad example", they will say "I don't get it". That is they will assume that they are making the mistake. That they are interpreting it wrong, and will try to interpret it a different way. $\endgroup$ Oct 28, 2019 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.