【无标题】

1.指针定义

        指针其实很简单。同C语言中其他变量一样,把指针也看成是一种变量即可,这种变量专门存储地址值

int a = 100;
int* b = &a;

变量和指针的类型必须相同

2.指针的调用

        若直接调用函数调换a,b的值,结果a,b的值并没有交换成功。原因是:C程序在调用函数时使用“按值调用”,这意味着变量的值直接从调用函数复制到被调函数的实参中,“按值调用”是C语言中调用函数的唯一方式。

下列所示;

void swap(int* x, int* y)
{
    int tmp = *x;
    *x = *y;
    *y = tmp;   
}
void change()
{
    int a = 100;
    int b = 200;
    swap(&a, &b);
}

一个函数只能访问自己的栈帧

3.指针的运算

  • 指针p加上整数j表示指针向后移动j个单位(每个单位大小为指针p的类型所占的字节数),指向p原先指向的元素后的第j个元素。若p指向数组a[i],则p+j指向a[i+j]
  • 指针p减去整数j表示指针向前移动j个单位,指向p原先指向的元素前的第j个元素。若p指向数组a[i],则p-j指向a[i-j]
  • 两个指针相减,得到的是指针之间元素的个数。若指针p指向a[i],指针q指向a[j],则p-q等于i-j
  • 指针的比较依赖于指针所指向的两个元素的相对位置。若指针p指向a[i],指针q指向a[j],pq的比较结果由ij的大小决定。

                  因此适用于指针运算的运算符包括算术运算符+-,赋值运算符和复合赋值运算符(=+=,’-=’,++--)和所有的关系运算符

4.指针与数组

用指针表示数组

(1). 下标法

# include<stdio.h>

int main()
{
	int i,a[5];

    printf("Please enter 5 integer numbers:\n");
	for(i=0;i<5;i++)
		scanf("%d",&a[i]);
	for(i=0;i<5;i++)
		printf("%d ",a[i]);
	printf("\n");

	return 0;
}

(2). 通过数组名计算数组元素地址,找出元素的值

# include<stdio.h>

int main()
{
	int i,a[5];

	printf("Please enter 5 integer numbers:\n");
	for(i=0;i<5;i++)
		scanf("%d",&a[i]); // or scanf("%d",a+i)
	for(i=0;i<5;i++)
		printf("%d ",*(a+i));
	printf("\n");

	return 0;
}

(3). 用指针变量指向数组元素

法一:

# include<stdio.h>

int main()
{
	int i,a[5],*p;
	p = a; // or  p=&a[0]

	printf("Please enter 5 integer numbers:\n");
	for(i=0;i<5;i++)
		scanf("%d",p+i);
	for(i=0;i<5;i++)
		printf("%d ",*(p+i));
	printf("\n");

	return 0;
}

法二:

# include<stdio.h>

int main()
{
	int i,a[5],*p;

	printf("Please enter 5 integer numbers:\n");
	for(i=0;i<5;i++)
		scanf("%d",&a[i]);
	for(p=a;p<(a+5);p++)        //   a 代表数组首元素的地址,是一个指针型常量
		printf("%d ",*p);     	       
	printf("\n");

	return 0;
}

5.指针与指针变量

指针是程序数据在内存中的地址,而指针变量是用来保存这些地址的变量。

 用来保存 指针 的变量,就是指针变量
在这里插入图片描述
        由于内存中的每一个字节都有一个唯一的编号,因此,在程序中使用的变量,常量,甚至数函数等数据,当他们被载入到内存中后,都有自己唯一的一个编号,这个编号就是这个数据的地址。指针就是这样形成的。

6.声明一个指向函数的指针

void print(int num); // 声明函数
void (*funptr)(int) = print; // 声明指向函数的指针, 该函数接受一个int参数, 返回void, 并用print函数的地址初始化
  • 通过指向函数的指针调用函数
    事实上有三种调用方式可选:

print(10); // (1) 使用函数名调用print函数
(*funptr)(10); // (2) 使用指向函数指针解引调用print函数`
funptr(10); // (3) 使用指向函数指针直接调用print函数

(1)的执行过程是函数名print首先被转换成一个指向函数的指针, 该指针指向print函数在内存中的位置, 然后调用操作符调用print函数, 执行开始于这个位置的代码.
(2)的执行过程是解引操作将funptr转换为函数名, 然后执行(1)的操作, 显然解引操作不是必需的, 函数调用操作符需要的是一个指向函数的指针.
(3)的执行过程是函数调用操作符直接调用函数.

  • 声明 “指向函数的指针” 的指针
    指向函数的指针本质上仍然是一种指针, 我们可以按照二级指针声明指向它的指针.
void print(int num); // 声明函数
void (*funptr)(int) = &print; // 声明指向函数的指针
void (**funpptr)(int) = &funptr; // 声明 "指向函数的指针" 的指针
(**funpptr)(10); // 通过二级指针调用print
  • 声明元素类型为 “指向函数的指针” 的数组
    同样, 如果具有多个类型一样的指向函数的指针, 我们可以将它们放在一个数组中.
void print(int num); // 声明函数
void (*funptr)(int) = &print; // 声明指向函数的指针
void (*funptrarray[])(int) = funptr; // 声明元素类型为"指向函数的指针"的数组, 数组大小为1, funptrarray[0]用funptr初始化
(*funptrarray[0])(10); // 调用print
(**funptrarray)(10); // 等价的调用print

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值