C语言中指针的加减运算

本文深入解析了C语言中指针与数组的关系,包括字符数组与字符指针数组的内存分配,以及指针的加减运算原理。通过实例演示了如何使用指针访问数组元素,展示了不同类型的指针在内存中的位置及指向的数据。

参考文章,值得一看

    char arr[3];
    printf("arr:\n%d\n%d\n%d\n", arr, arr + 1, arr + 2);
    char *parr[3];
    printf("parr:\n%d\n%d\n%d\n", parr, parr + 1, parr + 2);

输出结果1

从结果可以看到,字符数组每个元素占1字节,字符指针数组每个占4字节。
再看一个例子:

    char a = 'a', b = 'b', c = 'c', d = 'd';
    char *arr[20] = {&a,&b,&c,&d};
    char **parr = arr;  //arr的类型也是char**
    char *str;
    printf("&a:%d,&b:%d,&c:%d,&d:%d\n",  &a, &b, &c, &d);
    printf("&arr[0]:%d,&arr[1]:%d,&arr[2]:%d,&arr[3]:%d\n", &arr[0], &arr[1], &arr[2], &arr[3]);
    printf("arr:%d,parr:%d\n", arr,parr);
    printf("*parr:%d,**parr:%c\n", *parr, **parr);
    str = *parr;   //arr[0],char*类型
    printf("-----  str=*parr  -----\n");
    printf("str:%d,*str:%c\n", str, *str);
    str++; 
    printf("-----  str++  -----\n");
    printf("str:%d,*str:%c\n", str, *str);
    
    str = *(parr + 1);
    printf("-----  str=*(parr+1)  -----\n");
    printf("str:%d,*str:%c\n", str, *str);
    str = *(parr + 2);  //*(arr+2*4)
    printf("-----  str=*(parr+2)  -----\n");
    printf("str:%d,*str:%c\n", str, *str);

输出结果2
指针的加减运算,就是将指针当前值与sizeof(指针指向的类型)相加减
比如上例中str=*parr,这时str当前值为arr[0],指向的类型是一个字符(所以大小为1字节),str++就代表arr[0]+1*1,但是由于指针数组的每一项占4字节,所以之后的*str输出为?。
再比如上例中str=*(parr+1),指针parr当前值为arr,指向的类型是一个字符指针char*类型(所以大小为4字节),parr+1就代表arr+1*4,向高地址方向移动4个字节,即&arr[0]+4==&arr[1],str就变成了arr[1],所以之后输出的*str为b。
另外

指针和指针进行加减:两个指针不能进行加法运算,这是非法操作,因为进行加法后,得到的结果指向一个不知所向的地方,而且毫无意义。两个指针可以进行减法操作,但必须类型相同,一般用在数组方面,不多说了。

转载于:https://www.cnblogs.com/wincent98/p/10158564.html

### C语言指针加减运算规则 在C语言中,指针加减运算是基于指针所指向的数据类型的大小来进行计算的。当对指针执行加法或减法操作时,编译器会根据指针类型自动调整偏移量。 对于`int *p`这样的指针来说,在32位系统上假设`sizeof(int)`等于4字节,则每增加1会使指针前进4个字节的位置;同理减少也会按照相应数据类型的长度向回退[^1]。 #### 指针加法实例展示 ```c #include <stdio.h> int main() { int numbers[] = {10, 20, 30}; int n; /* 获取数组首地址 */ int *ptr = numbers; ptr++; // 移动到下一个整数位置 n = *ptr; // 取出当前指针对应内存单元存储的内容 printf("Value at ptr: %d\n", n); } ``` 上述例子展示了如何使用`++`运算符让指针向前移动一位,并读取新位置处的数据值[^2]。 #### 关于指针与数组的关系说明 由于数组名称实际上代表了一个不可更改(即常量性质)的指针,因此可以直接用于初始化其他相同类型指针变量。而且,当我们提到访问某个特定索引下的元素时——比如`array[i]`——这实际上是被转换成了`(base_address + i)`形式的操作来完成定位工作[^3]。 #### 减法规则及应用案例分析 ```c #include <stdio.h> #define SIZE 5 void printArrayElements(int arr[], size_t length); int main(){ char str[SIZE]="hello"; char *strPtr=str+3;/* 让字符型指针指向字符串第四个字母'o' */ puts(str); /* 输出整个字符串 "hello"*/ putchar(*strPtr); /* 显示单独的一个字符 'o'*/ strPtr-=3; /* 返回至起始位置 */ puts(strPtr); /* 再次打印完整的单词 "hello" */ } // 辅助函数定义 void printArrayElements(int arr[], size_t length){ for(size_t idx=0 ;idx<length;++idx) printf("%d ",*(arr+idx)); } ``` 在这个程序里,通过改变指针相对于原始地址的位置实现了不同部分的选择性输出功能。特别是`strPtr -= 3;`这一句体现了指针能够安全有效地做减法的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值