Storage Classes and Type Qualifiers

Question 1
Which of the following is not a storage class specifier in C?
A
auto
B
register
C
static
D
extern
E
volatile
F
typedef
Storage Classes and Type Qualifiers    
Discuss it


Question 1 Explanation: 
volatile is not a storage class specifier. volatile and const are type qualifiers.
Question 2
Output of following program?
#include <stdio.h>
int main()
{
    static int i=5;
    if(--i){
        main();
        printf("%d ",i);
    }
}
A
4 3 2 1
B
1 2 3 4
C
0 0 0 0
D
Compiler Error
Storage Classes and Type Qualifiers    
Discuss it


Question 2 Explanation: 
A static variable is shared among all calls of a function. All calls to main() in the given program share the same i. i becomes 0 before the printf() statement in all calls to main().
Question 3
#include <stdio.h>
int main()
{
    static int i=5;
    if (--i){
        printf("%d ",i);
        main();
    }
}
A
4 3 2 1
B
1 2 3 4
C
4 4 4 4
D
0 0 0 0
Storage Classes and Type Qualifiers    
Discuss it


Question 3 Explanation: 
Since i is static variable, it is shared among all calls to main(). So is reduced by 1 by every function call.
Question 4
#include <stdio.h>
int main()
{
    int x = 5;
    int * const ptr = &x;
    ++(*ptr);
    printf("%d", x);
  
    return 0;
}
A
Compiler Error
B
Runtime Error
C
6
D
5
Storage Classes and Type Qualifiers    
Discuss it


Question 4 Explanation: 
See following declarations to know the difference between constant pointer and a pointer to a constant. int * const ptr —> ptr is constant pointer. You can change the value at the location pointed by pointer p, but you can not change p to point to other location. int const * ptr —> ptr is a pointer to a constant. You can change ptr to point other variable. But you cannot change the value pointed by ptr. Therefore above program works well because we have a constant pointer and we are not changing ptr to point to any other location. We are only icrementing value pointed by ptr.
Question 5
#include <stdio.h>
int main()
{
    int x = 5;
    int const * ptr = &x;
    ++(*ptr);
    printf("%d", x);
  
    return 0;
}
A
Compiler Error
B
Runtime Error
C
6
D
5
Storage Classes and Type Qualifiers    
Discuss it


Question 5 Explanation: 
See following declarations to know the difference between constant pointer and a pointer to a constant. int * const ptr —> ptr is constant pointer. You can change the value at the location pointed by pointer p, but you can not change p to point to other location. int const * ptr —> ptr is a pointer to a constant. You can change ptr to point other variable. But you cannot change the value pointed by ptr. In the above program, ptr is a pointer to a constant. So the value pointed cannot be changed.
Question 6
#include<stdio.h>
int main()
{
  typedef static int *i;
  int j;
  i a = &j;
  printf("%d", *a);
  return 0;
}
A
Runtime Error
B
0
C
Garbage Value
D
Compiler Error
Storage Classes and Type Qualifiers    
Discuss it


Question 6 Explanation: 
Compiler Error -> Multiple Storage classes for a. In C, typedef is considered as a storage class. The Error message may be different on different compilers.
Question 7
Output?
#include<stdio.h>
int main()
{
   typedef int i;
   i a = 0;
   printf("%d", a);
   return 0;
}
A
Compiler Error
B
Runtime Error
C
0
D
1
Storage Classes and Type Qualifiers    
Discuss it


Question 7 Explanation: 
There is no problem with the program. It simply creates a user defined type i and creates a variable a of type i.
Question 8
#include<stdio.h>
int main()
{
  typedef int *i;
  int j = 10;
  i *a = &j;
  printf("%d", **a);
  return 0;
}
A
Compiler Error
B
Garbage Value
C
10
D
0
Storage Classes and Type Qualifiers    
Discuss it


Question 8 Explanation: 
Compiler Error -> Initialization with incompatible pointer type. The line typedef int *i makes i as type int *. So, the declaration of a means a is pointer to a pointer. The Error message may be different on different compilers.
Question 9
Output?
#include <stdio.h>
int fun()
{
  static int num = 16;
  return num--;
}

int main()
{
  for(fun(); fun(); fun())
    printf("%d ", fun());
  return 0;
}
A
Infinite loop
B
13 10 7 4 1
C
14 11 8 5 2
D
15 12 8 5 2
Storage Classes and Type Qualifiers    
Discuss it


Question 9 Explanation: 
Since num is static in fun(), the old value of num is preserved for subsequent functions calls. Also, since the statement return num– is postfix, it returns the old value of num, and updates the value for next function call.
fun() called first time: num = 16 // for loop initialization done;


