目录
例题:对输入的两个整数按照从大到小顺序输出(用函数实现交换功能)
例题:输入a,b,c 3个整数,按照从小到大输出(函数+指针)
1.初识指针
1.1初始两个操作符
*: 取值操作符 &:取址操作符
例如:
int i=2000;//
int *p;//定义一个指针
p=&i;//此时p等于i的地址
printf("%d",*p);
1.2指针与指针变量
c中可以定义一类特殊的变量,这些变量专门用来存放地址,称为指针变量
注意:指针变量的值(即指针变量中存放的值)是地址(即指针)
float *p1;//p1是指向float型变量的指针变量
char *p2; //p2是指向char型变量的指针变量
一般形式:类型说明符 *变量名
在定义指针变量时必须指定基类型
将float型的变量的地址放到指向int型变量的指针变量中(错误)
&a表示变量a的地址,&b表示变量b的地址。当然,变量本身必须预先声明。
1.2.1例题:通过指针变量访问整型变量
#include<stdio.h>
void main()
{
int a, b;//定义变量
int* p1, * p2;//定义两个指针变量
a = 100; b = 10;//赋初值
p1 = &a; p2 = &b;//p1变量等于a的地址,p2等于b的地址
printf("%d %d\n", a, b);//输出a,b
printf("%d %d\n",*p1,*p2);//将p1,p2地址中存放的值通过*取出来
}
输出结果 100 10
100 10
1.3对“&”和“*”运算符的说明
1.*p=&a;那么&*p的含义是:由于两个运算符的优先级别相同,但按照自右向左结合,它就是变量a,在执行&操作
因此,&*p于&a相同,即变量a的地址
2.(*p)++相当于a++
例题:输入a,b两个整数,按从大到小的顺序输出a和b。
#include<stdio.h>
void main()
{
int a, b;
int* p1, * p2, * p;
scanf_s("%d%d", &a, &b);//输入两个数
p1 = &a; p2 = &b;//p1等于a的地址
if (a < b) {
p = p1; p1 = p2; p2 = p;//两个数交换值的代码
}
printf("%d %d", *p1, *p2);
}
//或者上面定义为p
//交换可以改为if (a < b) {p = *p1;* p1 = *p2; *p2 = p;}
例题:对输入的两个整数按照从大到小顺序输出(用函数实现交换功能)
#include<stdio.h>
int swap(int *p1,int *p2) {
int p;
p = *p1; //相当于p=a;
*p1 = *p2; //相当于a=b;
*p2 = p; //相当于b=p;
}
void main()
{
int a, b;
int* p1, * p2;
scanf_s("%d%d", &a, &b);
p1 = &a; p2 = &b;
if (a < b) {
swap(p1, p2);//swap实现的是交换
}
printf("%d %d", *p1, *p2);
}
例题:输入a,b,c 3个整数,按照从小到大输出(函数+指针)
#include<stdio.h>
int swap(int* p1, int* p2) {//交换代码
int p;
p = *p1; *p1 = *p2; *p2 = p;
return 0;
}
void main() {
int a, b, c;
int* p1, * p2, * p3,*p;
scanf_s("%d%d%d", &a, &b, &c);
p1 = &a; p2 = &b; p3 = &c;
if (a > b) {swap(p1, p2);}//调用函数
if (a > c) {swap(p1, p3);}//调用函数
if (b > c) {swap(p2, p3);}//调用函数
printf("%d,%d,%d", *p1, *p2, *p3);//输出
}
2.数组与指针
数组元素的指针就是数组元素的地址。
指针变量赋值
p=&a[0];//把a[0]元素的地址赋给指针变量
2.1.通过指针引用数组元素
(1)下标法,如a[i]形式;
(2)指针法,如*(a+i)或*(p+i)
其中a是数组名,p是指向数组元素的指针变量,其初值p=a。即p=&a[0]
注意:数组名即“翻译成数组的第一个元素的地址”。
例题:输出数组中的全部元素
假设有一个a数组,整型,有10个元素。要输出各元素的值的方法:
(1)下标法。
#include<stdio.h>
void main()
{
int a[10], i;
for (i = 0; i < 10; i++) {
scanf_s("%d", &a[i]);
}
printf("\n ");
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
}
(2)通过数组名计算数组元素地址,找出元素的值。
#include<stdio.h>
void main()
{
int a[10], i;
for (i = 0; i < 10; i++) {
scanf_s("%d", &a[i]);
}
printf("\n ");
for (i = 0; i < 10; i++) {
printf("%d ", *(a+i));
}
}
(3)用指针变量指向数组元素。
#include<stdio.h>
void main()
{
int a[10], i;
int* p;
for (i = 0; i < 10; i++) {
scanf_s("%d", &a[i]);
}
printf("\n ");
for (p=a; p<(a+10); p++) {
printf("%d ", *p);
}
}
2.2用数组名做函数参数
f(int arr[],int n)
//但在编译时是将arr按指针变量处理的,相当于将函数f的首部写成f(int *arr,int n)
//这两种的写法是等价的
需要说明的是:c语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表是数组首函数地址,因此传递的值是地址,所以要求形参为指针变量