关于指针_2

下面写的是一个关于指针的比较经典的例子——互换两个数

1

# include <stdio.h>

void huhuan_1(int, int);
void huhuan_2(int *, int *);
void huhuan_3(int *, int *);

int main(void)
{
	int a = 3;
	int b = 5;

	//	huhuan_2(&a, &b);
	//  huhuan_2(*p, *q); 是错误的  huhuan_2(a, b); 也是错误的
	huhuan_3(&a, &b);
	printf("a = %d, b = %d\n", a, b);

	return 0;
}

void huhuan_1(int a, int b)  //不能完成互换功能
{
	int t;
	t = a;
	a = b;
	b = t;

	return;
}

void huhuan_2(int * p, int * q)  //不能完成互换功能
{
	int * t;  //如果要互换p和q的值 t必须是int * ,不能是int
	t = p;
	p = q;
	q = t;
}

void huhuan_3(int * p, int * q)  //可以完成互换功能
{
	int t;  //如果要互换*p和*q的值,则t必须定义成int,不能定义成int *,否则语法出错

	t = *p;//p是int *,*p是int  
	*p = *q;
	*q = t;
}

输出结果为:

这个程序需要好好看看,要明白为什么前两个函数为什么不能实现两个数的互换


附注:

的含义:

  1、乘法

2、定义指针变量

int * p; 

//定义了一个名字叫p的变量,int * 表示p只能存放int变量的地址

3、指针运算符

该运算符放在已经定义好的指针变量的前面

如果p是一个已经定义好的指针变量

则 *p表示以p的内容为地址的变量


如何通过被调函数修改主调函数普通变量的值

1、实参必须为该普通变量的地址

2、形参必须为指针变量

3、在被调函数中通过

*形参名 = ......

的方式就可以修改主调函数相关变量的值


下面再说一个例子:利用指针使函数返回一个以上的值

2

# include <stdio.h>

int f(int i, int j)
{
	return 100;
	//	return 88;
}

void g(int * p, int * q)
{
	*p = 1;
	*q = 2;
}

int main(void)
{
	int a = 3, b = 5;
	g(&a, &b);
	printf("%d %d\n", a, b);
	return 0;
}

输出结果为:

指针和数组

指针和一维数组

一维数组名

一维数组名是一个指针变量

它存放的是一维数组第一个元素的地址

下面举个例子说明一下

3

# include <stdio.h>

int main(void)
{
	int a[5];// a是数组名,5是数组元素的个数,元素就是变量 从a[0]—a[4]
//	int a[3][4]; //3行4列  a[0][0]是第一个元素  a[i][j]是第 i+1 行 j+1 列个元素
	int b[5];

//	a = b;//错误 a是常量
	printf("%#x\n", &a[0]);
	printf("%#x\n", a);

	return 0;
}

输出结果为:

下标和指针的关系

如果p是个指针变量, 则

p[i]永远等于 *(p+i)

4

# include <stdio.h>

int main(void)
{
	int a[5] = {1, 2, 3, 4, 5};
	int i;
	
	for (i=0; i<5; ++i)
		printf("%d\n", a[i]);  //a[i] == *(a+i) 
	
	return 0;
}

输出结果为:

 确定一个一位数组需要几个参数【如果一个函数要处理一个一位数组,则需要接受该数组的哪些信息】

需要两个参数:

数组第一个元素的地址

数组的长度

下面举几个例子

5

# include <stdio.h>

//f函数可以输出任何一个一位数组的内容
void f(int * pArr, int len)
{
	int i;

	for(i=0; i<len; ++i)
		printf("%d ", *(pArr+i) ); // *pArr *(pArr+1) *(pArr+2) 
	printf("\n");
}

int main(void)
{
	int a[5] = {1, 2, 3, 4, 5};
	int b[6] = {-1, -2, -3, 4, 5, -6};
	int c[100] = {1, 99, 22, 33};

	f(a, 5); // a是 int *
	f(b, 6);
	f(c, 100);

	return 0;
}

输出结果为:

6

# include <stdio.h>

void f(int * pArr, int len)
{
	pArr[3] = 88;  //5行
}

int main(void)
{
	int a[6] = {1, 2, 3, 4, 5, 6};
	printf("%d\n", a[3]); // 11行
	f(a, 6);
	printf("%d\n", a[3]); // 13行

	return 0;
}

一定要明白 5行的pArr[3] 11行、13行的a[3]是同一个变量

输出结果为:

7

# include <stdio.h>

void f(int * pArr, int len)
{
	int i;
	
	for(i=0; i<len; ++i)
		printf("%d ", pArr[i] ); // *(pArr+i) 等价于 pArr[i]
	printf("\n");
}

int main(void)
{
	int a[5] = {1, 2, 3, 4, 5};
	int b[6] = {-1, -2, -3, 4, 5, -6};
	
	f(a, 5);
	f(b, 6);
	
	return 0;
}

输出结果为:

指针变量的运算

指针变量不能相加 不能相乘 也不能相除

如果两个指针变量指向的是同一块连续空间中的不同存储单元,

则这两个指针变量才可以相减

8

# include <stdio.h>

int main(void)
{
	int i = 5;
	int j = 10;
	int * p = &i;
	int * q = &j;
	int a[5];
	p = &a[1];
	q = &a[4];
	printf("p 和 q 所指向的单元相隔 %d 个单元\n", q-p);
//	p-q 没有实际意义

	return 0;
}

输出结果为:


一个指针变量到底占几个字节[非重点]

预备知识:

sizeof(数据类型)

功能:返回值就是该数据类型所占的字节数 

例子:sizeofint) =  4   sizeofchar) =  1

  sizeofdouble) =  8

  sizeof(变量名

功能:返回值是该变量所占的字节数

假设p指向char类型变量(1个字节)

假设q指向int类型变量(4个字节)

假设r指向double类型变量(8个字节)

p q r 本身所占的字节数是否一样?

答案:p  q  r 本身所占的字节数是一样的

请看下例

9

# include <stdio.h>

int main(void)
{
	char ch = 'A';
	int i = 99;
	double x = 66.6;
	char * p = &ch;
	int * q = &i;
	double * r = &x;

	printf("%d %d %d\n", sizeof(p), sizeof(q), sizeof(r));

	return 0;
}

输出结果为:

总结:

一个指针变量,无论它指向的变量占几个字节

一般情况下,该指针变量本身只占4个字节

一个变量的地址是用该变量首字节的地址来表示


【所有代码均在windows系统下VC++6.0下运行通过】

(如有错误,敬请指正)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值