Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ExamQuestions_1.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
265.73 Кб
Скачать

Example

Character Pointer

Sample Code

  1. #include <stdio.h>

  2. int main()

  3. {

  4. char a='b';

  5. char *ptr;

  6. printf("%cn",a);

  7. ptr=&a;

  8. printf("%pn",ptr);

  9. *ptr='d';

  10. printf("%cn",a);                                                   

  11. return 0;

  12. }

Copyright exforsys.com

Description of code: In line 1 we are declaring char variable called a; it is initialized to character ‘b’, in line 2, the pointer variable ptr is declared. In line 4, the address of variable a is assigned to variable ptr. In line 6 value stored at the memory address that ptr points to is changed to ‘d’

Note: & notation means address-of operand in this case &a means ‘address-of a’.

Address operator

Address operator (&) is used to get the address of the operand. For example if variable x is stored at location 100 of memory; &x will return 100.

This operator is used to assign value to the pointer variable. It is important to remember that you MUST NOT use this operator for arrays, no matter what data type the array is holding. This is because array identifier (name) is pointer variable itself. When we call for ArrayA[2]; ‘ArrayA’ returns the address of first item in that array so ArrayA[2] is the same as saying ArrayA+=2; and will return the third item in that array.

Pointer arithmetic

Pointers can be added and subtracted. However pointer arithmetic is quite meaningless unless performed on arrays. Addition and subtraction are mainly for moving forward and backward in an array.

Note: you have to be very careful NOT to exceed the array elements when you use arithmetic; otherwise you will get horrible errors such as “access violation”. This error is caused because your code is trying to access a memory location which is registered to another program.

Array and pointer arithmetic

Sample Code

  1. #include <stdio.h>

  2. int main()

  3. {

  4. int ArrayA[3]={1,2,3};

  5. int *ptr;

  6. ptr=ArrayA;

  7. printf("address: %p - array value:%d n",ptr,*ptr);

  8. ptr++;

  9. printf("address: %p - array value:%d n",ptr,*ptr);                                

  10. return 0;

  11. }

Copyright exforsys.com

25.Pointers: Passing pointers to a function

Pointers can be used with functions. The main use of pointers is ‘call by reference’ functions. Call by reference function is a type of function that has pointer/s (reference) as parameters to that function. All calculation of that function will be directly performed on referred variables.

Sample Code

  1. #include <stdio.h>

  2. void DoubleIt(int *num)

  3. {

  4.         *num*=2; 

  5. }

  6. int main()

  7.         int number=2; 

  8.                 DoubleIt(&number);

  9.                         printf("%d",number);

  10. return 0; 

  11. }

  1. Pointers and Arrays

Up to now, we've carefully been avoiding discussing arrays in the context of pointers. The interaction of pointers and arrays can be confusing but here are two fundamental statements about it:

  • A variable declared as an array of some type acts as a pointer to that type. When used by itself, it points to the first element of the array.

  • A pointer can be indexed like an array name.

The first case often is seen to occur when an array is passed as an argument to a function. The function declares the parameter as a pointer, but the actual argument may be the name of an array. The second case often occurs when accessing dynamically allocated memory. Let's look at examples of each. In the following code, the call to calloc() effectively allocates an array of struct MyStruct items.

Pointers and array names can pretty much be used interchangeably. There are exceptions. You cannot assign a new pointer value to an array name. The array name will always point to the first element of the array. In the function KrazyFunction above, you could however assign a new value to parm1, as it is just a pointer to the first element of myArray. It is also valid for a function to return a pointer to one of the array elements from an array passed as an argument to a function. A function should never return a pointer to a local variable, even though the compiler will probably not complain.

When declaring parameters to functions, declaring an array variable without a size is equivalent to declaring a pointer. Often this is done to emphasize the fact that the pointer variable will be used in a manner equivalent to an array.

Now we're ready to discuss pointer arithmetic. You can add and subtract integer values to/from pointers. If myArray is declared to be some type of array, the expression *(myArray+j), where j is an integer, is equivalent to myArray[j]. So for instance in the above example where we had the expression secondArray[i].num2, we could have written that as *(secondArray+i).num2or more simply (secondArray+i)->num2.

