Rub*_*ozo 9 c pointers operators pointer-arithmetic
我正在使用指向结构的指针.我想知道是否可以直接移动到特定位置而不使用++运算符.
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
struct dummy{
int id;
char buffer[10];
};
typedef struct dummy dummy_struct;
int main()
{
int i=0;
dummy_struct *ds = malloc(sizeof(dummy_struct)*ARRAY_SIZE);
dummy_struct *iterator = ds;
for(i=0;i<ARRAY_SIZE;i++)
{
iterator->id = i;
sprintf(iterator->buffer,"%d",i);
iterator++;
}
iterator = ds;
for(i=0;i<ARRAY_SIZE;i++)
{
printf("%d:%s:%p\n",iterator->id,iterator->buffer,iterator);
iterator++;
}
// I want to access directly to 5th position
iterator = ds + (sizeof(dummy_struct)*5);
printf("5th position %d:%s:%p\n",iterator->id,iterator->buffer,iterator);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个说法
iterator = ds + (sizeof(dummy_struct)*5);
Run Code Online (Sandbox Code Playgroud)
不管用.我将不胜感激任何建议.
Sou*_*osh 30
好吧,指针算术尊重数据类型!!
iterator = ds + 5;
Run Code Online (Sandbox Code Playgroud)
将完成工作.
详细说明,上面的表达式将通过将其移动5次,乘以类型的大小(ds以字节为单位)来生成指针.那是一样的&(ds[5]).
为了完整起见,解释为什么iterator = ds + (sizeof(dummy_struct)*5);是错误的,在这里,你实际上是在尝试将指针移动到索引的元素,因为(sizeof(dummy_struct)*5它超出了界限.请注意,这会调用未定义的行为 !! 请注意以下
引用C11,章节§6.5.6/ P8
当一个具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型.如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向偏离原始元素的元素,使得结果元素和原始数组元素的下标的差异等于整数表达式.换句话说,如果表达式
P指向i数组对象的-th元素,则表达式(P)+N(等效地N+(P))和(P)-N(其中N有值n)分别指向数组对象的i+n第-th和i?n-th元素,前提是它们存在.[....]
然后,关于上面提到的未定义的行为,
[....]如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义.如果结果指向数组对象的最后一个元素之后,则不应将其用作
*已计算的一元运算符的操作数.
话虽如此,printf()声明也是错误的.您有两个转换说明符,但提供了三个参数.它没有害处,但无用/无意义.
相关的,从章节§7.21.6.1/ P2,
[...]如果参数保留时格式已用尽,则会评估多余的参数(一如既往),否则将被忽略.[...]
基于这种情况,您可以直接使用
printf("5th position %d:%s:\n",ds[5].id,ds[5].buffer);
Run Code Online (Sandbox Code Playgroud)
的行为
iterator = ds + (sizeof(dummy_struct) * 5);
Run Code Online (Sandbox Code Playgroud)
如果将指针设置为超出数组最后一个元素的指针,则未定义.你实际上是在设置iterator数组中的元素而不是你想象的因素sizeof(dummy_struct)!不要那样做.
该语言允许您使用该表示法iterator = ds + 5;.这个惯用的指针算法为地址增加了5很多.换句话说,编译器会为您进行调整.这就是指针算法如此强大的原因之一.sizeof(dummy_struct)iteratorsizeof
最后请注意*(ds + 5)相当于ds[5].我发现后者在使用数组时更加清晰.
| 归档时间: |
|
| 查看次数: |
2861 次 |
| 最近记录: |