0% found this document useful (0 votes)
24 views

Array and Pointers

Arrays in C store homogeneous elements of the same type, use pointers to represent the base address of the array, and allow accessing elements through indexes or pointer arithmetic on the base address; pointers can point to memory addresses or other pointers, and are commonly used to pass arrays to functions by reference in C.

Uploaded by

TANISHQ KALE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views

Array and Pointers

Arrays in C store homogeneous elements of the same type, use pointers to represent the base address of the array, and allow accessing elements through indexes or pointer arithmetic on the base address; pointers can point to memory addresses or other pointers, and are commonly used to pass arrays to functions by reference in C.

Uploaded by

TANISHQ KALE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Arrays and Pointers in C

Arrays in C

All elements of same type – homogenous

Unlike Java, array size in declaration

int array[10]; Compare: C: int array[10];


int b; Java: int[] array = new int[10];

First element (index 0)


array[0] = 3; Last element (index size - 1)
array[9] = 4;
array[10] = 5;
array[-1] = 6;

No bounds checking!
Allowed – usually causes no obvious error
array[10] may overwrite b
Array Representation
Homogeneous ® Each element same size – s bytes
w An array of m data values is a sequence of m´s bytes
w Indexing: 0th value at byte s´0, 1st value at byte s´1, …

m and s are not part of representation


w Unlike in some other languages
w s known by compiler – usually irrelevant to programmer
w m often known by compiler – if not, must be saved by
programmer

0x1008 a[2]
0x1004 a[1] int a[3];
0x1000 a[0]
Array Representation
char c1;
int a[3];
char c2;
int i;

0x1014 i
0x1010 c2

0x100C a[2]
Could be optimized by
a[1] making these adjacent,
0x1008 and reducing padding
a[0] (by default, not)
0x1004

0x1000 c1
Array aligned by
size of elements
Array Sizes

int array[10];

What is

sizeof(array[3])? 4
returns the size of
an object in bytes
sizeof(array)? 40
Multi-Dimensional Arrays

0x1014 matrix[1][2]
0x1010 matrix[1][1]
int matrix[2][3];
0x100C matrix[1][0]

matrix[1][0] = 17; 0x1008 matrix[0][2]


0x1004 matrix[0][1]
0x1000 matrix[0][0]
Recall: no bounds checking

What happens when you write: “Row Major”


Organization

matrix[0][3] = 42;
Variable-Length Arrays

