C语言——指针详解(一)

本文详细解析了指针的概念、定义、使用方法,包括如何通过指针访问和修改变量,以及指针在函数参数传递和返回值中的应用。通过多个实例和代码示例,展示了指针在C语言编程中的核心作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、指针是什么?

要知道什么是指针,先来了解下指针的存储和读取。

当我们在对程序编译时,会为变量分配存储单元。如我们定义int a=10;就是为a这个整型变量分配了4个字节。内存区的每一个字节都有一个编号,这就是“地址”,相当于旅馆中的房间号。在里面存数据就相当于在这个房间中住旅客了。

由于通过地址能找到变量单元,所以我们说地址指向这个变量单元。

二、指针的定义和使用

1、小例子看指针

int a = 10;————>定义了一个整型变量,并赋值为10;

int *p;——————>定义了一个指针,这里的*仅仅表示p一个指针,没有其他任何含义;

p=&a;——————>我们把p指针指向了a,也表示把a的地址给了p;

printf(“a=%i\t;p=%p\t;p指向的值是:%d\n”,a,p,*p);———>我们分别打印a的值,p的地址值,p指向的地址里面的内容。

可以看出,当我们把p指向a时,我们可以说a和*p代表的是同一个东西。

所以指针的定义格式为:数据类型    *指针变量名

这里介绍两个符号 :

(1)&    取地址运算符。&a是变量a的地址。

(2)*    指针运算符(或叫“间接访问”运算符),*p代表指针变量p指向的对象。

2、变量访问方式

①直接访问 :通过变量名或地址访问变量的存储区。

②间接访问:将一个变量的地址存放在另一个变量中。如:将变量 a 的地址存放在变量p 中, 访问a 时先找到p,再由p 中存放的地址找到 a。

3、注意:

(1) 在变量定义时,* 号表示该变量是指针变量。

(2)定义指针变量后,系统为其分配存储空间, 用以存放其他变量的地址, 但在对指针变量赋值前,它并没有确定的值,也不指向一个确定的变量。

(3)p与*p不同,p是指针变量, p的值是p所指向的变量的地址。 *p 是p 所指向的变量 ,*p的值是p所指向的变量的值。

(4)引用指针变量时的 * 与定义指针变量时的 * 不同的。定义变量时的 * 只是表示其后的变量是指针变量。      

4、简单的指针运算

我的错误:

int a=2,b=5,c,d,*p;

(1)         p=&a;

(*p)++;———>等价于a++;

P的值是a的地址,*p的值是2,p的值不变,完后*p的值加1变为3。

(2)         c=*p++;———>等价于c=*(p++);

执行后c的值为3,*p的值为5。

(3)         d=*++p;———>d*(++p);

执行后d为3,*p为3。

注意:上面这是错的,为什么我也要写出来呢?因为这是很容易忽视的问题,那就是顺序存储。我们自认为我们的指针能一级往下找,其实不是这样的,通过下图就明白 了。

这与我们预料的完全不一样,从这里可以看出P++其实是加了一int的长度,即把指针往后挪4个字节。

4、下面求2个数的大小的程序,我们可以看出,指针也有类似于“单向值传递”的规律。

 

int *p1,*p2,*p,a,b,max,min;

  scanf("%d %d",&a,&b);

  p1=&a;

  p2=&b;

  if (a<b)

  {

        p=p1;

        p1=p2;

        p2=p;

  }

  printf("a=%d,b=%d\n",a,b);

  printf("max=%d,min=%d\n",*p1,*p2);

这儿知道只是指针变换了一下,等于把门牌号换了一下,但是旅客并没有变。

 

三、指针和函数

(1)指针变量做为函数参数

void test1(int num1,int num2)

{

       //单向值传递,不改变实参a,b的值

       int temp;

       temp = num1;

       num1 = num2;

       num2 = temp;

}

void test2(int *p1,int *p2)

{    

       //交换了p1,p2变量的值,所以a和b的位置也会换掉

       int temp;

       temp = *p1;

       *p1 = *p2;

       *p2 = temp;

}

