24
05/18/22 Course material created by D. Woit 1 CPS 393 Introduction to Unix and C START OF WEEK 9 (C-3)

KIERAN C WOOT WOOT 2

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 1

CPS 393Introduction to Unix and C

START OF WEEK 9 (C-3)

Page 2: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 2

Pointers • Pointer is a data type which allows storage of location (address) of

data rather than data itself. See example1.c• int main(void) { • int Num;• int *NumPtr;

• Num=5;• NumPtr = &Num;• printf(" %d \n", *NumPtr );• *NumPtr = 7;• printf(" %p %d %d \n", NumPtr, *NumPtr, Num );

• return(0);• } • NumPtr is a "pointer to int" • &Num is the address of variable Num (1200 here)• *NumPtr is the value at address in NumPtr (de-reference NumPtr)• or, what NumPtr "points to"

Page 3: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 3

• After statements Num=5; NumPtr = &Num; memory allocation is;• 1200 1204 1208 ... 1531 - memory addresses

• ------------------------ ---------------• ... | 5 | | | ... |1200 | - memory storage• ------------------------ ----------------• Num NumPtr

• After statement *NumPtr = 7; memory allocation is:

• 1200 1204 1208 ... 1531 - memory addresses

• ------------------------ ---------------• ... | 7 | | | ... |1200 | - memory storage• ------------------------ ----------------• Num NumPtr

Page 4: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 4

Pointers and Arrays • an array name is an address (i.e., a pointer)• i.e. it is address of the 1st item of the array• Code in ptr1.c• int main(void) { • int A[5] = {1,2,3,4,5};• int *p;• p=A;• printf("%d %d %d ", *p, *(p+1), *(p+2) );• putchar('\n');• printf("%d %d %d ", p[0], p[1], p[2] );• putchar('\n');• printf("%p %p %p ", p, p+1, p+2 );• printf("\nsize of int: %d\n",sizeof(int));• return(0);• }

Page 5: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 5

• int A[5] = {1,2,3,4,5};• 100 104 108 112 116 ... 236 ... …. 300• ------------------------ ----- ------ ------• | 1 | 2 | 3 | 4 | 5 |... … | |....... |100|• ------------------------ ----- ----- -------• A[0] A[1] A[2] A[3] A[4] A• int *p;• 100 104 108 112 116 ... 236 ... 300• ---------------------------- -------- -----• | 1 | 2 | 3 | 4 | 5 |... | |... |100|• -------------------------- ---- -----------• A[0] A[1] A[2] A[3] A[4] p A• • p=A;• 100 104 108 112 116 ... 236 ... 300• ----------------------------- ----- ---• | 1 | 2 | 3 | 4 | 5 |... |100|... |100|• ------------------------ ----- ------ -----• A[0] A[1] A[2] A[3] A[4] p A•

Page 6: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 6

• Discussion of previous example in ptr1.c• printf("%d %d %d ", *p, *(p+1), *(p+2) );• putchar('\n');• printf("%d %d %d ", p[0], p[1], p[2] );• putchar('\n');• printf("%p %p %p ", p, p+1, p+2 );

• 1 2 3• 1 2 3• 100 104 108 //assuming above storage placement

• why 104 ? 4 byte ints on our machine--use sizeof(int) to see.• ^ sizeof is a keyword (built-in like "for")• depends on type of p. • if int *p then p+1 is p+4bytes• if char *p then p+1 is p+1byte•

Page 7: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 7

Pointers cont.• Wrong usage , see ptrerr.c :• char B[] = "bcd";• char *p = B; /*wrong initialization ptr to address of B[0] */• /*or: char *p = &B[0]; */• assuming &B[0] is 1000, what is the output of:• printf("%p %p %p ", p, p+1, p+2 ); • SAME THING:• char B[] = "bcd";• char *p;• p=B; /*or p=&B[0]*/• Note p[1] same as B[1] same as *(p+1) i.e., 'c' • p[0] same as B[0] same as *p i.e., 'b'•

