C语言基础-指针

指针是一种保存变量地址的变量。

  • 变量放在机器中有编号的存储单元中,就像变量放在房间里,房间有门牌号
  • 指针这种变量专门用来存放门牌
  • 一般而言,一个存储单元存储8位,比如一个int类型占位32位,那么它就被放在四个连续的存储单元中,而指针变量一般存放变量存储最开始的那个存储单元的地址
指针类型变量声明
数据类型 *变量名;
  • 和普通变量声明一致,就是在变量名前加了个星号*
    代码示例
int *pi;//声明了一个变量pi,用他来存放int类型变量的地址
char *pc; //声明了一个变量pi,用他来存放char类型变量的地址
  • 也可以叫pi为指向int类型的指针
  • 指针只能指向特定类型的对象
指针类型变量使用
  • 如何获取变量地址
    • 使用&操作符可以得到变量的地址
数据类型 *变量名 = &之前声明过的变量名;

代码示例

int a = 10;
int *pa = &a;//将变量a的地址赋值给指针变量
  • 如何通过指针来操作变量
    • 使用*操作符间接引用变量,访问指针指向的内容
*指针变量名; //获取指针指向的内容

代码示例

#include <stdio.h>
int main(int argc, char const *argv[])
{
	int a = 10;
	int b;
	int *pa = &a;
	
	b = *pa; // 将pa指针指向的内容赋值给b,b=10
	*pa = 100; // pa指针指向的内容变更为100,那么a也将变更为100
	
	printf("a:%d\n", a); // 100
	printf("b:%d\n", b); // 10
	
	return 0;
}

运行结果:

a:100
b:10
指针与数组
指针访问数组元素
  • 指针运算符
    • 指针可以应用++/–/+n/-n运算
      • +1表示指针后移一个数据类型单元
      • -1表示指针前移一个数据类型单元
  • 数组是一组连续的数据类型存储单元
    • 数组元素依序占据数据类型单元
  • 可以应用指针运算前后移动访问数组元素
    代码示例
#include <stdio.h>

int main(int argc, char const *argv[])
{
	int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int *pi = &a[2]; // 指针指向数组中的某个元素
	
	printf("pi point to %d\n", *pi); //3
	pi++; //指针后移一个数据类型单元,指向a[3]
	printf("pi point to %d\n", *pi); //4
	pi--;//指针前移一个数据类型单元,指向a[2]
	printf("pi point to %d\n", *pi); //3
	
	return 0;
}

运行结果:

pi point to 3
pi point to 4
pi point to 3
数组名也是指针
  • 数组名可以直接赋值给指针变量
  • 数组名这个指针只能指向数组首元素,不能指向其他地方
  • 数组名可以通过对数组名+n来访问数组元素
  • 指针也可以通过[下标]的方式来访问数组元素
    代码示例
#include <stdio.h>

int main(int argc, char const *argv[])
{
	int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int *pi = a;//数组名可以直接赋值给指针,指针指向数组
	
	printf("a[0] %d\n", *a); //a[0]
	printf("a[4] %d\n", *(a+4)); //a[4]
	printf("pi point to a[2] %d\n", pi[2]); //指针可以通过下标方式访问数组元素
	//int i = 10;
	//a = &i;//a不能指向其他地方
	//a++;//非法
	
	return 0;
}

运行结果:

a[0] 1
a[4] 5
pi point to a[2] 3
指针数组

即存放指针类型变量的数组

数据类型 *数组名[数组大小];
  • 指针数组的数组名此时就会有个高大上的名字叫做:指向指针的指针
    代码示例
#include <stdio.h>

int main(int argc, char const *argv[])
{
	int *ppi[10]; //存放指针类型的数组
	int a = 10;
	int b = 100;
	int c = 1000;
	
	ppi[0] = &a;
	ppi[1] = &b;
	ppi[2] = &c;
	
	printf("a %d\n", *(*ppi));
	printf("b %d\n", *(*(ppi+1)));
	printf("c %d\n", *(ppi[2]));
	
	return 0;
}

