3

In C, I know you can assign strings to char pointers, so by extension, why does this fail? So, I have a char double pointer, and say initially I want it to have certain values. Then I'm done using those and I want to re-assign it.

char **notes = {
    "C4", "C5", "A3", "A4", "A3#", "A4#", "REST",
    "C4", "C5", "A3", "A4", "A3#", "A4#", "REST",
    "F3", "F4", "D3", "D4", "D3#", "D4#", "REST",
    "F3", "F4", "D3", "D4", "D3#", "D4#", "REST",
    "D4#", "D4", "C4#", "C4", "D4#", "D4", "G3#",
    "G3", "C4#", "C4", "F4#", "F4", "E4", "A4#",
    "A4", "G4#", "D4#", "B3", "A3#", "A3", "G3#"
};

// do something with notes, then

notes = {
    "C3", "C4", "A2", "A3", "A2#", "A3#", "REST",
    "C3", "C4", "A2", "A3", "A2#", "A3#", "REST",
    "F2", "F3", "D2", "D3", "D2#", "D3#", "REST",
    "F2", "F3", "D2", "D3", "D2#", "D3#", "REST",
    "D3#", "D3", "C3#", "C3", "D3#", "D3", "G2#",
    "G2", "C3#", "C3", "F3#", "F3", "E3", "A3#",
    "A3", "G3#", "D3#", "B2", "A2#", "A2", "G2#"
};

I get the error:

error: expected expression
notes = {
        ^

(Bonus points to anyone who can identify the song. Hint: switch the sharps to equivalent flats)

1
  • 3
    It's the Mario underground theme. Do I get bonus points even though I didn't get proper answer points? Commented Apr 18, 2015 at 23:14

1 Answer 1

4

You should initialize it where it is declared and not as a separate step.

char** notes = {
    "C3", "C4", "A2", "A3", "A2#", "A3#", "REST",
    "C3", "C4", "A2", "A3", "A2#", "A3#", "REST",
    "F2", "F3", "D2", "D3", "D2#", "D3#", "REST",
    "F2", "F3", "D2", "D3", "D2#", "D3#", "REST",
    "D3#", "D3", "C3#", "C3", "D3#", "D3", "G2#",
    "G2", "C3#", "C3", "F3#", "F3", "E3", "A3#",
    "A3", "G3#", "D3#", "B2", "A2#", "A2", "G2#"
};

The above causes undefined behavior if you try to modify it later on. If you want a mutable array, one option is using the 2 dimensional array notation (char notes[][4] = ...), but that would lead to waste of space in this format, because you would need 4 characters to be stored per element as the longest character array is 4 in length, 3 non-nulls and one null.

Update: If you're using C99, there are compound literals that allow you to make the right hand side an expression and hence reassign to it in the following manner.

char** notes;
notes = (char*[]) {
    "D3", "C4", "A2", "A3", "A2#", "A3#", "REST",
    "C3", "C4", "A2", "A3", "A2#", "A3#", "REST",
    "F2", "F3", "D2", "D3", "D2#", "D3#", "REST",
    "F2", "F3", "D2", "D3", "D2#", "D3#", "REST",
    "D3#", "D3", "C3#", "C3", "D3#", "D3", "G2#",
    "G2", "C3#", "C3", "F3#", "F3", "E3", "A3#",
    "A3", "G3#", "D3#", "B2", "A2#", "A2", "G2#"
};

Example: https://ideone.com/eD1xFu

Sign up to request clarification or add additional context in comments.

4 Comments

What if I want to reassign the values later? This still doesn't explain why C doesn't allow the assignment after declaration. I get that this is a solution, but only if I'm not reassigning the array.
@PatrickRoberts No easy way to do that. When you do the above, it is probably in the ROData section and not modifiable (causes UB). If you do want to modify it, you should be malloc-ing that storage (or using the array notation). The above is only suitable for small amounts of data which doesn't change for the duration of your program.
@PatrickRoberts Please see update if you are using C99 and simply want to reassign another constant set of values to it.
@PatrickRoberts, If you have to modify the notes in some way, you should allocate using malloc or using the array notation on the "stack", because these are immutable.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.