0%

C语言指针

指针是内存地址
指针变量是用来存放内存地址的变量
指针变量的值是地址(即指针)
指针变量可以有空值,即不指向任何变量
p=NULL;
如果两个指针变量都指向同一个数组中的元素,则两个指针变量值之差是两个指针之间的元素个数。
若两个指针指向同一个数组的元素,则可以进行比较,指向前面的元素的指针变量“小于”格向后面元素的指针变量。

*:取值操作符
&: 取址操作符
以下代码示例:
(1)

1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main()
{
int i=2000;
int *pointer;//此处*表示定义了一个指针变量,指针变量名是pointer,而不是*pointer
pointer=&i;//pointer==i的地址
printf("%d\n",*pointer);//取出pointer所指向地址的值
return 0;
}

在这里插入图片描述
(2)在函数中运用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdio.h>
int main()
{
int a,b;
int *pointer_1,*pointer_2;
void swap(int *p1,int *p2);
scanf("%d %d",&a,&b);
pointer_1=&a;
pointer_2=&b;
if(a<b)
{
swap(pointer_1,pointer_2);
}
printf("%d %d\n",a,b);
return 0;
}

void swap(int *p1,int *p2)
{
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}

在这里插入图片描述
*和&的优先级相同,按照自右向左的顺序
例:

1
2
3
1)现令pointer=&a;
则&*pointer==&a
2)*&a==a;

C语言运算符优先级表
在这里插入图片描述
赋值时,指针变量和变量的类型需要一样
指针变量可以赋值给另一个指针变量

1
pointer_1=pointer_2

示例程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
int main()
{
int a,b;
int *pointer_1,*pointer_2;
a=3;
b=5;
pointer_1=&a;
pointer_2=&b;
pointer_1=pointer_2;
printf("%d %d\n",*pointer_1,*pointer_2);
return 0;
}

在这里插入图片描述
数组和指针
当引用一个数组元素时,可以使用:
(1)下标法:如a[i]
(2)指针法,如*(a+i)
由于数组名指向的是数组的第一个元素的地址,故,假设a是数组名,p是指向数组元素的指针变量,其初值p=a,即p=&a[0],上面的指针法中的a也可以写成p.
(3)指针变量
使用指针变量指向数组元素

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0};
int i;
int *p;
for(p=a;p<(a+10);p++)
{
printf("%d",*p);
}
printf("\n");
return 0;
}

在这里插入图片描述
使用数组名作为函数参数:

1
2
3
4
5
6
7
8
9
10
void f(int arr[],int n)
//在编译时将arr按指针变量处理,相当于函数首部写成f(int *arr,int n)
{
}
void main()
{
int array[10];
……
f(array,10);
}

补充一下函数里面实参和形参的内容:
形参(形式参数):
在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参。
实参(实际参数):
函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参。
形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。

多维数组和指针
在这里插入图片描述
在这里插入图片描述
类型说明符 (*指针变量名)[长度]
例如:

1
int (*p)[4]

表示p是一个指针变量,指向包含4个元素的一维数组。

1
2
*(p+i)+j 二维数组i行j列的元素的地址
*(*(p+i)+j)i行j列元素的值

字符串和指针

1
2
3
4
5
6
7
#include<stdio.h>
int main()
{
char *string="HelloWorld!";
printf("%s\n",string);
return 0;
}

在这里插入图片描述
字符串也可以用下标法和指针法

下标法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
int main()
{
char a[]="HelloWorld!";
int i;
char b[100];
for(i=0;*(a+i)!='\0';i++)
{
*(b+i)=*(a+i);
}
*(b+i)='\0';
for(i=0;b[i]!='\0';i++)
{
printf("%c",b[i]);
}
printf("\n");
return 0;
}

在这里插入图片描述
指针法:

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()
{
char a[]="HelloWorld!";
int i;
char b[100];
char *p1,*p2;
p1=a;
p2=b;
for( ;*p1!='\0';p1++,p2++)
{
*p2=*p1;
}
*p2='\0';
for(i=0;b[i]!='\0';i++)
{
printf("%c",b[i]);
}
printf("\n");
return 0;
}

在这里插入图片描述
字符指针变量和字符数组
1.字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第1个字符的地址),不是将字符串放到字符指针变量中。
2.赋值方式。对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值。

1
2
char str[20];
str = "Hello World!"

而对字符指针变量,可以采用下面方法赋值

1
2
char *a;
a = "HelloWorld!";

注意赋给a的不是字符,而是字符串第一个元素的地址。
指向函数的指针
可用于在函数中调用别的函数

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
int main()
{
int max(int,int);
void process(int x,int y,int(*fun)(int,int));
int a,b;
scanf("%d %d",&a,&b);
process(a,b,max);
return 0;
}

返回指针值的函数

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>
int main()
{
int score[][2] = {{10,20},{20,40},{30,60}};
int *search(int(*pointer)[2],int n);
int *p;
int i,m;
scanf("%d",&m);
p=search(score,m);
for(i=0;i<2;i++)
{
printf("%d\t",*(p+i));
}
printf("\n");
return 0;
}
int *search(int (*pointer)[2],int n)
{
int *pt;
pt=*(pointer+n);
return pt;
}

在这里插入图片描述
指针函数和函数指针
指针函数是指带指针的函数,本质是一个函数。
函数指针是指向函数的指针变量,因而函数指针本身首先应是指针变量了,只不过该指针变量指向函数。
指针数组
一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为:
int *name[4];
指向指针的指针
例如:

1
char **p;//相当于*(*p)

在这里插入图片描述