# EZLippi/practical-programming-books

Switch branches/tags
Nothing to show
Fetching contributors…
Cannot retrieve contributors at this time
168 lines (143 sloc) 12.7 KB

## 三、指针和数组

(Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type “array of type” is converted to an expression with type “pointer to type” that points to the initial element of the array object and is not an lvalue.)

```short a[] = {1,2,3};
short *pa;
short (*px)[];
void init(){
pa = a;
px = &a;
```printf(&quot;a:%p; pa:%p; px:%p\n&quot;, a, pa, px);

printf(&quot;a[1]:%i; pa[1]:%i (*px)[1]:%i\n&quot;, a[1], pa[1], (*px)[1]);
```
}```

（译者注：%i能识别输入的八进制和十六进制）

aint 型数组，pa 是指向 int 的指针，px 是个未完成的、指向数组的指针。a 赋值给 pa 前，它的值被转为一个指向数组开头的指针。右值表达式 &a 并非意味着指向 int，而是一个指针，指向 int 型数组因为当使用一元符号&时右值不被转换为指针。

```int a[];
int *pa;```

```extern int *a;
extern int pa[];```

### 3.1 数组作为函数形数

```void sum(int data[10]) {}
void sum(int data[]) {}
void sum(int *data) {}```

```typedef int[4] vector;
vector m[2] = {{1,2,3,4}, {4,5,6,7}};
int n[2][4] = {{1,2,3,4}, {4,5,6,7}};```

```int *p = n[1];
int y = p[2];```

`int z = *(*(n+1)+2);`

`int x = n[1][2];`

```void sum(int data[2][4]) {}
void sum(int data[][4]) {}
void sum(int (*data)[4]) {}```

```void list(int *arr, int max_i, int max_j){
int i,j;
```for(i=0; i&lt;max_i; i++){

for(j=0; j&lt;max_j; j++){
int x = arr[max_i*i+j];
printf(&quot;%i, &quot;, x);
}

printf(&quot;\n&quot;);
}
```
}```

```int main(int argc, char **argv){
int arr1[4] = {1,2,3,4};
int arr2[4] = {5,6,7,8};
```int *arr[] = {arr1, arr2};

list(arr, 2, 4);
```
}
void list(int **arr, int max_i, int max_j){
int i,j;
```for(i=0; i&lt;max_i; i++){

for(j=0; j&lt;max_j; j++){
int x = arr[i][j];
printf(&quot;%i, &quot;, x);
}

printf(&quot;\n&quot;);
}
```
}```

```const char *strings[] = {
"one",
"two",
"three"
};```

```void list(int max_i, int max_j, int arr[][max_j]){
/* ... */
int x = arr[1][3];
}```

```static void catch_int(int no) {
/* ... */
};
int main(){
signal(SIGINT, catch_int);
```/* ... */
```
}```

## 四、打桩（Interpositioning）

```/* _GNU_SOURCE is needed for RTLD_NEXT, GCC will not define it by default */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <stdint.h>
#include <inttypes.h>
static uint32_t malloc_count = 0;
static uint64_t total = 0;
void summary(){
fprintf(stderr, "malloc called: %u times\n", count);
fprintf(stderr, "total allocated memory: %" PRIu64 " bytes\n", total);
}
void malloc(size_t size){
static void (*real_malloc)(size_t) = NULL;
void *ptr = 0;
```if(real_malloc == NULL){
real_malloc = dlsym(RTLD_NEXT, &quot;malloc&quot;);
atexit(summary);
}

count++;
total += size;

return real_malloc(size);
```
}```

```\$ gcc -shared -ldl -fPIC malloc_counter.c -o /tmp/libmcnt.so
\$ ps
PID TTY          TIME CMD
2758 pts/2    00:00:00 bash
4371 pts/2    00:00:00 ps
malloc called: 184 times
total allocated memory: 302599 bytes```

### 4.1 符号可见性

```#if __GNUC__ >= 4 || __clang__
#define EXPORT_SYMBOL __attribute__ ((visibility ("default")))
#define LOCAL_SYMBOL  __attribute__ ((visibility ("hidden")))
#else
#define EXPORT_SYMBOL
#define LOCAL_SYMBOL
#endif```