在C中的指针中键入转换错误

时间:2016-08-08 17:25:32

标签: c pointers types casting

我无法进行指针的类型转换..我发现了Y的垃圾值。 我在代码中做错了吗?请帮我找到我的欲望输出

#include<stdio.h>

int main(){

    float x= 15;
    int *y;

    y=(int *)&x;

    printf("\tValue of X is : %f \n",x);
    printf("\tValue of y is : %d",*y);

    return 0;
}

输出

enter image description here

5 个答案:

答案 0 :(得分:3)

float x= 15;
int *y;

y =(int *)&x;

float的地址分配给指向int的指针是未定义的行为,它们的类型不同且不可互换,允许执行此操作的唯一类型是{{1 }和char *

更改为:

void *

float x= 15;
char *y;

y = (char *)&x;

printf("\tValue of X is : %f \n", x);
printf("\tValue of y is : %d", (int)*(float *)y);

答案 1 :(得分:0)

我刚做了一个迷你程序来测试猜测,我找到了你的问题

package com.example.akkisocc.heath;


import android.content.Intent;
import android.content.IntentSender;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.fitness.data.Value;
import com.google.android.gms.fitness.request.DataSourcesRequest;
import com.google.android.gms.fitness.request.OnDataPointListener;
import com.google.android.gms.fitness.request.SensorRequest;
import com.google.android.gms.fitness.result.DataSourcesResult;

import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity implements OnDataPointListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {
    private static final int REQUEST_OAUTH = 1;
    private static final String AUTH_PENDING = "auth_state_pending";
    TextView msg;
    private boolean authInProgress = false;
    private GoogleApiClient mApiClient;

    @Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        msg = (TextView) findViewById(R.id.msg);
        msg.setText("On Create");
Log.e("GoogleFit", "Oncreate");

        if (savedInstanceState != null) {
            authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
        }

        mApiClient = new GoogleApiClient.Builder(this)
                .addApi(Fitness.SENSORS_API)
                .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mApiClient.connect();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_OAUTH) {
            authInProgress = false;
            if (resultCode == RESULT_OK) {
                if (!mApiClient.isConnecting() && !mApiClient.isConnected()) {
                    mApiClient.connect();
                }
            } else if (resultCode == RESULT_CANCELED) {
                Log.e("GoogleFit", "RESULT_CANCELED");
            }
        } else {
            Log.e("GoogleFit", "requestCode NOT request_oauth");
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        DataSourcesRequest dataSourceRequest = new DataSourcesRequest.Builder()
                .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
                .setDataSourceTypes(DataSource.TYPE_RAW)
                .build();

        ResultCallback<DataSourcesResult> dataSourcesResultCallback = new ResultCallback<DataSourcesResult>() {
            @Override
            public void onResult(DataSourcesResult dataSourcesResult) {
                for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                    if (DataType.TYPE_STEP_COUNT_CUMULATIVE.equals(dataSource.getDataType())) {
                        registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE);
                    }
                }
            }
        };

        Fitness.SensorsApi.findDataSources(mApiClient, dataSourceRequest)
                .setResultCallback(dataSourcesResultCallback);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        if (!authInProgress) {
            try {
                authInProgress = true;
                connectionResult.startResolutionForResult(MainActivity.this, REQUEST_OAUTH);
            } catch (IntentSender.SendIntentException e) {

            }
        } else {
            Log.e("GoogleFit", "authInProgress");
        }

    }

    private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {

        SensorRequest request = new SensorRequest.Builder()
                .setDataSource(dataSource)
                .setDataType(dataType)
                .setSamplingRate(3, TimeUnit.SECONDS)
                .build();

        Fitness.SensorsApi.add(mApiClient, request, this)
                .setResultCallback(new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        if (status.isSuccess()) {
                            Log.e("GoogleFit", "SensorApi successfully added");
                        }
                    }
                });
    }

    @Override
    public void onDataPoint(DataPoint dataPoint) {
        for (final Field field : dataPoint.getDataType().getFields()) {
            final Value value = dataPoint.getValue(field);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(), "Field: " + field.getName() + " Value: " + value, Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}

果然,它会打印#include <iostream> union test { float f; int i; }Test; int main() { union test t; t.f = 15; std::cout << t.i << std::endl; } 。这是因为整数和浮点数都是32位数,你所做的就是告诉它&#34;解释我作为一个浮点数保存的0和1的模式而不是&#34;。当它落到0和1时,Ints和浮标的保存方式完全不同,甚至

1097859072
尽管数字相同,但

将具有0和1的完全不同的模式。你所做的并不是一种有效的类型转换方法。 @Inline's回答有一种方法可以做到,另一种是:

int x = 10;
float y = 10;

编辑: 我应该澄清一点,并非所有的整数都是32位,但我可以告诉你,你的小测试程序是通过实验证据。您可以使用 float x = 15; int y = (int)x; 来获取系统上数据类型的字节大小以进行验证。

答案 2 :(得分:0)

float x= 15;
int *y;
y=(int *)&x;
...
printf("\tValue of y is : %d",*y);

使用此代码,您告诉编译器您要将位模式用于float值15.0并将解释该模式作为{ {1}}。正如其他人所指出的,这段代码导致了未定义的行为,这意味着任何结果都是可能的。 intint具有不同的表示形式,它们可能(并且在许多平台上)具有不同的大小,并且可能具有不同的对齐要求。

做的是将浮点值float转换为整数值15.0

假设有一个大端,IEEE-754 32位单精度15float的二进制表示将如下所示:

15.0
它也恰好是整数0 10000010 111000000000000000000 | | | | | | | | +---------+---------+ | +--+---+ | | | +----------- binary fraction 1.1112 (normalized) | +--------------------------- exponent (3, excess 127 notation) +-------------------------------- sign bit 的位模式。

如果要将浮点1097859072转换为整数15.0,只需执行以下操作:

15

C会自动将浮点值float x = 15.0; int y = x; // no pointers involved at all (表示为15.0)转换为整数值010000010111000000000000000000002(表示为15

请注意,在此转换中,小数部分被简单地丢弃;你将有效地走向0.

答案 3 :(得分:-1)

您正在尝试将指针类型转换为另一种类型的指针。

为了理解你的失败,你需要了解计算机的内存是如何工作的。我会尽力以最短最简单的方式向你解释。

可以用不同的方式解释位序列:

x: 01000010

RAM中每个单元的内存都具有变量类型给出的含义。

所以,例如:

  • 如果x整数,则值01000010将被解释为整数: 66
  • 如果x char ,则该值将被解释为字符 B ,依此类推。

代码错误

你在内存中分配了一个整数,所以:

x: 15.0f // In decimal base, floating point

如果使用带浮点指针的指针访问该内存,就像你的情况一样:

float* y = (float*)&x

然后相同的位序列将被解释为整数值。

实际上,浮点数有一种标准的方式可以用比特形式表示:wiki FP standard

754标准将值15存储为:

01000001011100000000000000000000

浮点表示中的15.0,但 1097859072 作为整数表达式。

您可以在DecimalConversion上进行测试。

答案 4 :(得分:-3)

y=(int *)&x;如果您执行类似此值的操作,则&f引用将不会转换为float。您将获得float指针,指向int

这是正确的方法:

int main()
{
    float x= 15;
    int *y = malloc( sizeof(int) ); // Allocate memory for int
    *y  =  int(x); // Convert to int and set as value which y pointing

    printf("\tValue of X is : %f \n",x);
    printf("\tValue of y is : %d",*y);

    free(y); // Free heap allocated memory
}

您还可以获得有关floatint个实现

的一些信息