Custom Types, String Functions & Storage Classes
struct
struct is a user-defined datatype. It is used to construct complex datatypes from existing ones.
struct Syntax
struct [struct_tag] {
/* member variable 1 */
/* member variable 2 */
/* member variable 3 */
}[struct_variables]; // <-- remember the semicolon
struct_tag- The name for the structure (optional).
You can then define a struct like so:
struct Employee {
char name[50];
int age;
char gender;
float salary;
} employee1, employee2;
Accessing struct Members
To assign a value to a struct member, the member name must be liked with the struct variable using a dot . operator:
#include <stdio.h>
#include <string.h>
struct Lecturer {
char name[50];
char *room[20];
int age;
};
int main() {
struct Lecturer lec;
strcpy(lec.name, "Phil Jimmieson");
*lec.room = "Ashton 1.20";
printf("Name: %s\n", lec.name);
printf("Room: %s\n", *lec.room);
return 0;
}
Be aware that you cannot assign structure arrays in the normal way. Either use strcpy or use pointers.
You can also initialise the struct like so:
struct Lecturer lec = {"Phil Jimmieson", "Ashton 1.20", 69};
This way you don’t have to mess with array types.
Array of struct
You can initialise arrays of structs in the normal way:
struct Lecturer lec[4];
lec[0] = {"Phil Jimmieson", "Ashton 1.20", 69};
Nested struct
struct Student {
char[30] anme;
int age;
struct Address {
char[50] locality;
char[50] city;
int pincode;
} addr;
};
Pointers to struct
#include <stdio.h>
struct point {
int x;
int y;
double dist;
};
void init_point(struct point *p) {
/* Normal Way */
(*p).x = (*p).y = 0;
(*p).dist = 0.0;
/* Syntactic Sugar */
p->x = p->y = 0;
p->dist = 0.0;
}
int main() {
struct point p; // allocate structure
struct point *pt = &p; // allocate pointer to struc
init_point(pt);
printf("x=%d\n", pt->x);
return 0;
}
typedef
typedef allows us to assign alternative names to existing datatypes.
Defining a typedef
The syntax takes the following form:
typedef <existing_name> <alias_name>
For example, we can use this to shorten double-barrelled types:
typedef unsigned long ulong;
We can also use this in conjunction with struct to define new types:
typedef struct { // no name is used
int x;
int y;
double dist;
} Point, *pointPtr;
From this we now have:
- A new datatype called
Point. - A new type of pointer to the custom type called
pointPtr.
We can also use it to give an alias for pointers to a type:
typedef int* IntPtr;
IntPtr x, y, z;
union
union is a special datatype allowing us to store different datatypes in the same physical memory location. A union can have many members by only one member can contain a value at any given time.
union Syntax
The syntax of union is very similar to struct:
union Example {
int i;
float f;
char str[20];
} e;
The difference is that the memory allocated for union is based on the largest type that it can store, instead of the sum of the type sizes.
Accessing union Members
This is very similar to assessing struct members:
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
data.i = 66;
data.f = 99.9;
strcpy(data.str, "comp281");
/* only data.str will print correctly */
printf("data.i:\t%d\n", data.i);
printf("data.f:\t%d\n", data.f);
printf("data.str:\t%d\n", data.str);
return 0;
The difference is that writing to additional members will overwrite previous ones.
Strings
There is no specific datatype for strings, they are just arrays of char terminated by \0 (NUL).
You should be aware of the extra NUL character when calculating the length of strings.
String Functions
strcat()
For concatenating two strings:
char *strcat(char *s1, const char *s2);
Parameters:
s1- A pointer to a string that will be modified.s2- A pointer to a string that will be appended to the end ofs1.
Returns:
- A pointer to
s1(where the resulting string resides).
strcpy()
For copying one string into another:
char *strcpy(char *dest, const char *src);
Parameters:
dest- The pointer to the destinationchararray where the content is to be copied.src- The string to be copied.
Returns:
- A pointer to the destination string.
strlen()
Returns the length of a string:
size_t strlen(const char *s);
Parameters:
s- The string whose length is to be found.
Returns:
-
The length of the string pointed to by
s.This does not include the
NULcharacter in the length calculation.
strcmp()
For comparing two strings:
int strcmp(const char *str1, const char *str2);
Parameters:
str1- The first string to be compared.str2- The second string to be compared.
Returns:
- $0$ - If
s1ands2are the same. - $<0$ - If
s1<s2. - $>0$ - If
s1>s2.
strchr()
For searching for the first occurrence of a character:
char *strchr(const char *str, int c);
Parameters:
str- The string to be searched in.c- The character to be searched for.
Returns:
- A pointer to the first occurrence of the character
cin the stringstr. NULLif the character is not found.
Storage Classes
Each variable has a storage class which decides the scope, default initial value and lifetime. The following storage classes are mostly used:
Automatic Variables
- Scope - Local to the function block when they are defined.
- Default Initial Value - Garbage.
- Lifetime - Till the end of the function where they are defined.
They can be used in the following two ways:
int detail;
auto int details;
If you have no specific need, use this type of variable.
External (Global) Variables
- Scope - Not bound by any function; available everywhere.
- Default Initial Value - 0 (Zero)
- Lifetime - Until the program finishes executing.
Global values can be changed by any function in the program and are declared outside of the scope of any functions:
#include <stdio.h>
int meaningOfLife = 42;
int main() {
printf("The meaning of life, the universe and everything is: %d.\n", meaningOfLife);
}
extern
If we want to include global variables from included files then we need to use the extern keyword:
#include <stdio.h>
#include "file.c"
int main() {
extern int a;
printf("%d", a);
return 0;
}
Static Variables
This tells the compiler to persist the variable until the end of the program:
- Scope - Local to the block in which the variable is defined.
- Default Initial Value - 0 (Zero)
- Lifetime - Until the program finished executing.
Instead of creating and destroying a variable every time is goes in and out of scope, a static variable is initialised only once.
This is not the same as a constant.
The following program:
#include <stdio.h>
void test();
int main() {
test();
test();
test();
return 0;
}
void test() {
static int a = 0;
a++;
printf("%d\t", a);
}
will product the following output:
1 2 3
Register Variables
Tells the compiler to store the variable in a CPU register:
- Scope - Local to the function in which it is declared.
- Default Initial Value - Garbage
- Lifetime - Until the end of the function in which the variable is defined.
We can use them like so:
register int number
We cannot get the address of register variables.