C语言-指针第2课-C 指针的算术运算&指针数组

在我们的C程序中,每一个定义的变量,在内存中都占有一个内存单元,比如int类型占四个字节,char类型占一个字节等等,每个字节都在0~4,294,967,295之间都有一个对应的编号,C语言允许在程序中使用变量的地址,并可以通过地址运算符"&"得到变量的地址。

#include<stdio.h>

int main()

{       

    int i;       
    int a[10]={1,2,3,4,5,6,7,8,9,0};       
    char b[10]={'c','l','a','n','g','u','a','g','e'};       
    for(i=0;i<10;i++)       
    {               
        printf("int Address:0x%x,Value:%d\n",&a[i],a[i]);      
    }       
    printf("\n");       
    for(i=0;i<10;i++)       
    {               
        printf("char Address:0x%x,Value :%c\n",&b[i],b[i]);       
    }       
    return 0;
}

在32位linux系统下运行参考结果:(注意地址的变化)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

int Address:0xbfb949c4,Value:1

int Address:0xbfb949c8,Value:2

int Address:0xbfb949cc,Value:3

int Address:0xbfb949d0,Value:4

int Address:0xbfb949d4,Value:5

int Address:0xbfb949d8,Value:6

int Address:0xbfb949dc,Value:7

int Address:0xbfb949e0,Value:8

int Address:0xbfb949e4,Value:9

int Address:0xbfb949e8,Value:0

char Address:0xbfb949f2,Value :c

char Address:0xbfb949f3,Value :l

char Address:0xbfb949f4,Value :a

char Address:0xbfb949f5,Value :n

char Address:0xbfb949f6,Value :g

char Address:0xbfb949f7,Value :u

char Address:0xbfb949f8,Value :a

char Address:0xbfb949f9,Value :g

char Address:0xbfb949fa,Value :e

char Address:0xbfb949fb,Value :

 C 指针是一个用数值表示的地址。因此,您可以对指针执行算术运算。可以对指针进行四种算术运算:++、--、+、-。

递增一个指针

我们喜欢在程序中使用指针代替数组,因为变量指针可以递增,而数组不能递增,数组可以看成一个指针常量。下面的程序递增变量指针,以便顺序访问数组中的每一个元素:

#include <stdio.h>
 const int MAX = 3; 
 int main ()
 { 
    int var[] = {10, 100, 200}; 
    int i, *ptr; 

/* 指针中的数组地址 */ 
    ptr = var; 
    for ( i = 0; i < MAX; i++)
 { 
        printf("存储地址:var[%d] = %p\n", i, ptr ); 
        printf("存储值:var[%d] = %d\n", i, *ptr );

         /* 指向下一个位置 */ 
         ptr++; 
} 
    return 0; 
}

当上面的代码被编译和执行时,它会产生下列结果:

存储地址:var[0] = e4a298cc

存储值:var[0] = 10

存储地址:var[1] = e4a298d0

存储值:var[1] = 100

存储地址:var[2] = e4a298d4

存储值:var[2] = 200

注意地址的变化

递减一个指针

同样地,对指针进行递减运算,即把值减去其数据类型的字节数,如下所示:

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int  i, *ptr;
 
   /* 指针中的数组地址 */
   ptr = var;
   for ( i = 0; i < MAX; i++)
   {
      printf("存储地址:var[%d] = %p\n", i, ptr );
      printf("存储值:var[%d] = %d\n", i, *ptr );
 
      /* 指向下一个位置 */
      ptr++;
   }
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

存储地址:var[2] = 518a0ae4

存储值:var[2] = 200

存储地址:var[1] = 518a0ae0

存储值:var[1] = 100

存储地址:var[0] = 518a0adc

存储值:var[0] = 10

指针的比较

指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。

下面的程序修改了上面的实例,只要变量指针所指向的地址小于或等于数组的最后一个元素的地址 &var[MAX - 1],则把变量指针进行递增:

#include <stdio.h>
    const int MAX = 3; 
    int main () 
{ 
    int var[] = {10, 100, 200};
    int i, *ptr;

 /* 指针中第一个元素的地址 */ 
    ptr = var;
    i = 0;

     while ( ptr <= &var[MAX - 1] ) 
{
        printf("存储地址:var[%d] = %p\n", i, ptr ); 
        printf("存储值:var[%d] = %d\n", i, *ptr ); 
        /* 指向上一个位置 */ 
        ptr++; i++; 
} 
return 0; 
}

