answersLogoWhite

0


Best Answer

A type declaration introduces a user-defined type. The new type may be an alias, a structure, a union or an enumeration.

Aliases are typically used to reduce verbosity:

typedef unsigned long long UINT;

Here we can use the UINT alias wherever we'd normally use an unsigned long long. The compiler will treat the UINT type just as it would an unsigned long long. We can also use macros to achieve the same thing however a macro is not type safe.

Data structures allow us to create aggregate data types:

typedef struct Data { int x; double y; char* z; };

Unlike an array where all elements must be of the same type, data structure members may be any type (both built-in and user-defined) and of any length (in bytes). Each member has a name whereas array elements are accessed using zero-based subscripts. The length of a data structure is the sum of its member lengths plus any padding bytes for alignment purposes. For instance, pointers are typically aligned on word boundaries.

In the above example, the full name of the data type is struct Data. Repeating the struct keyword every time we want to use this data type can quickly become tiresome:

struct Data a[100];

struct Data* b;

struct Data c;

Fortunately, we can append an alias to reduce the verbosity:

typedef struct Data { int x; double y; char* z; } data;

Note that the actual type is still struct Data. However, we can now use the alias data in our code:

data a[100];

data* b;

data c;

Unions allow us to optimise memory consumption:

typedef union Stuff { char c; int i; long double d; } stuff;

Unlike a structure where each member is allocated separately, union members are allocated to the same address. The length of a union is equal to the length of the largest member. Unions are useful when we have two or more variables of different types but we only require one of them at any given time. The onus is on the programmer to keep track of which member is the active member.

A common error with new programmers is to use a union as an unsafe type cast. This is particularly bad when the cast is to a pointer type:

typedef union Stuff { int i; int* p; } stuff;

int* cheat (int x) {

stuff s;

s.i = x; // assign the value of x to s.i

return s.p; // "cast" x to a memory address (to int)

}

This function has undefined behaviour. Firstly, the code assumes that an int is the same length as a pointer to int. That may well be the case on some systems but certainly not for all systems. On a 64-bit system an int might be 4 bytes long, but a pointer may well be 8 bytes long. Under those circumstances, the integer value cannot possibly cover the entire address space. Worse, when we assign x to s.i, only the low-order bytes of s.p will be overwritten. The high-order bytes will be whatever value happens to reside in that memory at the time. The returned address could be pointing literally anywhere, but almost certainly not where you intended to be pointing. Even if sizeof (int) and sizeof (int*) are the same length, the code is still unsafe because it would be unreasonable to expect an integer to be allocated to an odd address and there's a 50% chance x is an odd value. Worse, integers are typically aligned on 4-byte boundaries and there's a 75% chance x is not a multiple of 4. And that's before we consider whether the address we return actually belongs to our program. In short, don't use unsafe casts!

An enumeration is simply a group of named constants.

enum e {m1, m2, m3, m4};

By default, members are enumerated in the order they are declared, starting at 0, incrementing by 1 for each subsequent member. However, we can assign any value to any member and restart the enumeration from that point onward. We can even assign the same value to more than one member.

Assuming the default values (m1=0, m2=1, m3=2 and m4=3), we can use the members just as we would any other constant:

void f (e data) {

if (data == m1) {

data = 20;

}

}

In the above example, although the data argument is an e type, we can assign it any valid integral value (20 is not defined by the e type). Typically we would want to restrict values to just those that we defined. For that we need to typedef the enumeration (with an alias):

typedef enum t {m1, m2, m3, m4} e;

void f (e data) {

if (data == m1) {

data = 20; // ERROR: 20 is not an e type

}

}

Enumerations are implicitly int. However, we can also specify any integral type as appropriate:

typedef enum t : char {m1, m2, m3, m4} e;

User Avatar

Wiki User

7y ago
This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: What is the purpose of type declarations in c?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Continue Learning about Engineering

What is the purpose of the header file io.h in c plus plus?

The header, io.h, is part of the standard C library and contains declarations for file handling and I/O functions. The file has no practical purpose in C++; it is only included because it was required prior to C++ standardisation. However, it can be used when writing C-style programs and libraries in C++.


How do you position your variable declarations and process statements?

Formally, in C, variable declarations occur first in the block, followed by process statements. In C++, this was relaxed and declarations are permitted within the process statements. This allows somewhat easier code readability, since the declaration is near the use, but the style is yours to choose. Most modern C compilers are also C++ compilers, so the C++ rules often work in C code, though you can set flags to enforce a certain standard, if you wish.


How do you define the definition section of a c program?

