数组指针
数组指针
一个变量有一个地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址,且连续分布。所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。
字节是内存中的最小可操作单元,通常将一个字节称为一个内存单元。
一个数组是由连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素(下标变量)组成的。每个数组元素按其类型不同占有几个连续的内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。
通过指针引用数组
引入指针变量后,就可以用两种方法访问数组元素。 p的初值为&a[0],则:
- p+i 和 a+i 就是 a[i] 的地址,或者说它们指向a数组的第 i 个元素。
*(p+i)或*(a+i)就是 p+i 或 a+i 所指向的数组元素(的内容),即a[i]。例如,*(p+5)或*(a+5)就是 a[5]。- 指向数组的指针变量也可以带下标,如 p[i] 与
*(p+i)等价。
根据以上叙述,引用一个数组元素可以用:
- 下标法:即用 a[i] 形式访问数组元素,在前面介绍数组时都是采用这种方法。
- 指针法:即采用 (a+i) 或 (p+i) 形式,用间接访问的方法来访问数组元素,其中a是数组名,p是指向数组的指针变量,它们的值相同。
C语言用数组作函数参数
- 按值传递:用普通变量做函数参数,形参和实参位于不同的内存区域,发生函数调用时,会把实参的值传递给形参,改变形参的值不会影响到实参,它们是相互独立的。
- 按引用传递: 在用数组名作函数参数时,不是进行值的传送,不会把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。那么,数据的传送是如何实现的呢?数组名就是数组的首地址,用数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实实在在的数组。实际上是形参数组和实参数组为同一数组,拥有同一段内存空间。这种传值方式成为按引用传递。 用普通变量作函数参数时,所进行的值传递是单向的,只能从实参传向形参,不能从形参传回实参。形参的初值和实参相同,而形参的值发生改变后,实参并不变化,两者的终值是不同的。而当用数组作函数参数时,情况有所不同。由于实际上形参和实参为同一数组,因此当形参数组发生变化时,实参数组也随之变化。
C语言字符串指针
C语言中,通过字符数组存放一个字符串,也可以用字符指针指向一个字符串。
- 对指向字符变量的指针变量应赋予该字符变量的地址。
char c, *p=&c; - 表示p是一个指向字符变量c的指针变量
- 下面表示s是一个指向字符串的指针变量。把字符串的首地址赋予s
char *string = "I love coding";
指针型函数
前面我们介绍过,所谓函数类型是指函数返回值的类型。函数的返回值是一个指针(即地址),这种返回指针值的函数称为指针型函数。定义指针型函数的一般形式为:
数据类型 *函数名(形参列表) {
// 函数体
}
代码示例#2.6.1-比较两个字符串的长度
#include <stdio.h>
char *func(char *str1, char *str2){
if(strlen(str1) >= strlen(str2)){
return str1;
}else{
return str2;
}
}
int main()
{
char *s1 = "C Language";
char *s2 = "C is very great!";
char *longstr = func(s1, s2);
printf("Long string: %s\n", longstr);
return 0;
}
指针数组
指针数组中每个元素的值都为指针。一般的定义形式为:
数据类型 *数组名[数组长度];
用pa表示二维数组,pa是一个指针数组,有三个元素,每个元素值都是一个指针,指向整型变量。
int *pa[3]{ a[0], a[1], a[2]};
指针的指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个变量为指向指针的指针变量或指向指针的指针。
数据类型 **变量名;