Q:

How is the value of global variable changing in my code?

I have declared global variable again after the main function but It still affects main function. I know that C allows a global variable to be declared again when first declaration doesn’t initialize the variable(It will not work in c++). If I assign the value after the main function it still works with two warning in c but gives error in c++. 
I have debugged the code but it never reaches the line int a=10;.
#include <stdio.h>
#include <string.h>

int a;

int main()
{
    printf("%d",a);
    return 0;
}
/*a=10  works fine with following warnings in c.
        warning: data definition has no type or storage class
        warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]|

        but c++ gives the following error
        error: 'a' does not name a type|
*/
int a=10;

The output is 10.

A:

Several things:

The first int a; is a tentative declaration; the second int a = 10; is a defining declaration.
a is declared at file scope, so it will have static storage duration - this means that storage for it will be set aside and initialized at program startup (before main executes), even though the defining declaration occurs later in the source code.
Older versions of C allow for implicit int declaration - if a variable or function call appears without a declaration, it is assumed to have type int. C++ does not support implicit declarations, so you will get an error.

A:

Here
int a; /* global declaration */

compiler treats above statement as just a declaration not definition. It looks for definition of a in other translation units, it finds below main() as
int a=10;

Hence the output 10.
To avoid warnings, declare a with extern storage class for e.g
extern int a;

A:

From C Standard#6.9.2p2

2 A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.....

So, this
int a;

is tentative definition of identifier a. 
Couple of points about tentative definition:

If there are no definitions in the same translation unit, then the tentative definition acts as an actual definition with the initializer = 0.  
If an actual external definition is found earlier or later in the same translation unit, then the tentative definition just acts as a declaration. 

In your program, compiler found the definition of a in the same translation unit:
int a=10;

Hence, you are getting the output 10 when compiling with C compiler.
Now, regarding the error when compiling with C++ compiler:
If you have this statement in your program:
a=10;

This will give error when compile with C++ compiler because you are missing the type specifier which is required. But this code will compile with C complier because, in older version of C (C89/90), if the type specifier is missing then it will default set to int. Of course, you will get warning message when compile with C99 & C11 compiler because this implicit declaration is no longer supported. 
If you have this statement in your program:
int a=10;

C++ does not have concept of tentative definitions and int a; is definition in C++. Hence, due to concept of One Definition Rule the C++ compiler will give error - redefinition of 'a'.