Note that for addition and subtraction of integers and pointers, the value of the pointer is not adjusted by the integer amount, but is adjusted by the amount multiplied by the size (in bytes) of the type to which the pointer refers. One pointer may also be subtracted from another, provided they point to elements of the same array (or the position just beyond the end of the array). If you have a pointer that points to an element of an array, the index of the element is the result when the array name is subtracted from the pointer.

  1. Structures:Defining and processin

A structure is a collection of variables referenced under one name, providing a convenient means of keeping related information together. A structure declaration forms a template that may be used to create structure objects (that is, instances of a structure). The variables that make up the structure are called members. (Structure members are also commonly referred to as elements or fields). Generally, all of the members of a structure are logically related. For example, the name and address information in a mailing list would normally be represented in a structure. The following code fragment shows how to declare a structure that defines the name and address fields. The keyword struct tells the compiler that a structure is being declared.

struct addr { char name[30]; char street[40]; char city[20]; char state[3]; unsigned long int zip; };

Notice that the declaration is terminated by a semicolon. This is because a structure declaration is a statement. The type name of the structure is addr. As such, addr identifies this particular data structure and is its type specifier. At this point, no variable has actually been created. Only the form of the data has been defined. When you define a structure, you are defining a compound variable type, not a variable. Not until you declare a variable of that type does one actually exist. In C, to declare a variable (i.e., a physical object) of type addr, write struct addr addr_info; This declares a variable of type addr called addr_info

  1. Typedef statement

A typedef declaration is a declaration with typedef as the storage class. The declarator becomes a new type. You can use typedef declarations to construct shorter or more meaningful names for types already defined by C or for types that you have declared. Typedef names allow you to encapsulate implementation details that may change.

A typedef declaration is interpreted in the same way as a variable or function declaration, but the identifier, instead of assuming the type specified by the declaration, becomes a synonym for the type.

Syntax

declaration:

declaration-specifiers init-declarator-list opt ;

declaration-specifiers:

storage-class-specifier declaration-specifiers opt

type-specifier declaration-specifiers opt

type-qualifier declaration-specifiers opt

storage-class-specifier:

typedef

type-specifier:

void

char

short

int

long

float

double

signed

unsigned

struct-or-union-specifier

enum-specifier

typedef-name

typedef-name:

identifier

Note that a typedef declaration does not create types. It creates synonyms for existing types, or names for types that could be specified in other ways. When a typedef name is used as a type specifier, it can be combined with certain type specifiers, but not others. Acceptable modifiers include const and volatile.

typedef struct club

{

char name[30];

int size, year;

} GROUP;

  1. File structures: Definitions, file operations

A file may be defined as a collection of records. Though, a text file doesn’t conform

to this definition at the first glance, it is also a collection of records and records are

words in the file.

A file should always be stored in such a way that the basic operations on it can be

performed easily. In other words, queries should be able to be executed with out much

hassle. We focus, in this unit, on the ways of storing the files on external storage

devices. Selection of a particular way of storing the file on the device depends on

factors such as retrieval records, the way the queries can be put on the file, the total

number of keys in each record etc.

File Operations: These deal with the physical movement of data, in and out of

files. User programs effectively use file operations through appropriate

programming language syntax The File Management System manages the

independent files and acts as the software interface between the user programs

and the file operations.

1 Structure

To provide the ‘sequence’ required, a ‘key’ must be defined for the data records.

Usually a field whose values can uniquely identify data records is selected as the key.

If a single field cannot fulfil this criterion, then a combination of fields can serve as

the key.

12.4.2 Operations

1. Insertion: Records must be inserted at the place dictated by the sequence of

the keys. As is obvious, direct insertions into the main data file would lead to 34

File Structures

and Advanced

Data Structures

frequent rebuilding of the file. This problem could be mitigated by reserving’

overflow areas’ in the file for insertions. But, this leads to wastage of space.

