As been mentioned in the comments, this is not a trivial task that could be written with a few lines of code. What you need is a parser. That parser needs to handle many different cases. Here is a (probably non-exhaustive) list:
- One line comments: // This is a comment
- Multiline comments: /* This is a comment */
- Characters: char c='&'
- String literals: strcmp(str, "A string with a & in it")
- The bitwise operator: int a = mask & b
You would also need to decide how to handle incorrect input. Should the program be able to detect incorrect c code, or should it assume all input is correct? Another thing to consider is how to handle #include. Do you want to count the number of occurrences in the included files too? (I assume not, but this demonstrates a problem) 
If you want it to 100% accurate in finding only the address operator, then it is way above your knowledge. (OP wrote "This is a problem is designed to be solved by 1st-semester students with only basic knowledge." in comment below)
If you're allowed to cut some corners there are easier ways. 
Here is a complete example that cut some corners. It handles comments and strings, including escaped characters. However, it does not handle the bitwise operator.
#include <stdio.h>
#include <stdlib.h>
#define INPUT "input.c"
int main()
{
    FILE *f;
    if ((f = fopen(INPUT, "r")) == NULL)
    {
        perror (INPUT);
        return (EXIT_FAILURE);
    }
    char c, p=0;
    int n=0;
    while((c = fgetc(f)) != EOF)
    {
        if(c == '/' && p == '/') {
            while((c = fgetc(f)) != EOF) {
    // If we read // then we throw away the rest of the line
                if( c == '\n' ) {
                    break;
                }
            }
            if( c == EOF) {
                goto end;
            }
        }
        else if(c == '*' && p == '/') {
    // If we read /* then we throw away everything until we have read */
            while((c = getc(f)) != EOF) {
                if( c == '*' ) {
                    if((c = getc(f)) != EOF)
                        if( c == '/')
                            break;
                }
            } if ( c == EOF) {
                goto end;
            }
        }
        else if(c == '"') {
    // Read until end of string
            while((c = getc(f)) != EOF) {
                if(c == '\\') {
                    if((c = getc(f)) == EOF)
                       goto end;
                }
                else if(c == '"')
                    break;
            }
        }
        else if(c == '\'') {
            while((c = getc(f)) != EOF) {
                if(c == '\\') {
                    if((c = getc(f)) == EOF)
                       goto end;
                }
                else if(c == '\'')
                    break;
            } if ( c == EOF)
                  goto end;
        }
        else if(c == '&') {
            printf("hej");
            if(p == '&')
                n--;
            else
                n++;
        }
        p=c;
    }
    end:
    printf("\n\nExited at pos %ld\n", ftell(f));
    printf("Number of address operators: %d\n", n);
}
It works a bit like this: When it sees a start of a comment, it reads and throws away everything until the comment is finished or EOF. It does the same for strings.
On this input:
// Test &
/* Also
   &
   test */
// "
int main()
{
    /* " //
     */
    // /*
    char str[]="hej&\"";
    char c='&';
    char k='\'';
    int a, b;
    int * p;
    p=&a;
    int c=a&b;
    int q=a&&b;
}
// Test &
/* Also
   &
   test */
It reports the expected result 2. It would be better if it printed 1, but as I mentioned, it cannot handle the bitwise operator, thus counting it as an address operator. Fixing this issue would make things a lot more complicated.
And yes, I'm using goto since it is extremely convenient in a situation like this. In C++, I'd use exceptions, but that's not an option in C.