In test condition, compiler checks for non zero value

fun() called again : num = 15

printf("%d \n", fun());:num=14 ->printed

Increment/decrement condition check

fun(); called again : num = 13

----------------

fun() called second time: num: 13 

In test condition,compiler checks for non zero value

fun() called again : num = 12

printf("%d \n", fun());:num=11 ->printed

fun(); called again : num = 10

--------

fun() called second time : num = 10 

In test condition,compiler checks for non zero value

fun() called again : num = 9

printf("%d \n", fun());:num=8 ->printed

fun(); called again   : num = 7

--------------------------------

fun() called second time: num = 7

In test condition,compiler checks for non zero value

fun() called again : num = 6

printf("%d \n", fun());:num=5 ->printed

fun(); called again   : num = 4

-----------

fun() called second time: num: 4 

In test condition,compiler checks for non zero value

fun() called again : num = 3

printf("%d \n", fun());:num=2 ->printed

fun(); called again   : num = 1

----------

fun() called second time: num: 1 

In test condition,compiler checks for non zero value

fun() called again : num = 0 => STOP 
Question 10
#include <stdio.h>
int main() 
{ 
  int x = 10; 
  static int y = x; 
  
  if(x == y) 
     printf("Equal"); 
  else if(x > y) 
     printf("Greater"); 
  else
     printf("Less"); 
  return 0; 
}
A
Compiler Error
B
Equal
C
Greater
D
Less
Storage Classes and Type Qualifiers    
Discuss it


Question 10 Explanation: 
In C, static variables can only be initialized using constant literals. This is allowed in C++ though.  See this GFact for details.
Question 11
Consider the following C function
int f(int n) 
{ 
   static int i = 1; 
   if (n >= 5) 
      return n; 
   n = n+i; 
   i++; 
   return f(n); 
}
The value returned by f(1) is (GATE CS 2004)
A
5
B
6
C
7
D
8
Storage Classes and Type Qualifiers    
Discuss it


Question 11 Explanation: 
Since i is static, first line of f() is executed only once.
Execution of f(1)
    i = 1
    n = 2
    i = 2
 Call f(2)
    i = 2
    n = 4
    i = 3
 Call f(4)
   i = 3
   n = 7
   i = 4
 Call f(7)
  since n >= 5 return n(7)
Question 12
In C, static storage class cannot be used with:
A
Global variable
B
Function parameter
C
Function name
D
Local variable
Storage Classes and Type Qualifiers    
Discuss it


Question 12 Explanation: 
Declaring a global variable as static limits its scope to the same file in which it is defined. A static function is only accessible to the same file in which it is defined. A local variable declared as static preserves the value of the variable between the function calls.
Question 13
Output? (GATE CS 2012)
#include <stdio.h>
int a, b, c = 0;
void prtFun (void);
int main ()
{
    static int a = 1; /* line 1 */
    prtFun();
    a += 1;
    prtFun();
    printf ( "\n %d %d " , a, b) ;
}
 
void prtFun (void)
{
    static int a = 2; /* line 2 */
    int b = 1;
    a += ++b;
    printf (" \n %d %d " , a, b);
}
A
3 1
4 1
4 2
B
4 2
6 1
6 1
C
4 2
6 2
2 0
D
3 1
5 2
5 2
Storage Classes and Type Qualifiers    
Discuss it


Question 13 Explanation: 
‘a’ and ‘b’ are global variable. prtFun() also has ‘a’ and ‘b’ as local variables. The local variables hide the globals (See Scope rules in C). When prtFun() is called first time, the local ‘b’ becomes 2 and local ‘a’ becomes 4. When prtFun() is called second time, same instance of local static ‘a’ is used and a new instance of ‘b’ is created because ‘a’ is static and ‘b’ is non-static. So ‘b’ becomes 2 again and ‘a’ becomes 6. main() also has its own local static variable named ‘a’ that hides the global ‘a’ in main. The printf() statement in main() accesses the local ‘a’ and prints its value. The same printf() statement accesses the global ‘b’ as there is no local variable named ‘b’ in main. Also, the defaut value of static and global int variables is 0. That is why the printf statement in main() prints 0 as value of b.
Question 14
What output will be generated by the given code d\segment if: Line 1 is replaced by “auto int a = 1;” Line 2 is replaced by “register int a = 2;” (GATE CS 2012)
A
3 1
4 1
4 2
B
4 2
6 1
6 1
C
4 2
6 2
2 0
D
4 2
4 2
2 0
Storage Classes and Type Qualifiers    
Discuss it


