Skip to content

Commit

Permalink
State of examples after class. TODOs are complete
Browse files Browse the repository at this point in the history
  • Loading branch information
payne committed May 23, 2012
1 parent bc79f07 commit 17f0076
Show file tree
Hide file tree
Showing 20 changed files with 184 additions and 28 deletions.
15 changes: 11 additions & 4 deletions 1.c
Expand Up @@ -9,17 +9,24 @@ int main() {
long diff=(long) &a;
diff -= (long) &e;
printf("&a=%p &e=%p diff=%ld\n", &a, &e, diff);
printf("WHY DOES THIS NOT MAKE SENSE?? \n"
"diff/sizeof(int)=%d\n", diff/sizeof(int));


diff=(long) &b;
diff -= (long) &c;
printf("&b=%p &c=%p diff=%ld\n", &b, &c, diff);
printf("diff/sizeof(int)=%d\n", diff/sizeof(int));

int *p;
p=&e;
// This next bit is a flashy demo and NOT a good practic!
int *p; // p points to an int
p=&a; // Set p to point at e by taking the address of e
int x;
for (x=0; x < 5; ++x) {
*p=100;
p++;
*p=100; // Change the value of the int pointed to by p to 100
// *p is read "dereference p"...
// as in p is a referenc to an int
p++; // Make p point to the next int
}

printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);
Expand Down
2 changes: 1 addition & 1 deletion 10.c
Expand Up @@ -9,7 +9,7 @@ int main() {

int i;
for (i=0; i < 3; ++i) {
// *p=100*(*p);
//*p=100*(*p);
printf("p=%p\n", p);
p++;
}
Expand Down
2 changes: 1 addition & 1 deletion 11.c
Expand Up @@ -11,7 +11,7 @@ int main() {
int i;
for (i=0; i < 3; ++i) {
*p=100*(*p);
printf("p=%p\n", p);
printf("p=%p *p=%d\n", p,*p);
//TRY THIS:
//p++;
}
Expand Down
20 changes: 15 additions & 5 deletions 13.c
Expand Up @@ -4,14 +4,15 @@
#include <stdlib.h>

int mycompare(const void *a, const void *b) {
int *ai = (int *) a;
// Almost always need to cast to tell C what is in the void
int *ai = (int *) a;
int *bi = (int *) b;
int aValue = (int)*ai;
int bValue = (int)*bi;
int aValue = (int)*ai; // CAST is NOT NEEDED!
int bValue = *bi;
return aValue-bValue;
}

void printAray(int *p,int nel) {
void printAray(int p[],int nel) { // or could say "int *p"
int i;
for (i=0; i < nel; ++i) {
printf("%d ", *p);
Expand All @@ -23,7 +24,16 @@ void printAray(int *p,int nel) {
int main() {
int aray[]={7,2,9};
int nel = 3;
qsort(aray,nel, sizeof(int), mycompare);
/*void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
*/
qsort(aray,nel, sizeof(int), &mycompare); // consistent with 7.c
printAray(aray,nel);
// Holy #Q@$!!! Why does it work BOTH WAYS!!!???
qsort(aray,nel, sizeof(int), mycompare); // consistent with 7.c
printAray(aray,nel);

// BECAUSE (sorry, it's lame) pointers are
// VERY VERY VERY DANGEROUS!!!
return 0;
}
31 changes: 29 additions & 2 deletions 14.c
@@ -1,13 +1,40 @@
/** Arrays/points in the command line */
/** Arrays/pointers in the command line */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
// RTFM man 7 environ
extern char **environ;

//ANSWER: This way (3rd param to main) is deprecated
// https://www.securecoding.cert.org/confluence/display/seccode/ENV31-C.+Do+not+rely+on+an+environment+pointer+following+an+operation+that+may+invalidate+it
int main(int argc, char *argv[], char *env[]) {
// argc -- argument cont
// argv -- argument vector
// Let's talk about argv!!

int i;
for (i=0; i < argc; i++) {
printf("argv[%d]='%s'\n", i, argv[i]);
}

//QUESTION: show how to properly access environment variables
//ANSWER: This way is deprecated
// https://www.securecoding.cert.org/confluence/display/seccode/ENV31-C.+Do+not+rely+on+an+environment+pointer+following+an+operation+that+may+invalidate+it
for (i=0; NULL==env[i]; i++) {
printf("env[%d]='%s'\n", i, env[i]);
}

// RTFM getenv
char *path=getenv("PATH");
printf("PATH is '%s'\n", path);
// RTFM man 7 environ
char **ep=environ;
while (NULL!=*ep) {
char *env_assignment=*ep;
ep++;
puts(env_assignment);
}


return 0;
}
19 changes: 14 additions & 5 deletions 15.c
@@ -1,4 +1,7 @@
/** Pointer arithmetic: p++ increases p by sizeof(*p) */
/** Pointer arithmetic: p++ increases p by sizeof(*p)
aka the size of the base type
int *p -- base type is int
*/

#include <stdio.h>

Expand All @@ -12,7 +15,8 @@ void voidDemo(void *p) {
void *pOld;
pOld=p;
p++;
printf("p=%p pOld=%p diff=%ld\n", p,pOld,diff(p,pOld));
printf("voidDemo: %3s=%p %6s=%p diff=%ld\n",
"p", p,"pOld",pOld,diff(p,pOld));
}

void charDemo() {
Expand All @@ -23,7 +27,8 @@ void charDemo() {
voidDemo(cp);
cpOld=cp;
cp++;
printf("cp=%p cpOld=%p diff=%ld\n", cp,cpOld,diff(cp,cpOld));
printf("charDemo: %3s=%p %6s=%p diff=%ld\n",
"cp", cp,"cpOld",cpOld,diff(cp,cpOld));
}

void shortDemo() {
Expand All @@ -34,7 +39,10 @@ void shortDemo() {
voidDemo(sp);
spOld=sp;
sp++;
printf("sp=%p spOld=%p diff=%ld\n", sp,spOld,diff(sp,spOld));
printf("shortDemo: %3s=%p %6s=%p diff=%ld sizeof(short)=%d\n",
"sp", sp,"spOld",spOld,diff(sp,spOld),sizeof(short));
printf("QUESTION: Why is the address one off from the void demo here?\n");
printf("ANSWER: points must align with their underlying type... short every two bytes (on vulcan), int every four bytes (on vulcan), and so on.\n");
}

void intDemo() {
Expand All @@ -45,7 +53,8 @@ void intDemo() {
voidDemo(ip);
ipOld=ip;
ip++;
printf("ip=%p ipOld=%p diff=%ld\n", ip,ipOld,diff(ip,ipOld));
printf("intDemo: %3s=%p %6s=%p diff=%ld sizeof(short)=%d\n",
"ip", ip,"ipOld",ipOld,diff(ip,ipOld),sizeof(int));
}

void longDemo() {
Expand Down
4 changes: 4 additions & 0 deletions 17.c
@@ -1,4 +1,8 @@
/** Pointer arithmetic: a[i] is really &a[0] + i * sizeof(a[0]) */
// Or &a[0] + i * sizeof(base data type)
// In other words ----
// In all C compilers
// Arrays are ALWAYS contiguous in MEMORY
#include <stdio.h>
#include <assert.h>

Expand Down
39 changes: 36 additions & 3 deletions 18.c
@@ -1,13 +1,46 @@
/** Arrays of pointers */
#include <stdio.h>
#include <string.h>

#define DAYS_IN_WEEK 7

void printAray(char *days[]);

//ANSWERED: Why did this qsort example fail!? Other than not practicing!
//qsort passes pointers to each element being sorted.
//so the parameters here are really pointers to pointers!
int ourstrcmp(const void *a_pointer_to_string, const void *b) {
static int number_of_debug_outputs=3;
// Step 1: Call it what it is -- a pointer to a pointer
char **pointer2pointer1=(char **)a_pointer_to_string;
// Step 2: Dereference it to get what we want -- a "char *"
char *string1 = *pointer2pointer1;
char **pointer2pointer2=(char **)b;
char *string2 = *pointer2pointer2;
if (0!=number_of_debug_outputs) {
number_of_debug_outputs--;
printf("string1=%s\n",string1);
printf("string2=%s\n",string2);
}
int result = strcmp(string1,string2);
return result;
}


int main(int argc, char *argv[]) {
char *days[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" };
char *days[] = { "Sunday", "Monday", "Tuesday", "Wed", "Beer day", "Fri",
"Saturday" };
printAray(days);
//qsort(days,DAYS_IN_WEEK,sizeof(char *), strcmp);//attempt to "cheat"
qsort(days,DAYS_IN_WEEK,sizeof(char *), ourstrcmp);//attempt to "cheat"
printAray(days);
return 0;
}

void printAray(char *days[]) {
printf("This is an array of seven pointers to strings.\n");
int i;
for (i=0; i < 7; ++i) {
for (i=0; i < DAYS_IN_WEEK; ++i) {
printf("\t%s\n", days[i]);
}
return 0;
}
2 changes: 1 addition & 1 deletion 2.c
Expand Up @@ -3,7 +3,7 @@

int main() {
int *p, q;
p = &q; // p gets the address of q
p = &q; // p gets the address of q -- p points at q
*p=42; // The integer pointed to by p gets the value 42
printf("q=%d p=%p &q=%p *p=%d\n", q,p,&q, *p);
q=86; // *p referes to the same location as q
Expand Down
1 change: 1 addition & 0 deletions 3.c
Expand Up @@ -7,6 +7,7 @@ int main() {
p="I like eggs";
printf("*p='%c'\n", *p);
printf("p='%s'\n", p);
printf("p='%s'\n", p+2);
return 0;
}

2 changes: 1 addition & 1 deletion 4.c
Expand Up @@ -11,7 +11,7 @@ int main() {
int a=42, b=86;

printf("a=%d b=%d\n", a,b);
swap(&a,&b);
swap(&a,&b); // The address of a becomes a pointer to a.... etc.
printf("a=%d b=%d\n", a,b);

return 0;
Expand Down
2 changes: 1 addition & 1 deletion 5.c
@@ -1,7 +1,7 @@
/** Simulating call-by-reference using (array[] syntax) pointers */
#include <stdio.h>

void swap(int p[], int q[]) {
void swap(int p[], int q[]) { // so, int p[] is "just like" int *p
int tmp = *p;
*p = *q;
*q = tmp;
Expand Down
1 change: 1 addition & 0 deletions 6.c
Expand Up @@ -3,6 +3,7 @@

// NOTE: this does not work -- void swap(int[] p, int[] q) {
void swap(int p[], int q[]) {
//int[] demop; // BAD SYNTAX!
int tmp = *p;
*p = *q;
*q = tmp;
Expand Down
15 changes: 14 additions & 1 deletion 7.c
Expand Up @@ -9,16 +9,29 @@ int addInt(int n, int m) {
return n+m;
}

int multInt(int n, int m) {
return n*m;
}

int main() {

int (*functionPtr)(int,int);

functionPtr=&addInt;
functionPtr=addInt;
//QUESTION: FIND OUT WHY & IS NOT NEEDED
//ANSWER: both are valid. Thus spoke stack overflow...
// http://stackoverflow.com/questions/258422/function-pointers-in-c-address-operator-unnecessary

int sum=(*functionPtr)(2,3);
printf("sum=%d\n", sum);
assert(5==sum);

// Wild and CRAZY!
functionPtr=&multInt;
sum=(*functionPtr)(2,3);
printf("sum=%d\n", sum);
assert(6==sum);

return 0;
}

25 changes: 24 additions & 1 deletion 8.c
@@ -1,6 +1,7 @@
/** Associate right to left: (*p)++ vs *p++ */

#include <stdio.h>
#include <assert.h>

long diff(int *x, int *y) {
long lx=(long)x;
Expand All @@ -9,19 +10,41 @@ long diff(int *x, int *y) {
}

int main() {
int a=1,b=2,c=3,d=4,e=5;
int a=100,b=200,c=300,d=400,e=500;
int *p, *pOld;

p=&a;
pOld=p;
// a is 100
// *p happens first due to ( )
// so value will be 100
// After the derefernce to get the value,
// we post increment the thing ("a") being referenced
int value = (*p)++;
printf("value=%d a=%d p=%p pOld=%p diff=%ld\n",
value,a,p,pOld,diff(p,pOld));
assert(100==value);
//assert(101=value);

assert(101==a);
value = ++(*p);
printf("value=%d a=%d p=%p pOld=%p diff=%ld\n",
value,a,p,pOld,diff(p,pOld));
assert(102==value);


pOld=p;
value = *p++;
printf("value=%d a=%d p=%p pOld=%p diff=%ld\n",
value,a,p,pOld,diff(p,pOld));
//FAILS: assert(200==*p); // Compiler specific code!! DANGER WILL ROBINSON!!!
//FAILS: assert(&b==p); // Compiler specific code!! DANGER WILL ROBINSON!!!
// Really not a non-compiler specific way???
// This is a nice idea! Put it back and check...
p--;
assert(&a==p); // NICE!
// So, we know that *p++ ended up incrementing the POINTER
// and not the thing being referenced (pointed at)

return 0;
}
3 changes: 3 additions & 0 deletions 9.c
Expand Up @@ -7,6 +7,9 @@ int main() {
int *p; // Non-constant pointer to non-constant data
p=&a;

// Taking advantage of a, b, and c being next to each
// other in RAM is a parlor trick and NOT A GOOD PRACTICE!
// Remember! Pointers are very very very dangerous
int i;
for (i=0; i < 3; ++i) {
*p=100*(*p);
Expand Down
4 changes: 3 additions & 1 deletion README.md
@@ -1,4 +1,6 @@
22May2012Talk
=============

Files related to my 5/22/12 guest appearance in Dr. Hahn's CSCI 1840
Files related to my 5/22/12 guest appearance in Dr. Hahn's CSCI 1840

Code will be kept up to date at https://github.com/payne/22May2012Talk

0 comments on commit 17f0076

Please sign in to comment.