Page 8: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 8

• //Source: cptr.c• char S[9]="Pointers";• char *cptr;• cptr=S; # try to omit this line and compile and then run• while ( putchar(*cptr++) ); //putchar returns the char it

printed• //this prints the '\0' but the following• //do not:• // or, more clearly• // while ( *cptr ) putchar(*cptr++);• // or even more clearly• // while ( *cptr != '\0' ) putchar(*cptr++);• // or even more clearly• // while ( *cptr != '\0' ) {• // putchar(*cptr);• // cptr++;• // }

Page 9: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 9

• /*Source: sample12d.c */• /*Input: a string max length 39 */• /*Output: the string in upper case */• /*Purpose: convert string to upper case */• #include <ctype.h>• #include <stdio.h>• int main(void) {• char str[40], *p; • printf("Enter a string: ");• (void) gets(str); • p=&str[0]; /*or p=str */• while ( *p != '\0' ) { /*or while(*p) */• *p++ = toupper(*p);• }• printf("%s\n",str);• exit(0);• }•

Note: the body of the while stmt is exactly same as { *p = toupper(*p); p++; }

Page 10: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 10

• /*Source highest.c*/• #define ELTS 5• #include <stdio.h>• int main(void) {• int i, *high, *p;• int array[ELTS]={200,34,78,600,45};• high=array;• p=array;• for ( i=1; i< ELTS; i++ ) {• p++;• if (*p > *high) high = p;• }• printf("the highest number is %d \n", *high);• printf("at address %p \n", high);• printf("at index %d of array \n", high-array);• exit(0);• }

Page 11: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 11

Pointers and String Constants • when compiler encounters a string constant, it stores it in a string

table and generates a pointer to the string (address)• char *p;• p="A String";• printf(p); • Note that the following is BAD:• char *p;• gets(p);• printf(p);• Why bad?• p has no storage allocated to it. It might "work" sometimes• and not work other times because its storage is overwritten,• or because the value IN p does not point to an accessible• storage location.

Page 12: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 12

Pointers as Parameters • all parameters in C are passed by value• However, we can fake pass by reference by passing the

*address*, and then use * inside function to modify the data• this explains: scanf("%d", &num ); • Example:• int A[20];• A is the address of the array (address of A[0])• Thus, a function call such as • sum(A)• passes the *address*; so any changes to A within sum• are retained (i.e., like call by reference.)

Page 13: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 13

(code in callByRef.c)

• Example for call by reference:

• void add1 (int *x) {• *x = *x + 1 ;• }• ...• int a=5;• add1(&a);• printf("a is %d\n",a);•

Page 14: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 14

• /*Source: sample14.c*/• void swap(int *arg1, int

*arg2);• int main(void) {• int i=0, j=2;• printf("i is %d, j is %d \n",

i,j);• swap(&i,&j);• printf("i is %d, j is %d \n",

i,j);• exit(0);• }•

• /*Function: swap • Purpose: swap values of

2 integers• Input: addresses of the 2

integers to swap• Output: none• */• void swap(int *arg1, int

*arg2 ) {• int temp;• temp = *arg1; • *arg1=*arg2;• *arg2=temp;• }• prints?

Page 15: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 15

• /*Source: sample15.c */• void swap1 (int A[2] );• int main(void) {• int A[2]={1,2};• printf("%d %d \n", A[0],

A[1] );• swap1(A);• printf("%d %d \n", A[0],

A[1] );• exit(0);• }•

• void swap1 (int A[2] ) {• int temp;• temp = A[0];• A[0] = A[1];• A[1] = temp;• }

• These function prototypes are all the same:

• void swap1(int A[2]);• void swap1(int A[]);• void swap1(int *A);

Page 16: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 16

