Joseph Haugh
University of New Mexico
What is the output of the following pieces of code?
void main(void) {
/* Assume sizeof(int) = 4 */
int x = 5; /* addr = 0x4A */
int *y = &x + x;
printf("&x=%p, y=%p\n", &x, y);
}
void main(void) {
/* Assume sizeof(int) = 4 */
int x = 5; /* addr = 0x4a */
int *y = &x + x;
printf("&x=%p, y=%p\n", &x, y);
}
&x=0x4a, y=0x5e
int and int* are always the same size.
int and int* are always the same size.
False
* means what in C?
* means what in C?
& means what in C?
& means what in C?
Given the following memory:
Address | Value |
---|---|
0x40 | 5 |
0x44 | 7 |
0x48 | 9 |
What will the following code print?
int array[] = {5, 7, 9};
printf("%p\n", array);
Given the following memory:
Address | Value |
---|---|
0x40 | 5 |
0x44 | 7 |
0x48 | 9 |
What will the following code print?
int array[] = {5, 7, 9};
printf("%p\n", array);
0x40
Arrays are initialized using the following syntax:
int array[] = {1, 2, 3, 4, 5};
The size of the array is optional when doing this.
You can initialize an array of pointers:
char *array[] = {"one", "two", "three"};
Multi-dimensional arrays are arrays of arrays.
int matrix[10][5];
matrix is an array of 10 arrays, each containing 5 integers.
It can be initialized as follows:
int matrix[10][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
/* ... */
};
When passing a multi-dimensional array to a function, you must specify the size of all but the first dimension.
void foo(int matrix[][5]) {
/* ... */
}
Arrays of pointers to arrays are often used in lieu of multi-dimensional arrays.
int *matrix[10];
Is an array of 10 pointers to arrays of integers.
We can do some interesting things with arrays of pointers.
int *foo[2]; /* Array of two integer pointers */
int a[3]; /* Array of three ints */
int b[4]; /* Array of four ints */
foo[0] = a;
foo[1] = b;
foo[0][0] = 0; /* a[0] = 0; */
foo[0][1] = 1; /* a[1] = 1; */
foo[1][3] = 3; /* b[3] = 3; */
foo[0][3] = 3; /* ERROR! */
Arrays of pointers to arrays are especially useful for arrays of Strings:
char *colors[3] = {"red", "green", "blue"};
colors[0][0] == 'r'
colors[1][0] == 'g'
colors[2][0] == 'b'
void main(void) {
char str1[] = "Hello World";
char *str2 = "Hello World";
str1[6] = 'X';
printf("str1=%s\n", str1);
printf("str2=%s\n", str2);
str2[6] = 'X';
printf("str2=%s\n", str2);
}
str1=Hello Xorld
str2=Hello World
Segmentation fault
Line 7 fails because str2 is a pointer to a string constant and thus, in read-only memory.
int n = 17;
int* a = &n;
short* b = (short*)&n;
char* c = (char*)&n;
printf("%p %p %p\n", a, b, c);
a++; b++; c++;
printf("%p %p %p\n", a, b, c);
printf("%d\n", n);
Line 7: The values at a*, b*, and c* are incremented by the size of their respective types and their values are now undefined.
0x7ffffba2610c 0x7ffffba2610c 0x7ffffba2610c
0x7ffffba26110 0x7ffffba2610e 0x7ffffba2610d
17
int strLen(char s[]) {
int i=0;
while (s[i]) i++;
return i;
}
int strLen2(char *s) {
char *p = s;
while (*p) p++;
return p - s;
}
int main(int argc, char *argv[]) {
Call program: ./a.out Hello World
argv -> | argv[0] -> | a.out\0 |
argv[1] -> | Hello\0 | |
argv[2] -> | World\0 |
argv is a pointer to an array of pointers.
Each pointer is the address of the first char in a null terminated string.
void main(int argc, char *argv[]) {
int i;
printf("Number of arguments = %d\n", argc);
for (i = 0; i < argc; i++) {
printf(" argv[%d]=%s\n", i, argv[i]);
}
}
a.out pi is 3.1415
Number of arguments = 4
argv[0]=a.out
argv[1]=pi
argv[2]=is
argv[3]=3.1415
argv[i] is the address of a null terminated string
void main(int argc, char *argv[]) {
printf("main(): argc=%d\n", argc);
while (argc-- > 0) { /* test first, then decrement */
printf("argc=%d: %s\n", argc, *argv++);
}
}
What is going on with *argv++?
a.out Hello World
main(): argc=3
argc=2: a.out
argc=1: Hello
argc=0: World