Question 14 Explanation: 
If we replace line 1 by “auto int a = 1;” and line 2 by “register int a = 2;”, then ‘a’ becomes non-static in prtFun(). The output of first prtFun() remains same. But, the output of second prtFun() call is changed as a new instance of ‘a’ is created in second call. So “4 2″ is printed again. Finally, the printf() in main will print “2 0″. Making ‘a’ a register variable won’t change anything in output. Please write comments if you find any of the answers/explanations incorrect, or you want to share more information about the topics discussed above.
Question 15
Output?
#include <stdio.h>
int main()
{
  register int i = 10;
  int *ptr = &i;
  printf("%d", *ptr);
  return 0;
}
A
Prints 10 on all compilers
B
May generate compiler Error
C
Prints 0 on all compilers
D
May generate runtime Error
Storage Classes and Type Qualifiers    
Discuss it


Question 15 Explanation: 
See point 1 of Register Keyword
Question 16
#include <stdio.h>
int main()
{
  extern int i;
  printf("%d ", i);
  {
       int i = 10;
       printf("%d ", i);
  }
}
A
0 10
B
Compiler Error
C
0 0
D
10 10
Storage Classes and Type Qualifiers    
Discuss it


Question 16 Explanation: 
Question 17
Output?
#include <stdio.h>

int main(void)
{
    int i = 10;
    const int *ptr = &i;
    *ptr = 100;
    printf("i = %d\n", i);
    return 0;
}
A
i = 100
B
i = 10
C
Compiler Error
D
Runtime Error
Storage Classes and Type Qualifiers    
Discuss it


Question 17 Explanation: 
Note that ptr is a pointer to a constant. So value pointed cannot be changed using the pointer ptr. See Const Qualifier in C for more details.
Question 18
Output of following program
#include <stdio.h>
int fun(int n)
{
    static int s = 0;
    s = s + n;
    return (s);
}

int main()
{
    int i = 10, x;
    while (i > 0)
    {
        x = fun(i);
        i--;
    }
    printf ("%d ", x);
    return 0;
}
A
0
B
100
C
110
D
55
Storage Classes and Type Qualifiers    
Discuss it


Question 18 Explanation: 
Since s is static, different values of i are added to it one by one. So final value of s is s = i + (i-1) + (i-2) + ... 3 + 2 + 1. The value of s is i*(i+1)/2. For i = 10, s is 55.
Question 19
#include <stdio.h>
char *fun()
{
    static char arr[1024];
    return arr;
}

int main()
{
    char *str = "geeksforgeeks";
    strcpy(fun(), str);
    str = fun();
    strcpy(str, "geeksquiz");
    printf("%s", fun());
    return 0;
}
A
geeksforgeeks
B
geeksquiz
C
geeksforgeeks geeksquiz
D
Compiler Error
Storage Classes and Type Qualifiers    
Discuss it


Question 19 Explanation: 
Note that arr[] is static in fun() so no problems of returning address, arr[] will stay there even after the fun() returns and all calls to fun() share the same arr[].
    strcpy(fun(), str);  // Copies "geeksforgeeks" to arr[]
    str = fun();    // Assigns address of arr to str
    strcpy(str, "geeksquiz");  // copies geeksquiz to str which is address of arr[]
    printf("%s", fun());   // prints "geeksquiz"
Question 20
Consider the following C function, what is the output?
#include <stdio.h>
int f(int n)
{
    static int r = 0;
    if (n <= 0) return 1;
    if (n > 3)
    {
        r = n;
        return f(n-2)+2;
    }
    return f(n-1)+r;
}

int main()
{
    printf("%d", f(5));
}
A
5
B
7
C
9
D
18
Storage Classes and Type Qualifiers    GATE-CS-2007    
Discuss it


Question 20 Explanation: 
f(5) = f(3)+2  
The line "r = n" changes value of r to 5.  Since r 
is static, its value is shared be all subsequence 
calls.  Also, all subsequent calls don't change r
because the statement "r = n" is in a if condition 
with n > 3.

f(3) = f(2)+5
f(2) = f(1)+5
f(1) = f(0)+5
f(0) = 1

So f(5) = 1+5+5+5+2 = 18 
Question 21
In the context of C data types, which of the followings is correct?
A
“unsigned long long int” is a valid data type.
B
“long long double” is a valid data type.
C
“unsigned long double” is a valid data type.
D
A), B) and C) all are valid data types.
E
A), B) and C) all are invalid data types.
Storage Classes and Type Qualifiers    C Quiz - 102    
Discuss it


Question 21 Explanation: 