A function may have type "pointer to type"• /*Source: sample16.c*/• /* adds string XX to input string */• #include <stdio.h>• #include <string.h>• char *addXX(char *S);• int main(void) {• char str1[25], *str2;• printf("input a string: ");• gets(str1); • str2=addXX(str1);• puts(str2);• // printf("concatenated string is now

%s\n", str2 );• exit(0);• }

• char *addXX(char *S) {• strcat(S,"XX");• return (S);• }

• Does str2 have storage allocated? No need because all processing is done on string str1.

• The problem may occur if the user enters a string that is more than 23 chars long.

• Why? Because original memory allocation is exceeded.

Page 17: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 17

HMWK• 1. Write a function with prototype: void swap_string1(char

*A, char *B); • The function swaps the strings in A and B. It does this by

looping through the string(s) and swapping individual characters. If your function needs to know the length of a string, it can use strlen from string.h, or it can just look for the '\0' at the string end.

• Write a main program to test swap_string1. Your main must allocate all the storage required for the strings. DO NOT copy junk from memory.

• Only copy characters from the strings.

Page 18: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 18

Multiple Indirection • char **mp, *p, ch;

• 1080 ... 1248 ... 1272

• ----------- ---------- ----------• ... | | ... | | ... | | • ----------- ---------- ----------• mp p ch

• p=&ch; mp=&p; **mp='A'; • 1080 ... 1248 ... 1272 • ----------- ---------- --------------• ... | 1248 | ... | 1272 | ... | A | • ----------- ---------- ---------------• mp p ch

• This is same as simply ch= ‘A’

Page 19: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 19

Precedence of Array & Ptr operations:• Operator Precedence Associativity (see def. below)• () [] -> . Left to right• ++ -- sizeof ! ~ (type) + - * & right (ALL ARE UNARY OPERATORS)

• * / % left to right• + - left (BINARY)• << >> (bitwise left and right shift) left • < <= > >= left • == != left• & (bitwise AND) left • ^ (bitwise XOR) left • | (bitwise OR) left • && left • || left • ?: right ternary operator• = += -= *= /= %= &= ^= |= <<= >>= right• , left

Page 20: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 20

• Associativity means if 2 operators with equal precedence are in an expression, they will be done from left-to-right if left-assoc and from right-to-left if right-assoc

• Operators -> and . are used to access fields of structures• ~ is one's complement (unary)• ! is logical not: if (!x)• ++ -- are unary inc/decrement prefix or postfix: i++ or ++i• unary * unary & are ptr dereference, address of• << >> left bit shift, right bit shift• && || logical and, or• & | ^ bitwise and, or, Xor• ?: ternary operation (for conditional e.g., z = (a>b) ? a : b ;

resolves to: z = a OR z = b , depending on (a>b) i.e the same as z= max(a,b)

Page 21: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 21

• Note:• **a means *(*a)• &(&a) will result in compiler error see sample17.c• (&&a is invalid since && is binary logical AND operator )• &a[1] means &(a[1])• *a[1] means *(a[1])

Page 22: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 22

Dealing with errors

Compile this program with gcc –lm –o sqrt sqrt.c

• //source sqrt.c• #include <stdio.h>• #include <errno.h>• #include <math.h>• #define POSITIVE 25• #define NEGATIVE -25•

Page 23: KIERAN C WOOT WOOT 2

04/10/23 Course material created by D. Woit 23

• int main(void){• double ret;• errno = 0;• ret = sqrt(NEGATIVE);• if (errno == EDOM) /*EDOM Signifies Domain Error*/• //printf("Domain Error : Invalid Input To Function\n");• perror("sqrt");• else • printf("Valid Input To Function\n");

• errno = 0;• ret = sqrt(POSITIVE);• if (errno == EDOM) • printf("Domain Error : Invalid Input To Function\n");• else • printf("Valid Input To Function\n");• return 0;• }

Page 24: KIERAN C WOOT WOOT 2

• If a function sets errno, it is stated in man page. e.g.,• man scanf• then search for errno • then search for ERROR• You can also check man errno