C programs don't have a definition section as such. C source files are composed from declarations and definitions, however the only requirement is that all user-defined identifiers be declared before they are used; the definition itself can literally be placed anywhere. However, a definition is itself a declaration so we really only need declarations when a definition is used by two or more source files or where two or more definitions refer to each other (cyclic dependants). Typically, we place declarations in header files which can then be included (via the #include compiler directive) in any source files that require them, thus ensuring all declarations are consistent. By organising declarations by their function we can include all related identifiers with a single #include directive. Declarations that are not actually used don't cost anything because declarations do not generate code. Definitions do generate code, but if the code is not used the only cost is in generating the code because unused code has neither internal or external linkages.


What do you mean by forward declarations in c plus plus?

A forward declaration is simply a declaration of an identifier that will be defined at a later point during compilation. It is quite common to separate declarations from their definitions using header files (.h) and source files (.cpp). The header essentially contains all the forward declarations of all the definitions contained in the source file. It is also common practice to use forward declarations when a header contains pointers to a type, rather than references. If it includes references, then you must include the header file for those references, but if they are pointers then you only need a forward declaration of the type (before it is used) and the actual header that contains the full declaration can be included in the source file instead.


What is the difference between datatypes and modifiers in c language?

For example 'int' is a data-type, 'short', 'long', 'signed' and 'unsigned' are modifiers, 'extern', 'auto', 'static', 'register' are storage-classes. The declarations go like this: storage-class modifiers data-type identifier example: static unsigned short int x;

Related questions

What was the declarations purpose?

they wanted to be free


What is the purpose of the header file io.h in c plus plus?

The header, io.h, is part of the standard C library and contains declarations for file handling and I/O functions. The file has no practical purpose in C++; it is only included because it was required prior to C++ standardisation. However, it can be used when writing C-style programs and libraries in C++.


What is the function of stdlibh in c language?

It contains useful declarations.


What was the purpose of the Potsdam declarations?

It warned the Japanese that if they did not surrender, they would face destruction.


what was the main purpose of the declarations of independence?

To remove the American colonies from British rule .


How do you position your variable declarations and process statements?

Formally, in C, variable declarations occur first in the block, followed by process statements. In C++, this was relaxed and declarations are permitted within the process statements. This allows somewhat easier code readability, since the declaration is near the use, but the style is yours to choose. Most modern C compilers are also C++ compilers, so the C++ rules often work in C code, though you can set flags to enforce a certain standard, if you wish.


What is the header in C programming language?

A haeder is a text-file, meant to include (#include) into a source-file. Usually it contains variable and function declarations, constants, type-definitions, documentation.


What is meant by block statement in c language?

BNF:statements -> | statement statementsstatement -> block | null_statement | expression_statement | if_statement | while_statement | ...null_statement -> ;expression_statement -> expression ;block -> { declarations statements }declarations -> | declaration declarationsif_statement -> if ( expression )statement


What is the use of header files in turbo c?

Header files in Turbo C serve the same purposes they serve in every other implementation of the C programming language. The primary function is to separate interfaces (declarations) from implementations (definitions). This is useful whenever we have interfaces that are common to more than one translation unit. Rather than repeatedly typing out the same declarations over and over, we can simply include the header or headers that contain those declarations. The include statements force the compiler to copy the contents of the named file in place, thus ensuring the declarations are consistent throughout our program.


What is the classifications of credit?

A) according to type of user B) according to purpose C) according to maturity (date) D) according to type of credit


How do you define the definition section of a c program?

C programs don't have a definition section as such. C source files are composed from declarations and definitions, however the only requirement is that all user-defined identifiers be declared before they are used; the definition itself can literally be placed anywhere. However, a definition is itself a declaration so we really only need declarations when a definition is used by two or more source files or where two or more definitions refer to each other (cyclic dependants). Typically, we place declarations in header files which can then be included (via the #include compiler directive) in any source files that require them, thus ensuring all declarations are consistent. By organising declarations by their function we can include all related identifiers with a single #include directive. Declarations that are not actually used don't cost anything because declarations do not generate code. Definitions do generate code, but if the code is not used the only cost is in generating the code because unused code has neither internal or external linkages.


What do you mean by forward declarations in c plus plus?

A forward declaration is simply a declaration of an identifier that will be defined at a later point during compilation. It is quite common to separate declarations from their definitions using header files (.h) and source files (.cpp). The header essentially contains all the forward declarations of all the definitions contained in the source file. It is also common practice to use forward declarations when a header contains pointers to a type, rather than references. If it includes references, then you must include the header file for those references, but if they are pointers then you only need a forward declaration of the type (before it is used) and the actual header that contains the full declaration can be included in the source file instead.