void test3(int *p1,int *p2)

{

       //只是挪了指针,但是变量的值还是没有变,等于换门牌号(指针指的位置变化)

       int *temp;

       temp=p1;

       p1=p2;

       p2=temp;

}

int main()

{ int a,b,*ptr1,*ptr2;

printf("输入两个数比较:\n");

scanf("%d%d",&a,&b);

printf("原 值:\t a = %d   b = %d\n",a,b);

ptr1 = &a;

ptr2 = &b;

test1(a,b);

//对他们进行分别调用,可以看出其中的差别

printf("调用test1后:a = %d   b =%d\n",a,b);

//test2(ptr1,ptr2);

//printf("调用test2后:a = %d   b =%d\n",a,b);

//test3(ptr1,ptr2);

//printf("调用test3后:a = %d   b =%d\n",a,b);

       getchar();

       getchar();

//printf("max = %d  min =%d",max min);

return 0;

}

#include <stdio.h>
void test1(int num1,int num2)
{
	//单向值传递,不改变实参a,b的值
	int temp;
	temp = num1;
	num1 = num2;
	num2 = temp;
}

void test2(int *p1,int *p2)
{	
	//交换了p1,p2变量的值,所以a和b的位置也会换掉
	int temp;
	temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

void test3(int *p1,int *p2)
{
	//只是挪了指针,但是变量的值还是没有变,等于换门牌号(指针指的位置变化)
	int *temp;
	temp=p1;
	p1=p2;
	p2=temp;	
}
int main()
{ int a,b,*ptr1,*ptr2;
printf("输入两个数比较:\n");
scanf("%d %d",&a,&b);
printf("原 值:\t a = %d   b = %d\n",a,b);
ptr1 = &a;
ptr2 = &b;
test1(a,b);
printf("调用test1后:a = %d   b = %d\n",a,b);

//test2(ptr1,ptr2);
//printf("调用test2后:a = %d   b = %d\n",a,b);

//test3(ptr1,ptr2);
//printf("调用test3后:a = %d   b = %d\n",a,b);
	getchar();
	getchar();

//printf("max = %d  min =%d",max min);
return 0;
}



解释见函数调用时的注释,挨得近,看得明白

(2)函数返回指针

前面我们用到的函数, 有些无返回值, 有些有返回值,一个函数的返回值也可以是一个指针类型的数据。

定义结构:

                   数据类型    *函数名(形参表)

                     {函数体;}

说明:定义一个返回指针值的函数与以前定义函数格式基本类似, 只是在函数名前加 *  , 它表明该函数返回一个指针值。

(3)指向函数的指针

函数的指针: 函数的入口地址

    在程序执行过程中调用函数时, 计算机会转去执行函数体内的语句, 因此计算机必须知道函数在什么地方。实际上函数在内存中也要占据一片存储单元, 这片存储单元一个起始地址, 我们称其为函数的入口地址,即函数的指针, 这个函数的入口地址是用函数名来表示。

    因此我们可以定义一个指针变量, 让它的值等于函数的入口地址, 然后可以通过这个指针变量来调用函数, 该指针变量称为指向函数的指针变量。指针和数组。

1>定义结构:

数据类型    (*函数名)(形参表);

2>说明:

①数据类型: 指针变量所指向的函数的返回值类型

②形参表列: 即指针变量所指向的函数的形参表列

③格式中的小括号不能省略

④因为函数名为函数的入口地址,所以直接将函数名赋给指针变量即可

⑤使用指针变量调用函数格式 :  (*指针变量名)( 实参表列)

#include <stdio.h>

int add( int   b[ ] , int   n);

void main( )

{ int  a[6]={ 1, 3, 5, 7, 9, 11},total ;

   int  (*pt) ( int  b[ ] , int n ) ;  

   pt = add ;

   total = (*pt) ( a , 6 ) ;                 

   printf( “total = %d \n” ,total ) ;

 }

int add( int   b[ ] , int   n )

{ int  i , sum = 0 ;

   for ( i = 0 ; i<n ; i++ )

         sum = sum+b[i];

   return(sum);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值