C language -- storage categories and links

Posted by mechew on Tue, 28 Dec 2021 12:44:54 +0100

Storage category

C language provides many different models or storage categories to store data in memory.

Scope

Scope describes the area in the application where identifiers are accessible. Let's start with a brief introduction:
The scope of a C variable can be:

  • Block scope
  • Function scope
  • Function prototype scope
  • File scope

A block is a code area enclosed in a pair of curly braces. The whole function body is a block, and any matching statement in the function is also a block.
For example:

int Add_Sum(int num)
{
	int sum = 0;
	for (int i = num; i >0; --i)	//i is the variable in the block of the for loop
	{
		sum += i;
	}								//End of scope for i
	return sum;
}

The function scope is only used for the label of goto statement, which means that even if a label appears in the inner block of the function for the first time, its scope extends to the whole function.

The function prototype scope is used for the formal parameter name in the function prototype

int Add_Sum(int num);

The scope of num starts from the definition to the end of the prototype declaration.

Variables are defined outside the function and have file scope.
Variables with file scope are visible from the definition to the end of the file where the definition is located.

#include<stdio.h>
#include<stdlib.h>

int count = 0;	//With file scope
int main(void)
{
	...
	...
	return 0;
}

Variables such as count can be used in multiple functions, so they are also called global variables.

link

C variables have three link attributes:
External links;
Internal links;
No link.

Variables with block scope, function scope and function prototype scope are unlinked variables.
Variables with file scope can be external links or internal links,
External link variables can be used in multi file programs,
Internal link variables can only be used in one translation unit.
(translation unit: the compiler regards the source code file and all header files as a separate file containing information, which is called translation unit. If a program is composed of multiple source code files, the program will also be composed of multiple translation units. Each translation unit corresponds to a source code file and the files it contains)

static

How do I know whether a file scope variable is an internal link or an external link?
Check whether the storage category specifier static is used in the external definition.

#include<stdio.h>

int Max = 10;	//File scope, external links
static int Min = 0;		//File scope, internal links

int main(void)
{
	...
}

This file and other files of the unified program can use the variable Max, and the variable Min is private to the file, which can be used by any function in the file.

Storage period

Scope and links describe the visibility of identifiers, and the storage period describes the lifetime of objects accessed through these identifiers.
C objects have four storage periods:

  • Static storage - file scope variables have a static storage period.
  • Thread storage period - used for concurrent programming. Program execution can be divided into multiple threads. An object with a thread storage period exists from the time it is declared to the end of the thread.
  • Automatic storage period - block scoped variables generally have automatic storage periods. When the program enters the block defining these variables, allocate memory for these variables; When the block is exited, the memory just allocated for the variable is released.
  • Dynamically allocate storage periods

Storage category

5 storage categories

Automatic variable

Variables belonging to the autostore category have autostore periods, block scopes, and no links.
Generally, it can be stated as follows:

auto int x;

Block scope and no link means that a variable can only be accessed through its name in the block in which it is defined.
For example:

#include<stdio.h>

int main(void)
{
	int x = 10;
	
	printf("x in outer block :%d at %p\n", x, &x);
	if (x > 1)
	{
		int x = 20;
		printf("x in inner block :%d at %p\n", x, &x);
	}

	return 0;
}

Operation results:

The addresses of two x's are different. This is equivalent to Zhang San on the second floor and Zhang San on the third floor, but they are definitely not the same person..

Block scoped static variables

A static variable means that the variable does not move in memory. These variables do not disappear after programs leave their function.
Example:

#include<stdio.h>

void Try_Static();
int main(void)
{
	int i = 0;
	for (i = 0; i < 5; ++i)
	{
		Try_Static();
	}
	return 0;
}

void Try_Static()
{
	int a = 0;
	static int b = 0;

	printf("a = %d \n", a++);
	printf("b = %d \n", b++);
}

Operation results:

You can see that every time you call the function try_ When static (), a will be redeclared, while b always exists.

Externally linked static variables

It has file scope, external link and static storage period.
Variables belonging to this category are called external variables.
If an external variable used by one source code file is defined in another source code file, the variable must be declared in that file with extern.

#include<stdio.h>

int x;			//Externally defined variables
int ar[10];		//Externally defined array
extern int a;	//If a is defined in another file, declare it this way

int main(void)
{
	extern int x;	//sure
	...
	return 0;
}

Internally linked static variables

This variable has static storage period, file scope and internal links.
static is defined outside all functions with the storage category specifier.
Example:

int a = 10;			//External links
static int b = 10;	//internal link

int main(void)
{
	extern int a;	//Use a defined elsewhere
	extern int b;	//Use b defined elsewhere
}

Both a and b have file scopes, but only a can be used for other translation units.
Both declarations use the extern keyword, indicating that the definitions of the two variables used in main () are elsewhere.

Program example

//part_a.cpp
#include<stdio.h>
void Report_Count();
void accumulate(int n);

int count = 0;		//File scope, external links

int main(void)
{
	int value;	//Automatic variable
	register int i;	  //register variable

	printf("Please enter a positive integer ");
	printf("or enter q to quit:\n");
	while (scanf_s("%d", &value) == 1 && value > 0)
	{
		++count;
		for (i = value; i >= 0; --i)
		{
			accumulate(i);
		}
		printf("Please enter next poistive integer ");
		printf("or enter q to quit:\n");
	}
	Report_Count();

	return 0;
}

void Report_Count()
{
	printf("Loop executed %d times\n", count);
}
//part_b.cpp
#include<stdio.h>

extern int count;	//Referential declarations, external links

static int total = 0;	//Static definition, internal link
void accumulate(int n);

void accumulate(int n)
{
	static int subtotal = 0;	//Static no link

	if (n <= 0)
	{
		printf("Loop cycle: %d\n", count);
		printf("subtotal:%d; total: %d\n", subtotal, total);
		subtotal = 0;
	}
	else
	{
		subtotal += n;
		total += n;
	}
}

Running example:

Random number functions and static variables

ANSI C provides the * * rand() * * function to generate random numbers.
The procedure is as follows:

// rand0.cpp

//seed
static unsigned long int next = 1;

unsigned int rand0()
{
	//Formula for generating pseudo-random number
	next = next * 1103515245 + 12345;

	return (unsigned int)(next / 65536) % 32768;
}

Then test the program:

//test
#include<stdio.h>
extern unsigned int rand0();

int main(void)
{
	int ar[10];
	//Initializing arrays with random numbers
	for (int i = 0; i < 10; ++i)
	{
		ar[i] = rand0();
	}
	//Print it out and view it
	for (int i = 0; i < 10; ++i)
	{
		printf("%d\n", ar[i]);
	}
	return 0;
}

Operation results:

Topics: C