int main(void) {
int *a;
int *b = a++;
printf("%d\n",b-a);
return 0;
}
我预计输出为1为什么它是-1?
在上述问题中假设而不是a++
我有++a
。
它仍然是未定义的行为吗?
答案 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 )