指针与数组专题

本文详细探讨了C/C++中的指针和数组。指针本质上是存储内存地址的变量,通过指针可以修改函数外的变量值。数组名是一个指针常量,指向数组的第一个元素。数组和指针的关系体现在数组下标相当于指针加偏移量。文章还介绍了如何通过指针和数组在函数间传递和修改数据。

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

一、指针

 

(一)定义

  •         地址

            内存单元的编号
            从0开始的非负整数
            范围0-FFFFFFFF 【0 到 4G-1】

  •         指针

            指针就是地址  地址就是指针
            指针变量就是存放内存单元地址的变量,不是变量里具体的值
            指针本质上就是一个操作受限的非负整数 

 

(二)例子

1、& 只能对明确的变量取地址

int i=0;
printf("Ox%x\n",&i);  //输出的是地址(有&),不是值
//Ox%x-->即 %p-->表输出地址,十六进制

int p;
p=(int)&i;  //int*转化为int
printf("Ox%x\n",p);  //输出的也是地址,与上面的&i的输出相同

2、int * p=&i;    //p保存i的地址,即p指向i。p是变量名字,int *表示该p变量只存储int类型变量的地址i是否赋值或修改值都不影响p,因为p指向的是i这个变量,而不是i的值。

int i;
//i=100;

//int * p=&i;  //即下面两行
int * p;
p=&i;

    int *p;   int k=55;    *p=k;     更正如下:

int *p;
int k,j;
k=55;

//*p=k;改成下两行
p=&k;
*p=k;  //即k=k

j=*p;  //即j=k

3、p是int指针,q是int变量,如下:

int* p,q;
int *p,q;

      p,q都是int指针,如下:

int *p,*q;

4、输出方式:

  • 一般输出
int *p;
int k,j;
k=55;

//*p=k;改成下两行
p=&k;
*p=k;  //即k=k
j=*p;  //即j=k

//下面两行输出的是地址
printf("%d",p);
printf("%d",&p);

//下面这行输出的是变量的值
printf("%d",*p);
  • 数组输出及其他相关
#include<stdio.h>
int main()
{
	int a[10];
	*a=25;	//即a[0]=25;

//	int * p=a; //即下两行
	int *p;
	p=a;

	//以下输出的都是a[0]的地址
	printf("Ox%x\n",p);
	printf("%p\n",&a);
	printf("%p\n",a);
	printf("%p\n",&a[0]);

//下面这行输出的是a[1]的地址,比a[0]大4,一个int的大小
	printf("%p\n",&a[1]);

	//以下输出的都是a[0]的值,即25
	printf("%d\n",p[0]);
	printf("%d\n",*a);

	return 0;
}

a[i]  <=>  *(a+i)  <=>  *(i+a)  <=>  i[a] 

                 *a+i   <=>  a[0]+i的结果

 

(三)指针应用 

1、通过被调函数修改主函数中普通变量的值

                Ⅰ    实参为相关变量的地址
                Ⅱ    形参为以该变量的类型为类型的指针变量
                Ⅲ    在被调函数中通过  *形参变量名 的方式就可以修改主函数相关变量的值

#include<stdio.h>

void f(int *p)
{    *p=100;  }

int main()
{
    int i=9;
    f(&i);
    printf("i=%d\n",i);

    return 0;
}

上面代码可以将主函数中的i=9改为100,输出为i=100。若去掉红色加粗部分,则还是输出为i=9。

下面的代码仅帮助理解(有**),虽然能执行,但程序内存上会有些问题,程序并不安全。。。

#include<stdio.h>

void f(int **q)
{    *q=(int*)0xFFFFFFFF;  }   //0是数字,非字母

int main()
{
    int i=9;
    int *p=&i;
    printf("%p\n",p);
    f(&p);    //&p=**p
    printf("%p\n",p);

    return 0;
}

2、函数返回多个值(传入的参数实际上是需要保存带回的结果的变量)

int swap(int *pa,int *pb)

{……} 

3、函数返回运算状态,结果通过指针返回

(常用套路:返回特殊的不属于有效范围内的值来表示出错(文件操作),当任何数值都是有效可能结果时,分开返回)

         状态-->return

     实际值-->指针参数返回

#include<stdio.h>

//注意 *result 和 ret
int divide(int a,int b,int *result)
{
	int ret=1;
	if(b==0)  ret=0;
	else  *result=a/b;
	return ret;
}

int main()
{
	int a=5,b=2,c;
	if(divide(a,b,&c))
		printf("%d/%d=%d\n",a,b,c);
	return 0;
}

二、数组


(一)基础知识

 1、数组名
                    一维数组名是个指针常量,
                    它存放的是一维数组第一个元素的地址, 
                    它的值不能被改变
                    一维数组名指向的是数组的第一个元素

 2、下标和指针的关系
                    a[i] <<==>> *(a+i)
                     *a  <<==>> a[0]
                    
                    假设指针变量的名字为p
                    则p+i的值是p+i*(p所指向的变量所占的字节数)   【p向后移i个位置】

 3、指针变量的运算
                    指针变量不能相加,不能相乘,不能相除
                    如果两指针变量属于同一数组,则可以相减
                    指针变量可以加减一整数,前提是最终结果不能超过指针允许指向的范围
                        p+i的值是p+i*(p所指向的变量所占的字节数)
                        p-i的值是p-i*(p所指向的变量所占的字节数)
                        p++  <==>    p+1
                        p--    <==>    p-1

4、数组元素个数=sizeof(a)/sizeof(a[0])
      优:修改数组中初试的数据,不需要修改遍历的代码

5、prime[count ++]=i;    //i给到数组prime[count],指针向后移一位(即count+1)

6、数组的表示:

int a[13]={[1]=2,4,[5]=6};  //C99Only 使用与数组稀疏  该数组:0 2 4 0 0 6 0……0

int a[10]={0}; // 该数组:0 0 0……0  ,即下面
/**
for(int i=0;i<10;i++)
    a[i]=0;
**/

7、数组与数组:

int a[]={5,6,2,8};
int b[]=a;    //数组变量本身不能被赋值
int b[4];  int b[];  
for(i=0;i<length;i++)
    b[i]=a[i];

(二)应用

1、通过被调函数修改主函数中一维数组的内容

   数组作函数参数时:
         1)无数组大小
         2)不能再利用sizeof来计算数组元素个数,往往必须再用另一个参数来传入数组大小 (如下例子中的length)

int search(int key,int a[],int length)   //a[]里没写大小,数组变量是特殊的指针。int a[]函数参数中等价于int *a
{……} 

数组输出修改的例子,可结合指针: 

#include<stdio.h>

void Show_Array(int *p,int len)
{
	int i;
	for(i=0;i<len;++i)
		printf("%d\n",p[i]);  //p[i]就是主函数的a[i]

	p[0]=-1;	//p[0]==*p  执行后a[0]的值就变成了-1
	p[4]=-4;    //执行后a[4]的值就变成了-4
}

int main(void)
{
	int a[5]={4,5,6,7,8};
	Show_Array(a,5);
	printf("a[0]=%d\n",a[0]);
	printf("a[4]=%d\n",a[4]);
	return 0;
}

 2、函数原型是等价的(函数中):

int sum(int *ar,int n);
int sum(int *,int);
int sum(int ar[],int n);
int sum(int [],int);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值