C语言指针记录
1. C语言指针基础
C语言的指针设计是一致和优雅的。C语言中“指针(pointer)”就是地址(所以不能用普通整数储存地址),“指针变量(pointer variable)”是存储地址的变量。一个指针变量,只能指向一个特定类型的变量,比如整数、浮点数、字符或者指针。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
2. 指针运算有且只有三种
-
指针加一个整数,该表达式值为同类型指针;
-
指针减一个整数,该表达式值为同类型指针;
-
指针与指针相减,该表达式值为整数。
指针与++
和--
结合的表达式
表达式 | 意义 |
---|---|
*p++ |
表达式值为p指针指向内容,之后指针自增 |
(*p)++ |
表达式值为p指针指向内容,之后指向内容自增 |
++*p |
表达式值为p指针指向内容自增,指针不变 |
*++p |
表达式值为p指针自增后指向内容 |
3. 指针与数组
-
C语言只有一维数组,其中元素可以是数(整数或浮点数)、字符和指针(字符串、其他类型数组或者其他类型指针)。
-
数组地址为第一个元素地址。可以使用数组名作为指向数组第一个元素的指针,但数组名不能被修改,例如不能被重新赋值。因此,假如
a
数组,a+i
等价与&a[i]
,*(a+i)
等价与a[i]
。 -
对于二维数组
a
,a
表示指向第一行的指针(即指针指向一维数组),a[0]
表示指向第一行第一个元素的指针。理解a[0]
:a[0]
等价与*(a + 0)
,表示指针a
指向的内容,即第一行数组;同时,一维数组名表示指向第一个元素的指针。 -
“字符串字面量(string literal)”被作为字符数组储存,类型为
char *
,因此对于字符串变量char s[] = "abc";
和char *s = "abc";
都合法。但是,int a[] = {1, 2, 3};
合法,int *a = {1, 2, 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. 指针与函数
-
C语言传入函数的都是值(数组被当做指针传入),而且形参对应对象的一个副本。
-
形参为指针,可以改变指向的内容。
-
形参为数组,传入指针(指向第一个元素地址)副本。因此,即便是数组名,也可以修改,即可以把数组名当做一个指针用。也可以使用指针传入部分数组。如下代码合法:
-
1 2 3 4 5 |
|
5. 注意事项
-
留意未初始化指针,修改未初始化指针所指向内容是危险的。字符指针必须初始化,比如指向已有字符变量、字符串字面量或动态分配字符串。
-
已有数组名不能被重新赋值,不能指向其他地址。
-
函数返回指针时,不能返回指向局部自动变量的指针,因为局部变量和对应指针在返回时销毁。可以返回指针形式的形参、指向外部变量的指针、指向声明为
static
的局部变量和指向动态分配内存的指针。如下代码合法:
1 2 3 4 5 6 |
|
补充材料
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
|
输出结果为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
参考资料
- KN King: C Programming: A Modern Approach, 2nd Edition, 2008.
更新记录
2016年4月17日