两个int指针之间的指针差异

时间:2016-11-21 06:43:19

标签: c pointers pointer-arithmetic

int main(void) {
    int *a;
    int *b = a++;
    printf("%d\n",b-a);
    return 0;
}

我预计输出为1为什么它是-1?

在上述问题中假设而不是a++我有++a

它仍然是未定义的行为吗?

6 个答案:

答案 0 :(得分:4)

第一个问题,正如我在这里看到的,主要是

 int *a;

a是自动本地的,初始值是不确定的(没有显式初始化),因此a++(或++a为此事件)调用undefined behavior

那说,关于指针扣除,请参阅why we need the operands of subtraction operator to be address of elements from same array object上的这个答案。

最后,两个指针的减法产生类型ptrdiff_t,您应该使用%td来打印结果。否则,你再次调用UB。

[如下面的评论所述]

假设指针已正确初始化,如

int k[5] = {0};
int * a = &(k[0]);
int *b = a++;
printf("%td\n",b-a);

在这种情况下,结果将是-1,因为这是两个元素的索引中的差异(请记住a++post-increment

章节§6.5.6/ 9,C11标准

  

当减去两个指针时,两个指针都指向同一个数组对象的元素,   或者超过数组对象的最后一个元素; 结果是差异   两个数组元素的下标。

答案 1 :(得分:4)

首先,您的代码会导致未定义的行为,因为它会读取和修改未初始化的变量。

还应使用说明符%td来打印指针差异。

假设指针a实际指向有效对象:

int i;
int *a = &i;
int *b = a++;
printf("%td\n",b-a);

postfix ++运算符给出操作数的当前值,然后将操作数增加1。以上代码与:

相同
int i;
int *a = &i+1;
int *b = &i;
printf("%td\n",b-a);

指针a指向一个超过对象i,指针b指向对象i。由于指针运算,减法将产生-1。如果操作是:a-b,则结果为1.

这是定义的行为。

答案 2 :(得分:3)

两个指针的差异(在这种情况下为(b-a))没有在C中定义,除非两个指针指向同一个数组的地址。

另外,由于指针' a'在你的代码中没有分配任何地址(包含垃圾值),做任何一种操作都是罪过。

如果你想看看两个指针的减法是如何工作的,那么试着定义一个数组并让这两个指针指向它。

答案 3 :(得分:0)

当您递增指针时,它不会将值添加到1.它只是告诉指针指向下一个位置。此外,您的指针从未初始化,它们只是指向随机垃圾数字。

答案 4 :(得分:0)

int *a是一个具有自动存储持续时间的变量,并且从不使用其地址(&a)。因此,代码调用未定义的行为(根据6.3.2.1,see this),并且您的程序不能有任何可预测的结果。

%d上使用ptrdiff_t格式说明符也会调用未定义的行为(7.21.6.1/9)。您应该使用%td ptrdiff_t%p作为指针。

因此,你不能指望你的程序。它可以输出任何内容,或者什么都不输,或者崩溃。

答案 5 :(得分:-1)

没有取消定义行为

当您声明* a时,指向内存位置 public class MyClientTask extends AsyncTask<Void, Void, Void> { String dstAddress; int dstPort; String response = ""; MyClientTask(String addr, int port) { dstAddress = addr; dstPort = port; } @Override protected Void doInBackground(Void... arg0) { // if (pingHost(1000)) { socket = null; try { socket = new Socket(dstAddress, dstPort); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024); byte[] buffer = new byte[1024]; DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); byte[] theByteArray = message.getBytes(); lengthMessage = (short) theByteArray.length; outputStream.writeByte((byte) 0xB); outputStream.writeByte((byte) 0xA); outputStream.writeByte((byte) 0xA); outputStream.writeByte((byte) 0xD); outputStream.writeShort(lengthMessage); outputStream.write(theByteArray); outputStream.writeShort(width); outputStream.writeShort(height); outputStream.writeInt(lengthbmp); outputStream.writeInt(lengthResizebmp); outputStream.writeShort(11); outputStream.write(imageInByte ); outputStream.write(imageResizeInByte); outputStream.writeByte((byte) 0xB); outputStream.writeByte((byte) 0xE); outputStream.writeByte((byte) 0xE); outputStream.writeByte((byte) 0xF); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } int bytesRead; InputStream inputStream = socket.getInputStream(); while ((bytesRead = inputStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, bytesRead); response += byteArrayOutputStream.toString("UTF-8"); } outputStream.flush(); outputStream.close(); } catch (UnknownHostException e) { e.printStackTrace(); isSuccsess = false; response = "UnknownHostException: " + e.toString(); } catch (IOException e) { e.printStackTrace(); Log.d("la", "nie udało sie"); isSuccsess = false; response = "IOException: " + e.toString(); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); if (socket != null) { try { socket.shutdownInput(); socket.shutdownOutput(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } if(isSuccsess){ Toast.makeText(MainActivity.this, "Zdjęcie zostało wysłane !" , Toast.LENGTH_LONG).show(); bm = null; clearEt(); ivImage.setImageBitmap(bm); } else{ Toast.makeText(MainActivity.this , "Nie udało się wysłać zdjęcia !" , Toast.LENGTH_LONG).show(); } pbWheel.setVisibility(View.INVISIBLE); } @Override protected void onPreExecute() { super.onPreExecute(); pbWheel.setVisibility(View.VISIBLE); } } ; b指向与a相同的位置, AND 增加a以指向比b指向的先前位置大1的位置。

*b = a++ //正确

我将举例说明

b - a = -1

我介绍 int main(void) { int *a; // 0x408 int *w = a++; // 0x400 int *b = a++; // 0x404 int c = (b-a); printf("%d\n",b-a);// -1 printf("%d\n",w-a); // -2 return 0; } 以更好地说明

变量的运行时内存地址与上面的类似。

w(0x404 - 0x408)== -1(-4);

sizeof int(在本例中)是4个字节。保存int地址的指针将其地址更改为(+/-)4倍, 到目前为止,int是关注在这种情况下4个字节保持一个整数(1个单位)

b - a

如果你有

w - a == (0x400 - 0x408) = -2( -8 )