0%

C/C语言指针

C指针

为什么学习指针

通过指针,可以简化一些C编程任务的执行,还有一些任务,如动态内存的分配,没有指针是无法执行的。

什么是指针

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,使用指针存储其他变量地址之前,需要对其进行声明,

指针的简单使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//指针学习
#include "stdio.h"
int main()
{
/*指针的简单使用*/
int number=20;/*实际变量的声明*/
int *num;/*指针变量的声明*/
num=&number;/*在指针变量中存储number的地址*/
printf("number的地址是L:%p\n",num);//两种打印number地址的方式
printf("number的地址是L:%p\n",&number);
printf("number的s值是:%d\n",*num);//两种打印number值的方式。
printf("number的s值是:%d\n",number);


}
/*输出结果为:
number的地址是L:0x7ffeefbff4ec
number的地址是L:0x7ffeefbff4ec
number的s值是:20
number的s值是:20
*/

C中的NULL指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为指针。

在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。

1
2
3
4
5
6
7
8
9
10
11
12
13
//检查一个空指针
#include "stdio.h"
int main()
{
int *Zero =NULL;
if (!Zero) {
printf("这是一个空指针\n");
}

}
/*输出结果为:
这是一个空指针
*/

指针的算术运算

指针的递增递减

我们喜欢在程序中使用指针代替数组,因为变量指针可以递增,而数组不能递增,数组可以看成一个指针常量。下面的程序递增变量指针,以便顺序访问数组中的每一个元素:

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
#include "stdio.h"
int main()
{
//定增一个指针
int number[4]={5,2,1,1314};
int *num=number;
int i=0;
while (i<=3) {
printf("number存储值为:%d\n",*num);
i++;
num++;
}
//递减一个指针
int number1[4]={1,2,3,4};
int *num1=&number1[3];//这里注意递减时指针的指向是不一样的
int j=3;
while (j>=0) {
printf("number1存储值为:%d\n",*num1);
j--;
num1--;
}

}
/*输出结果为:
number存储值为:5
number存储值为:2
number存储值为:1
number存储值为:1314
number1存储值为:4
number1存储值为:3
number1存储值为:2
number1存储值为:1
*/

指针的比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdio.h"
int main()
{
//通过指针的比较来输出数组中的字符
int number[4]={5,2,1,1314};
int *num=number;
int i=0;
while (num<=&number[3]) {
printf("number[%d]:%d\n",i,*num);
i++;
num++;
}
}
/*输出结果为:
number[0]:5
number[1]:2
number[2]:1
number[3]:1314
*/

指针数组

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
#include "stdio.h"
int main()
{
//指针数组
//整数指针
int number[4]={5,2,1,1314};
int i=0,*num[4];
for (i=0; i<=3; i++) {
num[i]=&number[i];
}
for (i=0; i<=3; i++) {
printf("number[%d]:%d\n",i,*num[i]);
}
printf(" \n");
//用一个指向字符的指针数组来存储一个字符串列表
printf("这就是我想要对你说的话:\n");
char *zifu[]={"I love you!","I love python!","But i love you best!"};
int j=0;
for (j=0; j<3; j++) {
printf("%s\n",zifu[j]);
}




}
/*输出结果为:
number[0]:5
number[1]:2
number[2]:1
number[3]:1314

这就是我想要对你说的话:
I love you!
I love python!
But i love you best!
*/

指向指针的指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stdio.h"
int main()
{ //定义指向指针的指针时,一定要使用两个*号
int num=20;
int *zz=&num;
int **zzz=&zz;
//使用三种方法分别打印出变量num的值
printf("num的值是:%d\n",num);
printf("num的值是:%d\n",*zz);
printf("num的值是:%d\n",**zzz);


}
/*输出结果为:
num的值是:20
num的值是:20
num的值是:20
*/

传递指针给函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stdio.h"
#include "time.h"
void sj(unsigned long *zz);
int main()
{ //通过传递指针给函数,可以直接修改原参数(实参),而不是引用实参到形参。
unsigned long shijian;
sj(&shijian);
printf("当前时间参数是:%ld\n",shijian);
}

void sj(unsigned long *zz)
{
*zz=time(NULL);
return ;
}
/*输出结果为:
当前时间参数是:1575623559
*/

能接受指针作为参数的函数,也能接受数组作为参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdio.h"
double get(int *zz);
int main()
{ //通过传递指针给函数,可以直接修改原参数(实参),而不是引用实参到形参。
int number[6]={1,2,3,4,5,6};
double jieguo;
jieguo=get(number);
printf("它们的平均数是:%lf\n",jieguo);
}

double get(int *zz)
{
int i=0;int sum=0;
for (i=0; i<=5; i++) {
sum=sum+zz[i];
}
return (double)sum/6;

}
/*输出结果为:
它们的平均数是:3.500000
*/

从函数返回指针

1
2