2

In my book there is an example which explains the differences between arrays in Java and C.

In Java we can create an array by writing:

int[] a = new int[5];

This just allocates storage space on the stack for five integers and we can access them exactly as we would have done in Java

int a[5] = {0};
int i;
for (i = 0, i < 5; i++){
    printf("%2d: %7d\n", i, a[i]);
}

Then the author says the following

Of course our program should not use a number 5 as we did on several places in the example, instead we use a constant. We can use the C preprocessor to do this:

#define SIZE 5

What are advantages of defining a constant SIZE 5?

Community
  • 1
  • 1
Olba12
  • 305
  • 2
  • 14
  • Use indentation (at least 5 spaces following '>') to format _code_ (I have done this for you). – davmac May 20 '16 at 22:02
  • 6
    I think they mean "use a *named* constant", i.e. avoid magic numbers. – GManNickG May 20 '16 at 22:02
  • 4
    Buy a new book. `new` creates storage from the heap, not the stack. – stark May 20 '16 at 22:02
  • @stark I suppose "this" refers to the snippet *below*, as suggested by the rest of the sentence. – Quentin May 20 '16 at 22:04
  • @stark: I *think* the "allocates storage space" remark is talking about the C++ code that follows. I think. – Michael Burr May 20 '16 at 22:05
  • 2
    Somewhere you are going to have a for loop go through the array, so rather than use 5, you can use `SIZE`. – stark May 20 '16 at 22:08
  • See [`static const` vs `#define` vs `enum`](https://stackoverflow.com/questions/1674032/static-const-vs-define-vs-enum/1674459#1674459) for a discussion of when `#define SIZE 5` as against, say, `enum { SIZE = 5 };` is appropriate. And see [What is the point of symbolic constants?](https://stackoverflow.com/questions/5062019/what-is-the-point-of-symbolic-constants/5062283) for a discussion and example of why symbolic constants are a good idea. – Jonathan Leffler May 20 '16 at 22:11

5 Answers5

4

Using a named constant is generally considered good practice because if it is used in multiple places, you only need to change the definition to change the value, rather than change every occurrence - which is error prone.

For example, as mentioned by stark in the comments, it is likely that you'll want to loop over an array. If the size of the array is defined by a named constant called SIZE, then you can use that in the loop bounds. Changing the size of the array then only requires changing the definition of SIZE.

There is also the question of whether #define is really the right solution. To borrow another comment, from Jonathan Leffer: see static const vs #define vs enum for a discussion of different ways of naming constants. While modern C does allow using a variable as an array size specifier, this technically results in a variable-length array which may incur a small overhead.

davmac
  • 20,150
  • 1
  • 40
  • 68
  • Yes, I understand this. My bad for not typing it out... From you answer I guess, there is no other advantages? And why would you do it with #define ... and not just a local variable int size = 5;? Is it because you might want to use SIZE inside another function? – Olba12 May 20 '16 at 22:09
  • 2
    And of course `SIZE` is just about the worst possible name you could use for such a constant, as it tells you precisely nothing about what the array is meant for, or why it is the given size. Constants like `UART1_RX_BUFFER_SIZE` are much preferred. – Lee Daniel Crocker May 20 '16 at 22:11
  • @Olba12 C++ and older versions of C do not allow non-constants to be used to declare an array size, so using a local variable such as `int size = 5` would probably give you a compilation error. – davmac May 20 '16 at 22:11
  • Oh, did not know that. Thanks for beinge patient with a newbie. :) – Olba12 May 20 '16 at 22:13
  • 2
    In C99 and later, you can use a local variable `int size = 5; int a[size];` if you wish. It is, however, a VLA — variable length array. There can be a little overhead associated with using VLAs, not enough to worry about most of the time, though. – Jonathan Leffler May 20 '16 at 22:15
3

You should use a constant, because embedding magic numbers in code makes it harder to read and maintain. For instance, if you see 52 in some code, you don't know what it is. However, if you write #define DECKSIZE 52, then whenever you see DECKSIZE, you know exactly what it means. In addition, if you want to change the deck size, say 36 for durak, you could simply change one line, instead of changing every instance throughout the code base.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
0

Well, imagine that you create a static array of 5 integer just like you did int my_arr [5]; ,you code a whole programm with it, but.. suddenly you realise that maybe you need more space. Imagine that you wrote a code of 6-700 lines, you MUST replace every occurence of you array with the fixed number of your choice. Every for loop, and everything that is related with the size of this array. You can avoid all of this using the preprocessor command #define which will replace every occurence of a "keyword" with the content you want, it's like a synonymous for something. Eg: #define SIZE 5 will replace in your code every occurence of the word SIZE with the value 5.

Claudio Cortese
  • 1,372
  • 2
  • 10
  • 21
  • Wrong assumption. Why would you code with fixed size, when you have `sizeof()` operator? – SergeyA May 20 '16 at 22:26
  • @SergeyA It's just another way to retrieve the size of an array, but why you would use sizeof() when you actually know that it has fixed size and indeed you know that it's 5, or using #define SIZE? – Claudio Cortese May 20 '16 at 22:31
  • 1
    Because this would work with arrays of variable sizes. – SergeyA May 20 '16 at 22:34
  • @SergeyA Of course yes, but hey, when do you program you have to know what do you want to achieve, hence, if you plan to use fixed-size static array you should use define and to retrieve the size just the keyword used for #define command. If you are going to use a dynamic array, of course you have to use sizeof() – Claudio Cortese May 20 '16 at 22:38
  • dynamic arrays and VLA arrays are not the same thing. – SergeyA May 20 '16 at 22:40
  • @SergeyA Indeed, VLA and fixed array are on the stack, whereas dynamic one are on the heap. What's the point? – Claudio Cortese May 20 '16 at 22:46
0

I find comments here to be superflous. As long as you use your constant (5 in this case) only once, it doesn't matter where it is. Moreover, having it in place improves readability. And you certainly do not need to use the constant in more than one place - afterall, you should infer the size of array through sizeof operator anyways. The benefit of sizeof approach is that it works seamlessly with VLAs.

The drawback of global #define (or any other global name) is that it pollutes global namespace. One should understand that global names is a resource to be used conservatively.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
-2
#define SIZE 5

This looks like an old outdated way of declaring constants in C code that was popular in dinosaur era. I suppose some lovers of this style are still alive.

The preferred way to declare constants in C languages nowadays is:

const int kSize = 5;
kinORnirvana
  • 1,667
  • 2
  • 17
  • 22
  • One big advantage is that this is typed. – stark May 20 '16 at 22:14
  • 3
    That works OK in C++; it isn't necessarily so desirable in C. You can't use `kSize` in contexts such as `case kSize:`, for example — it isn't sufficiently an integer constant, for all it is a constant integer. – Jonathan Leffler May 20 '16 at 22:17
  • 1
    That's not true, they differ a lot. One of the major difference is that SIZE hasn't a physical address related to it, because well, it's not a variable. Indeed they are both ways of doing the same thing but they differ in many aspects – Claudio Cortese May 20 '16 at 22:24