运行结果:

a 10
b 100
c 1000
字符指针与字符串

字符指针可以指向字符串常量

  • 与字符数组接收字符串常量不同的是,通过字符指针不能修改字符串中的字符
    代码示例
#include <stdio.h>

int main(int argc, char const *argv[])
{
	char *pc = "hello";
	
	printf("string is : %s\n", pc);
	printf("the seccond char is %c\n", *(pc+1));
	printf("the third char is %c\n", pc[2]);
	
	pc[4] = 'a';//会有问题,结果不确定,不要通过字符指针修改字符串常量
	
	return 0;
}

运行结果:

string is : hello
the seccond char is e
the third char is l
zsh: bus error  ./a.out //您的结果可能和我的不同
指针与结构体

指向结构体的指针

struct 结构体类型 *指向结构体的指针名;
  • 通过指向结构体的指针访问结构体时,可以使用->操作符
    代码示例
#include <stdio.h>

int main(int argc, char const *argv[])
{
	struct point{
		int x;
		int y;
	} p1;
	
	struct point *ps = &p1;
	
	(*ps).x = 1;
	ps -> y = 3; //可以使用->操作符访问结构体成员
	
	printf("point is (%d, %d)\n", ps -> x, ps -> y);
	
	return 0;
}

运行结果:

point is (1, 3)
指针与函数参数
  • 指针类型可以作为函数参数类型
  • 指针类型形参和普通类型形参的区别
    • 普通类型形参,函数接收的是参数的副本,在函数中修改的也只是参数副本,对参数本身没有任何影响
    • 指针类型形参,接收的是参数的地址,在函数中对指针内容的修改,将直接反应到参数本身上
      代码示例
#include <stdio.h>

void swap(int a, int b);
void swap2(int *a, int *b);

int main(int argc, char const *argv[])
{
	int a = 10;
	int b = 20;
	
	swap(a, b);
	printf("after-swap a is: %d\n", a);
	printf("after-swap b is: %d\n", b);
	swap2(&a, &b);
	printf("after-swap2 a is: %d\n", a);
	printf("after-swap2 b is: %d\n", b);
	
	return 0;
}

void swap(int a, int b){ //只是修改参数副本,不影响参数本身
	int temp = 0;
	temp = a;
	a = b;
	b = temp;
	printf("in-swap a is: %d\n", a);
	printf("in-swap b is: %d\n", b);
}

void swap2(int *a, int *b){
	int temp = *a;
	*a = *b;
	*b = temp;
	printf("in-swap2 a is: %d\n", *a);
	printf("in-swap2 b is: %d\n", *b);
}

运行结果:

in-swap a is: 20
in-swap b is: 10
after-swap a is: 10
after-swap b is: 20
in-swap2 a is: 20
in-swap2 b is: 10
after-swap2 a is: 20
after-swap2 b is: 10
指向函数的指针
  • 可以通过指向函数的指针访问函数
  • 这种类型的指针和其他指针变量一样,可以被修改赋值,可以放在数组中,可以当作函数参数,可以当作函数返回值
函数返回值类型 (*函数指针名)(参数列表);//声明指向函数的指针
(*函数指针名)(传参列表); //通过指向函数的指针访问函数

代码示例

#include <stdio.h>

void swap2(int *a, int *b);

int main(int argc, char const *argv[])
{
	int a = 10;
	int b = 20;
	void (*swap)(int *, int *) = swap2;//定义swap指向swap2函数
	
	(*swap)(&a, &b); //通过函数指针访问函数
	printf("after-swap a is: %d\n", a);
	printf("after-swap b is: %d\n", b);
	
	return 0;
}

void swap2(int *a, int *b){
	int temp = *a;
	*a = *b;
	*b = temp;
	printf("in-swap2 a is: %d\n", *a);
	printf("in-swap2 b is: %d\n", *b);
}

运行结果:

in-swap2 a is: 20
in-swap2 b is: 10
after-swap a is: 20
after-swap b is: 10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值