Yulong Niu

个人博客

C语言指针记录

Posted at — Apr 17, 2016

1. C语言指针基础

C语言的指针设计是一致和优雅的。C语言中“指针(pointer)”就是地址(所以不能用普通整数储存地址),“指针变量(pointer variable)”是存储地址的变量。一个指针变量,只能指向一个特定类型的变量,比如整数、浮点数、字符或者指针。

int tmp1 = 1, tmp2;

/* "=" does not mean "assignment", it just means "initiating" */
/* p is the address of tmp1, *p is equal to the value of tmp1*/
int *p = &tmp1;

int *q;
q = &tmp2;

/* p points to tmp1, q points to tmp2, now the value of tmp2 is 1*/
*p = *q;

/* p and q now both points to tmp1*/
q = p;

2. 指针运算有且只有三种

指针与++--结合的表达式

表达式意义
*p++表达式值为p指针指向内容,之后指针自增
(*p)++表达式值为p指针指向内容,之后指向内容自增
++*p表达式值为p指针指向内容自增,指针不变
*++p表达式值为p指针自增后指向内容

3. 指针与数组

数组类型初始化声明1函数形参声明的指针形式2第一个元素指针声明
元素为整数的数组int a[LEN]int *int *p = &a[0]int *p = a
元素为整数数组的数组(“二维数组”)int a[ROWNUM][COLNUM]int (*)[COLNUM]int *p = &a[0]int (*p)[COLNUM] = a 
元素为字符的数组(“字符串”)char a[LEN]char *char *p = &a[0]char *p = a
元素为字符串指针的数组(“字符串数组”)char *a[LEN]char **char *[LEN]char **p = &a[0]char **p = a
元素为结构、联合或枚举的数组struct t a[LEN]struct t *struct t *p = &a[0]struct t *p = a

1:初始化声明表示在声明同时初始化的形式,比如int a[3] = {1, 2, 3}char a[] = 'hello'或者char *a[] = {"hello", "world!"}

2:在函数中声明形参时,对应的指针类型。形参可以是完整类型或者元素类型,比如,形参char *a[LEN]是完整类型,形参char **a是元素类型;再比如,形参int a[ROWNUM][COLNUM]是完整类型,形参int (*a)[COLNUM]是元素类型;再比如,形参char a[]是完整类型,形参char *a是元素类型。编译器把数组型的形参视为指针。

4. 指针与函数

void TestFun(int const *a) {
  ...
  ++a;
  ...
}

5. 注意事项

struct node *Add(struct node *n, int v) {
  struct node *new;
  new = malloc(sizeof(struct node));
  ...
  return new;
}

补充材料


{% codeblock lang:c Using pointers to operate arrays in c %}
#include <stdio.h>

#define N 5

void PrintVal(int *a);
void PrintArray(int *a, int length);
void PrintString(char *a, int length);
void Print2Array(int colnum, int rownum, int (*a)[colnum]);
void Print2Array2(int colnum, int rownum, int **a);
void PrintStringArray(char *a[], int length);
void PrintStringArray2(char **a, int length);

int main(void)
{
  int testVal = 2;
  PrintVal(&testVal);
  printf("\n");

  int testArray[N] = {2, 3, 5};
  PrintArray(testArray, N);
  printf("\n");

  char testString[N] = "hell";
  PrintString(testString, N);
  printf("\n");

  int test2Array[N][N] = {{1, 2, 3, 4, 5}};
  Print2Array(N, N, test2Array);
  int *test2Array2[N] = {test2Array[0], test2Array[1], test2Array[2], test2Array[3], test2Array[4]};
  Print2Array2(N, N, test2Array2);

  char *testStringArray[N] = {"Hello,", "it", "is", "me", "!"};
  PrintStringArray(testStringArray, N);
  PrintStringArray2(testStringArray, N);

  return 0;
}

void PrintVal(int *a) {
  printf("%3d", *a);
}

void PrintArray(int *a, int length) {
  int *p;
  for (p = a; p < a + length; ++p) {
    printf("%3d", *p);
  }
}

void PrintString(char *a, int length) {
  char *p;
  for (p = a; p < a + length; ++p) {
    printf("%c", *p);
  }
}


void Print2Array(int colnum, int rownum, int (*a)[colnum]) {
  int (*p)[colnum];
  for (p = a; p < a + colnum; ++p) {
    for (int *q = *p; q < *p + rownum; ++q) {
      printf("%3d", *q);
    }
    printf("\n");
  }
}

void Print2Array2(int colnum, int rownum, int **a) {
  int **p;
  for (p = a; p < a + colnum; ++p) {
    for (int *q = *p; q < *p + rownum; ++q) {
      printf("%3d", *q);
    }
    printf("\n");
  }
}

void PrintStringArray(char *a[], int length) {
  char **p;
  for (p = a; p < a + length; ++p) {
    printf("%s\n", *p);
  }
}

void PrintStringArray2(char **a, int length) {
  char **p;
  for (p = a; p < a + length; ++p) {
    printf("%s\n", *p);
  }
}

输出结果为:

  2
  2  3  5  0  0
hell
  1  2  3  4  5
  0  0  0  0  0
  0  0  0  0  0
  0  0  0  0  0
  0  0  0  0  0
  1  2  3  4  5
  0  0  0  0  0
  0  0  0  0  0
  0  0  0  0  0
  0  0  0  0  0
Hello,
it
is
me
!
Hello,
it
is
me
!

参考资料

更新记录

2016年4月17日