In C, "float" is single precision floating type. "double" is double precision floating type. "long double"is often more precise than double precision floating type.  So the maximum floating type is "long double". There's nothing called "long long double". If someone wants to use bigger range than "long double", we need to define our own data type i.e. user defined data type. Besides, Type Specifiers "signed" and "unsigned" aren't applicable for floating types (float, double, long double). Basically, floating types are always signed only.

But integer types i.e. "int", "long int" and "long long int" are valid combinations. As per C standard, "long long int" would be at least 64 bits i.e. 8 bytes. By default integer types would be signed. If we need to make these integer types as unsigned, one can use Type Specifier "unsigned". That's why A) is correct answer.

Question 22
For the following “typedef” in C, pick the best statement
typedef int INT, *INTPTR, ONEDARR[10], TWODARR[10][10];
A
It will cause compile error because typedef is being used to define multiple aliases of incompatible types in the same statement.
B
“INT x” would define x of type int. Remaining part of the statement would be ignored.
C
“INT x” would define x of type int and “INTPTR y” would define pointer y of type int *. Remaining part of the statement would be ignored.
D
“INT x” would define x of type int. “INTPTR y” would define pointer y of type int *. ONEDARR is an array of 10 int. TWODARR is a 2D array of 10 by 10 int.
E
“INT x” would define x of type int. “INTPTR *y” would define pointer y of type int **. “ONEDARR z” would define z as array of 10 int. “TWODARR t” would define t as array of 10 by 10 int.
Storage Classes and Type Qualifiers    C Quiz - 106    
Discuss it


Question 22 Explanation: 
Here, INT is alias of int. INTPTR is alias of int *. That’s why INTPTR * would be alias of int **. Similarly, ONEDARR is defining the alias not array itself. ONEDARR would be alias to int [10]. That’s why “ONEDARR z” would define array z of int [10]. Similarly, TWODARR would be alias to int [10][10]. Hence “TWODARR t” would define array t of int [10][10]. We can see that typedef can be used to create alias or synonym of other types.
Question 23
Which of the followings is correct for a function definition along with storage-class specifier in C language?
A
int fun(auto int arg)
B
int fun(static int arg)
C
int fun(register int arg)
D
int fun(extern int arg)
E
All of the above are correct.
Storage Classes and Type Qualifiers    C Quiz - 107    
Discuss it


Question 23 Explanation: 
As per C standard, “The only storage-class specifier that shall occur in a parameter declaration is register.” That’s why correct answer is C.
Question 24
Pick the correct statement for const and volatile.
A
const is the opposite of volatile and vice versa.
B
const and volatile can’t be used for struct and union.
C
const and volatile can’t be used for enum.
D
const and volatile can’t be used for typedef.
E
const and volatile are independent i.e. it’s possible that a variable is defined as both const and volatile.
Storage Classes and Type Qualifiers    C Quiz - 107    
Discuss it


Question 24 Explanation: 
In C, const and volatile are type qualifiers and these two are independent. Basically, const means that the value isn’t modifiable by the program. And volatile means that the value is subject to sudden change (possibly from outside the program). In fact, C standard mentions an example of valid declaration which is both const and volatile. The example is “extern const volatile int real_time_clock;” where real_time_clock may be modifiable by hardware, but cannot be assigned to, incremented, or decremented. So we should already treat const and volatile separately. Besides, these type qualifier applies for struct, union, enum and typedef as well.
Question 25
Pick the best statement for the following program snippet:
#include "stdio.h"
void foo(void)
{
 static int staticVar;
 staticVar++;
 printf("foo: %d\n",staticVar);
}

void bar(void)
{
 static int staticVar;
 staticVar++;
 printf("bar: %d\n",staticVar);
}

int main()
{
 foo(), bar(), foo();
 return 0;
}
A
Compile error because same static variable name is used in both foo and bar. Since these static variables retain their values even after function is over, same name can’t be used in both the functions.
B
Compile error because semicolon isn’t used while calling foo() and bar() in side main function.
C
No compile error and only one copy of staticVar would be used across both the functions and that’s why final value of that single staticVar would be 3.
D
No compile error and separate copies of staticVar would be used in both the functions. That’s why staticVar in foo() would be 2 while staticVar in bar() would be 1.
Storage Classes and Type Qualifiers    C Quiz - 111    
Discuss it


Question 25 Explanation: 
Here, even though life of static variables span across function calls but their scope is respective to their function body only. That’s why staticVar of each function has separate copies whose life span across function calls. And d is correct.
There are 25 questions to complete.

GATE CS Corner


See Placement Course for placement preparation, GATE Corner for GATE CS Preparation and Quiz Corner for all Quizzes on GeeksQuiz.