----------------------------------------------- Pointers and Arrays 1. int a[10]; declares an array of size 10 (20 consecutive objects names a[0], a[1], ..., a[9]. 2. int *pa; pa = &a[0]; pa is a pointer to a[0] so x = *pa; is equivalent to x = a[0]; 3. if pa points to element i (pa = &a[i];), then pa+1 points to a[i+1], pa-1 points to a[i-1] and pa+j points to a[i+j]. 4. if pa = &a[0], *(pa+1) refers to a[1], pa+1 is the address of a[i], and *(pa+i) is the contents of a[i]. 5. The value of an array variable is the address of element zero of the array. If pa = &a[0], pa and a have identical values. 6. The assignment pa= &a[0]; is equivalent to pa = a; 7. A reference to a[i] can be replace with *(a+i) (which is what the c compiler actually does). 8. Since a[i] is identical to *(a+i), &a[i] and &*(a+i) = a+i are identical. 9. Similarly, pa[i] is idential to *(pa+i). 10. A pointer like pa is a variable so pa=a and pa++ are legal 11. An array name like a is not a variable, so a = pa and a++ are illegal. (An array name is an address constant just as 1234 is an integer constant.) 12. Can pass part of an array to a function (f(&a[2]) or f(a+2)) in function, f(int arr[]) or f(int *arr), arr is "shorter" array. 13. Pointer arithmetic 1. If pointers p and q point to members of the same array, then p==q, p!=q, pq, p>=q are legal. 2. In (1) above, if p < q, q-p+1 is the number of elements from p to q. 3. If p an q are pointers to the same type, p = q; is legal. 4. p=NULL, p==NULL, and p!=NULL are legal (#define NULL 0) 5. All other pointer arithmetic is illegal. 14. Note differences 1. char amessage[] = "now is the time"; /* an array, 16 bytes */ 2. char *pmessage = "now is the time"; /* pointer, 4 bytes */ 3. amessage[1]= 'X'; legal, *pmessage+1 = 'X'; illegal. 4. amessage = "abc"; illegal, pmessage = "abc"; legal. 15. More examples assuming p is a pointer 1. thing = *--p; /* decrement p, then fetch thing p points to */ 2. thing = --*p; /* fetch thing p points to, then decrement */ 2. *p++ = val ; /* push val onto stack */ 3. val = *--p; /* pop top of stack into val */ 15. pointers to pointers - sorting character strings +---------+ | o----+-------> abc\n +---------+ | o----+-------> defghi\n +---------+ | o----+-------> jklmnopqr\n +---------+ +---------+ | o----+--\ /--> abc\n +---------+ X | o----+--/ \--> defghi\n +---------+ | o----+-------> jklmnopqr\n +---------+ 16. int a[10][20]; vs int *b[10]; 1. Both a[3][4] and b[3][4] are references to a single int. 2. If int's are 4 bytes, int a[10][20] reserves 800 bytes. 3. If addresses are 4 bytes, *b[10] reserves 40 bytes. If 10 arrays of 20 int's are reserved, 840 bytes total. 4. *b[10] allows the rows to have different sizes. char *name[] = {"a", "ab", "abc"}; /* 2+3+4+3*4= 21 bytes */ char aname[][4] = {"a", "ab", "abc"}; /* 3*4 = 12 bytes */ 17. Command "grep addresses arrays.txt" int main(int argc, char *argv[]) {...} argv: +---------+ +---------+ | o----+-----> | o----+-------> grep\0 +---------+ +---------+ | o----+-------> addresses\0 +---------+ | o----+-------> arrays.txt\0 +---------+ | 0 + +---------+ 18. pargs1.c CIS-Linux2:~/nov09>cat pargs1.c #include /* echo command-line argments; 1st version */ main (int argc, char *argv[]) { int i; for (i = 0; i < argc; i++) printf("%s%s", argv[i], (i < argc-1) ? " " : ""); printf("\n"); return 0; } CIS-Linux2:~/nov09>pargs1 aa bbb cccc pargs1 aa bbb cccc CIS-Linux2:~/nov09> 19. pargs2.c CIS-Linux2:~/nov09>pargs1 aa bbb cccc pargs1 aa bbb cccc CIS-Linux2:~/nov09>cat pargs2.c #include /* echo command-line argments; 2nd version */ main (int argc, char *argv[]) { while (-- argc >= 0) printf("%s%s", *argv++, (argc>0) ? " " : ""); printf("\n"); return 0; } CIS-Linux2:~/nov09>pargs2 aa bbb cccc pargs2 aa bbb cccc CIS-Linux2:~/nov09> 20. pargs3.c CIS-Linux2:~/nov09>cat pargs3.c #include /* echo command-line argments; 3rd version */ /* also print the unix environment */ main (int argc, char *argv[], char *envp[]) { while (-- argc > 0) printf("%s%s", *++argv, (argc>1) ? " " : ""); printf("\n"); while (*envp != NULL) printf("%s\n", *envp++); return 0; } CIS-Linux2:~/nov09>pargs3 aaaa bbbbbbbb ccccccccccccccccccccccc aaaa bbbbbbbb ccccccccccccccccccccccc USER=stafford LOGNAME=stafford HOME=/home/TU/stafford PATH=/home/TU/stafford:/home/TU/stafford/bin:/usr/lib64/qt-3.3/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/X11R6/bin:/usr/local/bin:/usr/bin:. MAIL=/var/spool/mail/stafford SHELL=/bin/tcsh SSH_CLIENT=155.247.182.146 3528 22 SSH_CONNECTION=155.247.182.146 3528 129.32.95.123 22 SSH_TTY=/dev/pts/1 TERM=vt100 KRB5CCNAME=FILE:/tmp/krb5cc_29469_Q9WEzl HOSTTYPE=x86_64-linux VENDOR=unknown OSTYPE=linux MACHTYPE=x86_64 SHLVL=1 PWD=/home/TU/stafford/nov09 GROUP=domain users HOST=CIS-Linux2.temple.edu REMOTEHOST=wach424a.cis.temple.edu HOSTNAME=CIS-Linux2.temple.edu INPUTRC=/etc/inputrc LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35: G_BROKEN_FILENAMES=1 SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass KDE_IS_PRELINKED=1 KDEDIR=/usr LANG=en_US.UTF-8 LESSOPEN=|/usr/bin/lesspipe.sh %s QTDIR=/usr/lib64/qt-3.3 QTINC=/usr/lib64/qt-3.3/include QTLIB=/usr/lib64/qt-3.3/lib MANPATH=/usr/man:/usr/local/man:/usr/share/man WWW_HOME=http://www.cis.temple.edu CIS-Linux2:~/nov09> -----------------------------------------------