当上面的代码被编译和执行时,它会产生下列结果:

存储地址:var[0] = 0x7ffeee2368cc

存储值:var[0] = 10

存储地址:var[1] = 0x7ffeee2368d0

存储值:var[1] = 100

存储地址:var[2] = 0x7ffeee2368d4

存储值:var[2] = 200

C 指针数组

在我们讲解指针数组的概念之前,先让我们来看一个实例,它用到了一个由 3 个整数组成的数组:

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int i;
 
   for (i = 0; i < MAX; i++)
   {
      printf("Value of var[%d] = %d\n", i, var[i] );
   }
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:  

Value of var[0] = 10

Value of var[1] = 100

Value of var[2] = 200

假如想要让数组存储指向 int 或 char 或其他数据类型的指针。下面是一个指向整数的指针数组的声明: 

int *ptr[MAX];

在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成。因此,ptr 中的每个元素,都是一个指向 int 值的指针。下面的实例用到了三个整数,它们将存储在一个指针数组中,如下所示: 

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};  //定义一个数组
   int i, *ptr[MAX];                //定义指针
 
   for ( i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; /* 把数组复制给了指针 */
   }
   for ( i = 0; i < MAX; i++)
   {
      printf("Value of var[%d] = %d\n", i, *ptr[i] );//打印变量
      printf("Value of var[%d] = %p\n", i, ptr[i] );//打印地址   }
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果: 

 Value of var[0] = 10
Value of var[0] = 0x7ffc8ef159c4
Value of var[1] = 100
Value of var[1] = 0x7ffc8ef159c8
Value of var[2] = 200
Value of var[2] = 0x7ffc8ef159cc

C语言数组与指针的区别与联系 

前面我们已经知道,通过数组下标可以确定数组元素在数组中的顺序和存储地址。由于每个数组元素 相当于一个变量,因此指针变量可以指向数组中的元素,也就是说可以用指针方式访问数组中的元素。 对一个指向数组元素的指针变量的定义和赋值方法,与指针变量相同。例如: 

int a[10];         /*定义 a 为包含 10 个整型数据的数组*/

int *p;              /*定义 p 为指向整型变量的指针*/

p=&a[0];         /*把 a[0]元素的地址赋给指针变量 p*/

C 语言规定,数组名代表数组的首地址,也就是第 0 号元素的地址。因此: 

1

2

p=a;                 /*等价于 p=&a[0]; */

int *p=a;         /*等价于 int *p=&a[0]; */

对于指向首地址的指针 p,p+i(或a+i)就是数组元素 a[i]的地址,*(p+i)( 或*(a+i) )就是 a[i]的值。 
如果指针变量 p 已指向数组中的某一个元素,则 p+1 指向同一数组中的下一个元素。 
引入指针变量后,就可以用以下两种方法来访问数组元素: 
(1)下标法:即用 a[i]形式访问数组元素,在前面介绍数组时都是采用这种方法。 
(2)指针法:即采用*(a+i)或*(p+i)形式,用间接访问的方法来访问数组元素,其中 a 是数组名,p 是
指向数组的指针变量,其初值 p=a。

#include<stdio.h>
int main()
{
        int i;
        int a[10]={1,2,3,4,5,6,7,8,9,0};
        int *p=a;    //数组 a 赋值给了指针 P
        for(i=0;i<10;i++)
        {
            printf("P Value:%d   a Value :%d\n",*(p++),*(a+i));
        }
        printf("\n");
        return 0;
}

 当上面的代码被编译和执行时,它会产生下列结果:

P Value:1   a Value :1
P Value:2   a Value :2
P Value:3   a Value :3
P Value:4   a Value :4
P Value:5   a Value :5
P Value:6   a Value :6
P Value:7   a Value :7
P Value:8   a Value :8
P Value:9   a Value :9
P Value:0   a Value :0

注意输出的两种方式,指针可以通过++或--并修改自身值的方式移动,然而数组名本身值不可以被更改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值