The common method is to use transaction logging. This works as follows:

• It collects records for insertion in a transaction file in their order of their arrival.

• When population of the transactions file has ceased, sort the transaction file in

the order of the key of the primary data file

• Merge the two files on the basis of the key to get a new copy of the primary

sequential file.

Such insertions are usually done in a batch mode when the activity/program which

populates the transaction file have ceased. The structure of the transaction files

records will be identical to that of the primary file.

2. Deletion: Deletion is the reverse process of insertion. The space occupied by

the record should be freed for use. Usually deletion (like-insertion) is not done

immediately. The concerned record is written to a transaction file. At the time

of merging, the corresponding data record will be dropped from the primary

data file.

3. Updation: Updation is a combination of insertion and deletions. The record

with the new values is inserted and the earlier version deleted. This is also

done using transaction files.

4. Retrieval: User programs will often retrieve data for viewing prior to making

decisions. Therefore, it is vital that this data reflects the latest state of the data,

if the merging activity has not yet taken place.

Retrieval is usually done for a particular value of the key field. Before return in to the

user, the data record should be merged with the transaction record (if any) for that key

value.

The other two operations ‘creation’ and ‘deletion’ of files are achieved by simple

programming language statements.

  1. Dynamic Memory Allocation

C dynamic memory allocation refers to performing dynamic memory allocation in the C programming language via a group of functions in the C standard library, namely malloc, realloc, calloc and free.

  • malloc: a memory allocator

  • calloc: a memory allocator

  • realloc: memory reallocator

  • free: frees the memory space pointed to by ptr

  • The C programming language manages memory statically, automatically, or dynamically. Static-duration variables are allocated in main memory, usually along with the executable code of the program, and persist for the lifetime of the program; automatic-duration variables are allocated on the stack and come and go as functions are called and return. For static-duration and automatic-duration variables, the size of the allocation is required to be compile-time constant (before C99, which allows variable-length automatic arrays[5]). If the required size is not known until run-time (for example, if data of arbitrary size is being read from the user or from a disk file), then using fixed-size data objects is inadequate.

  • The lifetime of allocated memory is also a concern. Neither static- nor automatic-duration memory is adequate for all situations. Automatic-allocated data cannot persist across multiple function calls, while static data persists for the life of the program whether it is needed or not. In many situations the programmer requires greater flexibility in managing the lifetime of allocated memory.

  • These limitations are avoided by using dynamic memory allocation in which memory is more explicitly (but more flexibly) managed, typically, by allocating it from the heap, an area of memory structured for this purpose. In C, the library function malloc is used to allocate a block of memory on the heap. The program accesses this block of memory via apointer that malloc returns. When the memory is no longer needed, the pointer is passed to free which deallocates the memory so that it can be used for other purposes.

There are 2 differences between these functions. First, malloc() takes a single argument (the amount of memory to allocate in bytes), while calloc() needs 2 arguments (the number of variables to allocate in memory, and the size in bytes of a single variable). Secondly, malloc() does not initialize the memory allocated, while calloc() initializes the allocated memory to ZERO.

The standard method of creating an array of 10 int objects:

int array[10];

However, if one wishes to allocate a similar array dynamically, the following code could be used:

malloc returns a null pointer to indicate that no memory is available, or that some other error occurred which prevented memory being allocated.

malloc returns a void pointer (void *), which indicates that it is a pointer to a region of unknown data type. The use of casting is only required in C++ due to the strong type system, whereas this is not the case in C. The lack of a specific pointer type returned from malloc is type-unsafe behaviour according to some programmers: malloc allocates based on byte count but not on type. This is different from the C++ new operator that returns a pointer whose type relies on the operand. (see C Type Safety).

One may "cast" (see type conversion) this pointer to a specific type:

int *ptr;

ptr = malloc(10 * sizeof (*ptr)); /* without a cast */

ptr = (int *)malloc(10 * sizeof (*ptr)); /* with a cast */

There are advantages and disadvantages to performing such a cast.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]