Presentation is loading. Please wait.

Presentation is loading. Please wait.

2/23/2016Course material created by D. Woit 1 CPS 393 Introduction to Unix and C START OF WEEK 9 (C-3)

Similar presentations


Presentation on theme: "2/23/2016Course material created by D. Woit 1 CPS 393 Introduction to Unix and C START OF WEEK 9 (C-3)"— Presentation transcript:

1 2/23/2016Course material created by D. Woit 1 CPS 393 Introduction to Unix and C START OF WEEK 9 (C-3)

2 2/23/2016Course material created by D. Woit 2 Pointers Pointer is a data type which allows storage of location (address) of data rather than data itself. 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"

3 2/23/2016Course 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

4 2/23/2016Course 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); }

5 2/23/2016Course 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

6 2/23/2016Course 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 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

7 2/23/2016Course material created by D. Woit 7 Pointers cont. Wrong usage, see ptrerr.c : char B[] = "bcd"; char *p = B; /*initialize ptr to address of B[0] or...*/ /*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'

8 2/23/2016Course 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++; // }

9 2/23/2016Course 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 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++; }

10 2/23/2016Course material created by D. Woit 10 /*Source highest.c*/ #define ELTS 5 #include 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); }

11 2/23/2016Course 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.

12 2/23/2016Course 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.)

13 2/23/2016Course 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);

14 2/23/2016Course 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?

15 2/23/2016Course 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);

16 2/23/2016Course material created by D. Woit 16 A function may have type "pointer to type" /*Source: sample16.c*/ #include char *addXX(char *S); int main(void) { char str1[25], *str2; gets(str1); str2=addXX(str1); puts(str2); exit(0); } char *addXX(char *S) { strcat(S,"XX"); return (S); } Does str2 have storage allocated? No need. What happens if the user enters a string that is more than 23 chars long?

17 2/23/2016Course 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.

18 2/23/2016Course 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’

19 2/23/2016Course material created by D. Woit 19 Precedence of Array & Ptr operations : Operator Precedence Associativity (see below) () [] ->. left ++ -- sizeof ! ~ (type) + - * & right (ALL ARE UNARY OPERATORS) * / % left + - left (BINARY) > left >= left == != left & left (BINARY) ^ left | left && left || left ?: right = += -= *= /= %= &= ^= |= >= right, left

20 2/23/2016Course 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 ~ 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

21 2/23/2016Course material created by D. Woit 21 Note: **a means *(*a) &(&a) means &a (&&a is invalid) &a[1] means &(a[1]) *a[1] means *(a[1])

22 2/23/2016Course material created by D. Woit 22 Dealing with errors Compile this program with gcc –lm –o sqrt sqrt.c //source sqrt.c #include #define POSITIVE 25 #define NEGATIVE -25

23 2/23/2016Course 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; }

24 If a function sets errno, it is stated in man page. e.g., man scanf then search for errno then search for ERROR


Download ppt "2/23/2016Course material created by D. Woit 1 CPS 393 Introduction to Unix and C START OF WEEK 9 (C-3)"

Similar presentations


Ads by Google