int
function(int n)
{
int array[n];

Variable-length arrays
defined within functions

Global arrays must still have fixed (constant) length


Memory Addresses

Storage cells are typically viewed as being


byte-sized
w Usually the smallest addressable unit of memory
• Few machines can directly address bits individually
w Such addresses are sometimes called byte-
addresses
Memory is often accessed as words
w Usually a word is the largest unit of memory access
by a single machine instruction
• CLEAR’s word size is 8 bytes (= sizeof(long))
w A word-address is simply the byte-address of the
word’s first byte
Pointers

Special case of bounded-size natural numbers


w Maximum memory limited by processor word-size
w 232 bytes = 4GB, 264 bytes = 16 exabytes

A pointer is just another kind of value


w A basic type in C

int *ptr;

The variable “ptr” stores a pointer to an “int”.


Pointer Operations in C

Creation
& variable Returns variable’s memory address
Dereference
* pointer Returns contents stored at address
Indirect assignment
* pointer = val Stores value at address

Of course, still have...

Assignment
pointer = ptr Stores pointer in another variable
Using Pointers

int i1;
int i2;
int *ptr1; 0x1014 … 0x1000
int *ptr2;
0x1010 ptr2:
i1 = 1; 0x100C … 0x1000
i2 = 2;
0x1008 ptr1:

ptr1 = &i1; 0x1004 i2: 2


3
ptr2 = ptr1; 0x1000 i1: 3
1

*ptr1 = 3;
i2 = *ptr2;
Using Pointers (cont.)
int int1 = 1036; /* some data to point to */
int int2 = 8;

int *int_ptr1 = &int1; /* get addresses of data */


int *int_ptr2 = &int2;

*int_ptr1 = int_ptr2;

*int_ptr1 = int2;

What happens?

Type check warning: int_ptr2 is not an int

int1 becomes 8
Using Pointers (cont.)
int int1 = 1036; /* some data to point to */
int int2 = 8;

int *int_ptr1 = &int1; /* get addresses of data */


int *int_ptr2 = &int2;

int_ptr1 = *int_ptr2;

int_ptr1 = int_ptr2;

What happens?

Type check warning: *int_ptr2 is not an int *

Changes int_ptr1 – doesn’t change int1


Pointer Arithmetic
pointer + number pointer – number

E.g., pointer + 1 adds 1 something to a pointer

char *p; int *p;


char a; int a;
char b; int b;

p = &a; p = &a;
p += 1; In each, p now points to b p += 1;
(Assuming compiler doesn’t
reorder variables in memory)

Adds 1*sizeof(char) to Adds 1*sizeof(int) to


the memory address the memory address

Pointer arithmetic should be used cautiously


A Special Pointer in C

Special constant pointer NULL


w Points to no data
w Dereferencing illegal – causes segmentation fault

w To define, include <stdlib.h> or <stdio.h>


Generic Pointers

void *: a “pointer to anything”


type cast: tells the compiler to
void *p; “change” an object’s type (for type
int i; checking purposes – does not modify
char c; the object in any way)
p = &i;
p = &c; Dangerous! Sometimes necessary…
putchar(*(char *)p);

Lose all information about what type of thing


is pointed to
w Reduces effectiveness of compiler’s type-checking
w Can’t use pointer arithmetic

Cox Arrays and Pointers 16


Pass-by-Reference

void
set_x_and_y(int *x, int *y)
{

*x = 1001;
*y = 1002; a 1001
1
}
b 1002
2
void
f(void)
{ x
int a = 1;
int b = 2; y

set_x_and_y(&a, &b);
}
Arrays and Pointers
Dirty “secret”: Passing arrays:
Array name » a pointer to the Must explicitly
Really int *array pass the size
initial (0th) array element
int
foo(int array[],
a[i] º *(a + i) unsigned int size)
{
An array is passed to a function … array[size - 1] …
as a pointer }
w The array size is lost!
int
main(void)
Usually bad style to interchange {
arrays and pointers int a[10], b[5];
w Avoid pointer arithmetic! … foo(a, 10)… foo(b, 5) …
}
Arrays and Pointers
int
foo(int array[],
unsigned int size)
{
… What does this print? 8
printf(“%d\n”, sizeof(array));
}
... because array is really
a pointer
int
main(void)
{
int a[10], b[5];
… foo(a, 10)… foo(b, 5) … What does this print? 40
printf(“%d\n”, sizeof(a));
}
Arrays and Pointers

int i; int *p;


int array[10]; int array[10];

for (i = 0; i < 10; i++) { for (p = array; p < &array[10]; p++) {


… …
array[i] = …; *p = …;
… …
} }

These two blocks of code are functionally equivalent


Strings

In C, strings are just an array of characters


w Terminated with ‘\0’ character
w Arrays for bounded-length strings
w Pointer for constant strings (or unknown length)

char str1[15] = “Hello, world!\n”;


char *str2 = “Hello, world!\n”;

C, … H e l l o , w o r l d ! \n terminator

C terminator: ’\0’

Pascal, Java, … length H e l l o , w o r l d ! \n


String length

Must calculate length:


can pass an
int array or pointer
strlen(char str[])
{
array access int len = 0; Check for
to pointer! terminator

while (str[len] != ‘\0’)


len++;
What is the size
of the array???
return (len);
}
Provided by standard C library: #include <string.h>
Pointer to Pointer (char **argv)

Passing arguments to main:


size of the argv array/vector
int
main(int argc, char **argv)
{ an array/vector of
char *
...
} Recall when passing an
array, a pointer to the
first element is passed
Suppose you run the program this way

UNIX% ./program hello 1 2 3

argc == 5 (five strings on the


command line)
char **argv

“ 3”

0x1020 argv[4] These are strings!!


“ 2”
0x1018 argv[3] Not integers!
0x1010 argv[2] “ 1”
0x1008 argv[1] “hello”
0x1000 argv[0]
“./program”

You might also like