Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 向指针添加整数_C_Pointers_Variables_Integer - Fatal编程技术网

C 向指针添加整数

C 向指针添加整数,c,pointers,variables,integer,C,Pointers,Variables,Integer,所以,我把C语言中的指针弄乱了 int o = 10; int x = 20; int *pA = NULL; pA = &o; 将一个整数添加到 指针 pA+=x; 指针中存储的地址已从更改为 0000000000 61FE18 到 0000000000 61fe68 在使用*pA检查地址指向的值之后,该值为0,我可以使用 *pA += x; 和*pA变为等于20,但变量o中存储的值仍然是10 有人能解释一下这里发生了什么吗?指针指向的新地址在添加常量值后,取决于它指向的类型: N

所以,我把C语言中的指针弄乱了

int o = 10;
int x = 20;
int *pA = NULL;
pA = &o;
将一个整数添加到 指针 pA+=x; 指针中存储的地址已从更改为 0000000000 61FE18 到 0000000000 61fe68

在使用*pA检查地址指向的值之后,该值为0,我可以使用

*pA += x;
和*pA变为等于20,但变量o中存储的值仍然是10


有人能解释一下这里发生了什么吗?

指针指向的新地址在添加常量值后,取决于它指向的类型:

NewAddress = OldAddress + ConstantValue * sizeof ( Type )
所以,在普通数学中,如果pA+=x,那么

new_address_pointed_by_pA = old_address_pointed_by_pA + x * sizeof( int )
由于x=20,并且机器中的一个整数是4字节大,因此

new_address_pointed_by_pA = old_address_pointed_by_pA + 20*4 = 
                          = old_address_pointed_by_pA + 80
这正是您所经历的,因为0x61FE68-0x61FE58=0x50。实际上,您的地址是用十六进制格式表示的。因此,新地址比旧地址大0x50=80,这与我上面给出的简单计算结果相符

那个新地址包含什么?嗯,我们不知道。它取决于特定内存位置的历史记录

如果它从未被使用过,那么它包含0也就不足为奇了。而且还预计在*pA=x之后,它包含20个。同样,它最初指向的位置保持不变也就不足为奇了

但是。。。通过该赋值,您可以引发分段错误异常。当访问未分配给任务的内存位置时,操作系统通常会发出此信号。
因此,在使用指针时要注意,确保对指针执行的任何算术运算都会产生合法的新值。

这里有一个小程序,可以稍微解释一下指针算术

#include <stdio.h>

#define PRINTDIFF(type, p1, p2) printf("sizeof(%s) = %zu p1=%p p2 = %p diff(bytes) = %zi \ndiff(objects) = %zi diff(bytes)/sizeof(%s) = %zi\n\n", \
                                #type, sizeof(type), \
                                (void *)(p1), \
                                (void*)(p2), \
                                ((char *)(p2) - (char *)(p1)), \
                                (p2) - (p1),\
                                #type, \
                                ((char *)(p2) - (char *)(p1)) / sizeof(type))


int main(void)
{
    short s;
    char c;
    int i;
    long long ll;
    long double ld;

    short *sp = &s;
    char *cp = &c;
    int *ip = &i;
    long long *llp = &ll;
    long double *ldp = &ld;

    PRINTDIFF(short, sp, sp + 10);
    PRINTDIFF(char, cp, cp + 500);
    PRINTDIFF(int, ip, ip + 5);
    PRINTDIFF(long long, llp, llp + 5);
    PRINTDIFF(long double, ldp, ldp + 5);
}
顺便说一句,当你学习的时候,你应该尝试自己写一些简短的程序,这将帮助你理解C语言。学习C没有简单、轻松的方法指针pA本身由x的值乘以pA所指向的类型的大小来递增,并且等于x的大小,即int

因此,假设sizeofint或sizeofx为4,x的值为20,最终将pA的指针值乘以80,因为4*20=80,这与测试结果相匹配

0x61FE68-0x61FE18=0x50=80d

将整数添加到指针后 pA+=x。。。。并使用*pA检查地址指向的值,该值为0

由于您将指针pA本身增加了20*sizeofint,且pA+=x;,pA不再指向任何有效对象,并且超出了它应该指向的对象的边界

若要以这种方式递增指针,将调用并取消引用此指针

它显示0只是情况的任意变化。你不能依赖任何东西。该值可以在下次执行时更改

。。。我可以使用*pA+=x向这个地址添加一个整数;然后,*pA等于20

如上所述,该行为未定义。pA不指向任何合法引用的对象

…但存储在变量o中的值仍然是30

o一点也没有改变。第一个语句为pA+=x;您增加了指针本身,而不是一开始就指向的对象

谁能解释一下这里发生了什么事


您使用第一个pA+=x;将指针pA增加了sizeofint*20;。其他一切都无法真正解释,因为行为只是未定义。

这是否回答了您的问题?添加到指针会使指针的大小增加它所指向的指针的许多倍。毕竟,p[5]与*p+5是相同的。例如,如果p[5]得到第6个int,那么p+5必须将指针向前移动5个int对象的大小。你永远不会碰到o的值,之后它仍然应该是10。“30”是从哪里来的?我的错,我忘了在将x添加到你测试过的代码上的指针之前,我也将x添加到了o中,否则你会浪费时间/精力:@P_uj_uu你误解了我的目标。这不是C,而是简单的算术。我的目标是向OP展示实现他们体验的结果的不同步骤。我通常听取建议,但我不想换成那种表达方式。我可以改变我的表达方式,这样就可以清楚地看出这是一个简单的说教式的计算吗?@RobertoCaboni我这样做了,但你不能用这个语法。这是简单的误导。把更多的精力放在解释和解释上equations@P__J__我承认这是误导。格哈德(Gerhardh)在上面看到了我的评论。用简单的数学而不是C代码来演示这些步骤,这无疑是一种误导。现在我已经改变了符号,应该更清楚了。
sizeof(short) = 2 p1=0x7ffe0660eb76 p2 = 0x7ffe0660eb8a diff(bytes) = 20 
diff(objects) = 10 diff(bytes)/sizeof(short) = 10

sizeof(char) = 1 p1=0x7ffe0660eb75 p2 = 0x7ffe0660ed69 diff(bytes) = 500 
diff(objects) = 500 diff(bytes)/sizeof(char) = 500

sizeof(int) = 4 p1=0x7ffe0660eb70 p2 = 0x7ffe0660eb84 diff(bytes) = 20 
diff(objects) = 5 diff(bytes)/sizeof(int) = 5

sizeof(long long) = 8 p1=0x7ffe0660eb68 p2 = 0x7ffe0660eb90 diff(bytes) = 40 
diff(objects) = 5 diff(bytes)/sizeof(long long) = 5

sizeof(long double) = 16 p1=0x7ffe0660eb50 p2 = 0x7ffe0660eba0 diff(bytes) = 80 
diff(objects) = 5 diff(bytes)/sizeof(long double) = 5