1 / 24

CPS 393 Introduction to Unix and C

CPS 393 Introduction to Unix and C. START OF WEEK 9 (C-3). 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 = &amp; Num; printf(&quot; %d <br>&quot;, * NumPtr ); * NumPtr = 7;

zona
Download Presentation

CPS 393 Introduction to Unix and C

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CPS 393Introduction to Unix and C START OF WEEK 9 (C-3) 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. 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" 8/28/2014 Course material created by D. Woit 2

  3. After statements Num=5; NumPtr = &Num; memory allocation is; 1200 1204 1208 ... 1531 - memory addresses ------------------------ --------------- ... | 5 | | | ... |1200 | - memory storage ------------------------ ---------------- NumNumPtr After statement *NumPtr = 7; memory allocation is: 1200 1204 1208 ... 1531 - memory addresses ------------------------ --------------- ... | 7 | | | ... |1200 | - memory storage ------------------------ ---------------- NumNumPtr 8/28/2014 Course material created by D. Woit 3

  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); } 8/28/2014 Course material created by D. Woit 4

  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] pA 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] pA 8/28/2014 Course material created by D. Woit 5

  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 8/28/2014 Course material created by D. Woit 6

  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/28/2014 Course material created by D. Woit 7

  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++; // } 8/28/2014 Course material created by D. Woit 8

  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++; } 8/28/2014 Course material created by D. Woit 9

  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); } 8/28/2014 Course material created by D. Woit 10

  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. 8/28/2014 Course material created by D. Woit 11

  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.) 8/28/2014 Course material created by D. Woit 12

  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); 8/28/2014 Course material created by D. Woit 13

  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? 8/28/2014 Course material created by D. Woit 14

  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); 8/28/2014 Course material created by D. Woit 15

  16. /*Source: sample16.c*/ #include <stdio.h> #include <string.h> 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? A function may have type "pointer to type" 8/28/2014 Course material created by D. Woit 16

  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. 8/28/2014 Course material created by D. Woit 17

  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’ 8/28/2014 Course material created by D. Woit 18

  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 8/28/2014 Course material created by D. Woit 19

  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 8/28/2014 Course material created by D. Woit 20

  21. Note: **a means *(*a) &(&a) means &a (&&a is invalid) &a[1] means &(a[1]) *a[1] means *(a[1]) 8/28/2014 Course material created by D. Woit 21

  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 8/28/2014 Course material created by D. Woit 22

  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; } 8/28/2014 Course material created by D. Woit 23

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

More Related