What you need to reset the arrays after the declaration and the constant.

#include <stdio.h> main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c - '0']; else if (c == ' ' || c == 'n' || c == 't') ++nwhite; else ++nother; printf("digits="); for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]); printf("white space = %d, other =%dn", nwhite, nother); } 

The fact is that I cannot explain this moment for myself

 for (i = 0; i < 10; ++i) ndigit[i] = 0; 

Why do we recalculate the cells of the array from 1 to 10, and then reset them further? And didn't it have to declare an array of 11 variables, since one cell is reserved for zero? The program itself is taken from Kernigan and Richie and is engaged in counting numbers.

  • Give an example, but it is not very clear. - stanislav
  • It is not always necessary to reset arrays, but I don’t understand about constants at all. - skegg pm
  • 3
    Formulate the question more clearly. If it is implied that explicitly initializing variables and arrays is necessary, it is because otherwise they will be filled with random values. Moreover, debug and release versions of programs may behave differently because of this. In the debug version, usually all arrays and variables are intitled by zeros. But I would not count on it. - gecube
  • one
    Reset constants? What is it like? In other words - need a code - Zowie
  • We need to think about the minuses of the first version of the question. Why do we need to reset the arrays after the declaration and the constant and that's it ... - avp

5 answers 5

gecube rightly says in the comment, C is not C # and Java, no one but you will not reset the values ​​in the array. When you allocate memory for an array, you allocate just a range of addresses, and what was (what is) in these memory cells nobody knows, no one knows what the program used this section of memory before. In this code, zeroing is carried out in order to count the repetitions of each digit in the entered string, i.e. the output in ndigit [3] will be the number of triples in ndigit [6] the number of sixes. You need to reset because of this construction ++ ndigit [c - '0']; so that there is no -3267.

    On the subject of the question is a classic programmer joke:

    Petit had 3 apples, he gave two to Masha. How many apples did Masha have?

    Think two? No, not right. We do not know how many apples she had before.

    The conclusion is that before assignment, the variables must be initialized in order to know the initial value. Zeroing is a special case of initialization, no more.

      Well, in fact, everything is not so, but rather not so flat. Suppose mmap (MAP_ANONYMOUS) gives already zanulёnye pages, and very funny, when 95% of them are null for reliability. Malloc in large pieces also uses mmap, and you don’t need to reset the memory. But no matter how much I gulp, everyone stupidly uses a Memphis for reliability.

      Vobschem probably easier to use Memphit, or to nullify as in the example "for reliability", in order to avoid any rake.

      • @ o2n3e, do you think calloc () without need will cause memset ()? I mean, what can you see the source (I’m usually lazy). - avp
      • one
        Never calloc (). I think that in a wildebeest are not idiots and in vain he doesn’t memset. - o2n3e

      Just before the first increment of ++ndigit , there is garbage in the cells, for example, the number 12560. and you need an increment from zero

        Appealing to an uninitialized object is not even unspecified, but undefined behavior. So you can not do, and the compiler according to the standard has the right to generate code that will remove your database and transfer your money to Afghan hackers.

        That is, there is not just "it is not clear what value." The optimizer has the right to assume that access to an uninitialized variable cannot exist in principle and remove any piece of code around. The fact that there were no problems before was pure coincidence.

        Examples: [1] , [2] .

        • True, the static variables the compiler itself initializes to zero. Also, in Linux, the "fresh" pages returned by the kernel (first received by the process) are also zeroed out. - avp pm
        • @avp: Fresh pages - yes. But the local variable in the function will most likely be on the stack, and it is most often already allocated. In addition, you can completely run into a trap representation (for example, Not A Thing ). - VladD
        • @VladD, yes - "fresh pages" is information that is almost impossible to use. In fact, their zeroing is in some way a crazy idea, which was once implemented to appease paranoid safes. - avp
        • one
          Even as a violation. There is a whole bunch of patterns that use it. I personally met this (the answer is proposed to guess, then compile without optimizations and guess again. Yes, I know that such code is very strong trash, but this is sometimes used in microcontrollers) #include <stdio.h> void set (int a ) {int b; b = a; } void print () {int b; printf ("b =% d", b); } int main (void) {set (100); print (); return 0; } - KoVadim
        • one
          I looked in 64-bit Ubuntu (the same gcc 4.8.2), yes, it prints 100. It is quite natural, since it is known that in this architecture the arguments in the function are passed in registers. - By the way, I don’t understand at all why, when passing arguments on the stack, do you expect that b in set(int a) and b in print() will be located at the same address? - Looks like the last comment here, so I can not discuss ... - avp