Loop in a Linked List
Tuesday, November 11th, 2008A very good explanation on how to detect a loop in a linked list given here: http://gurmeetsingh.wordpress.com/2008/09/12/puzzle-loop-in-a-linked-list/#comment-430
A very good explanation on how to detect a loop in a linked list given here: http://gurmeetsingh.wordpress.com/2008/09/12/puzzle-loop-in-a-linked-list/#comment-430
Why does the following construct result in an error?
struct {
int i;
char j;
long k;
}b;
&b.k - &b; /* Compile error */
Section A6.6, Pointers and Integers, of K&R-II says:
Manjunath Warad sent this program.
int main()
{
int a[5]={0,1,2,3,4,5};
unsigned int b = 0xffffffff;
a[b] = 30;
printf(”%d\n”, a[-1]);
a[-1] = 50;
printf(”%d\n”, a[-1]);
return EXIT_SUCCESS;
}
Here though b is declared as unsigned int type, and while it is used as index, it is taken as a signed integer. The value of b is therefore -1.
Broadly speaking, there are only three operations that can be applied on an object of an array type! They are summarized as follows:
sizeof operatorAll other operations are usually a combination of these. Starting with this post, we will see each operation on array in some detail.
The sizeof operator yields the size of its operand in bytes. The operand is one of: an expression or the parenthesized name of a type. So, when applied to an operand that has the array type, the result is the total number of bytes in the array.
The following fragment of code finds the size of the array:
{
int a[10];
size_t size = sizeof a; /* the size is 10 * sizeof(int), */
/* which, in our case is 40 bytes.*/
}
Consider another example in which a function named apple() takes a parameter declared to have array type.
void
apple ( int seeds[6] )
{
size_t size;
/* … */
size = sizeof seeds; /* the size is sizeof(int*). */
}
In future post, we will see that an array variable decays into pointer to its first element, except under some situations as described later. So, when applied to a parameter declared to have array type, the sizeof operator yields the size of the pointer type; pointer to int in the above example.
Another use of the sizeof operator is to compute the number of elements in an array. The following expression finds that:
sizeof array / sizeof array[0]
Pointers and arrays are inseparably related, but they are not synonyms for each other. Starting with this post, we will look into one-dimensional array, it’s storage pattern, how the array elements are accessed. And lastly, we look into a new feature of C99: the variable length array.
An array is a nonempty set of sequentially indexed elements having the same type of data. Each element of an array has a unique identifying index number. Changes made to one element of an array do not affect the other elements.
In C, the declaration
int a[10];
defines an array of size 10, each of which is an integer object. These objects — named a[0], a[1], …, a[9] — appear contiguously in the storage area; that is, there is no padding between the array members.
An array type is called as an aggregate type since it is considered to be derived from its element type. If the element type is T, then the array type is called as “array of T”. For example, in the above declaration element type of a is integer, so the array a is called as “array of integers”.
An array must not be declared/defined with the register storage class specifier; doing so is an undefined-behavior.
You might have noticed that in C, the rightmost subscript of a two-dimensional array varies faster than the leftmost (in fact, there are no multidimensional arrays in C, but array of arrays). This fact suggests that the array is stored in a row major addressing format. However, for a one-dimensional array the case is the simplest: The array occupies a contiguous block of memory. The array -
int a[10];
- is laid out in memory as a contiguous block, as shown below:

Elements of array are stored in the successive increasing locations of memory. For example, if the array starts at memory location 0×1000, then with our assumed size of an integer (4 bytes), the first element is stored at location 0×1000, the second element at location 0×1004, and so on.
A pointer to void, void*, is a generic pointer. A generic pointer is capable of pointing to any object (except for bit-fields, objects declared with the register storage class and functions). A normal pointer can be converted to a generic pointer and vice versa, without the loss of information.
Functions using generic pointers implement common utility for almost all objects of various types. One such function is the standard memcmp() function which compares the objects pointed by s1 and s2, in the below declaration, for equality. Its prototype is:
#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
Internally, it casts s1 and s2 to pointers to character (signed or unsigned), and compares character-by-character till either of the following conditions occurs:
n character pointed by internal character pointers have been compared to be equal; returns with 0A pointer to void - that is, void* - is a generic pointer. A generic pointer is capable of pointing to any object (except for bit-fields, functions, and objects declared with the register storage class). A normal pointer can be converted to a generic pointer and vice versa, without the loss of information.
Functions using generic pointers implement common utility for almost all objects of various types. One such function is the standard memcmp() function which compares the objects pointed by s1 and s2, in the below declaration, for equality. Its prototype is:
#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
Internally, it casts s1 and s2 to pointers to character (signed or unsigned), and compares character-by-character till either of the following conditions occurs:
n character pointed by internal character pointers have been compared to be equal; returns with 0The foundational attribute of an object is decided by its data type. Additional attributes, if any, are influenced by the object’s type specifier (signed or unsigned), type qualifier (const, volatile and/or restrict) and storage class (auto, register, extern, or static).
The singularity of a parameter can be broadened by:
signed or unsigned. This attribute affects the range of values that an object can haveregister storage class indicating that the compiler, if possible, should place the parameter in a register for fast access. Usages of static storage class will be discussed in coming postsIn the tomorrow’s post, we will discuss about using const qualifier usage in parameters.
——–
At times, the called function is required to modify one or more parameters so that they can reflect in the calling function. In such situations, we use pointers; that is, we pass pointer to the object whose value requires to be changed. However, keep in mind that the pointer itself is passed by value! Only the object pointed by the pointer can be changed. Any change to the pointer is not reflected in the calling function.
Pointers are an interesting concept which can become fun when understood, or can become nervy for the programmer if ill-understood. However, there are different schema or styles of using pointer parameters depending upon the intent of usage. Starting from this post, we will see how pointers can be used in various ways in a function call.
Following subsections spell out pointer usage.
In yesterday’s post, What is a Pointer, we discussed pointer semantics. Here, in this post, we discuss the simplest usage of pointer as a function parameter.
In its basic or simplest form, a pointer parameter has the following template:
return_type function_name ( type *ptr );
and, has following usage pattern:
return_type
function_name ( type *ptr )
{
type var;
type *new_ptr;
new_ptr = ...; /* make new_ptr to point to valid type and location */
var = ...; /* compute `var' */
*ptr = var; /* let the calling-function know the value of `var' */
ptr = new_ptr; /* allowed, but not reflected; this usage is discouraged */
/*
* depending on the type of `return_type', return
* a value of appropriate type
*/
}
This pattern is generally used to
The parameters can also be attributed by the `register’ storage class to notify to use.
____
If you like these posts, help me by spreading a word. Ask your friends to join C FAQs by subscribing to these posts.