首页 文章

c将void *转换为int错误

提问于
浏览
2

我是C / C的新手,我正在尝试使用定义数据结构PDS的C库,并提供访问数据的方法 .

这是我用来访问它的函数:

pdsGetNext  (PDS *pds,char **pKey,PDStype *pT,size_t *pS,void **pD);

它基本上返回元素的键,元素的类型,元素的大小和元素的实际数据 . void **pD 在文档中描述如下:"Pointer to an address, which gets the actual element." .

我正在尝试将数据转换为适当的类型,如“PDStype”所示 . 我在将数据转换为整数时遇到问题,这里是示例代码:

char *key = NULL;
PDS_TYPE type;
size_t size;
void *data = NULL;
float f;

pdsRewind(myPDS);

while (pdsGetNext(myPDS, &key, &type, &size, &data) == PDS_ERR_NONE) {
    switch (type) {
    case PDS_TYPE::PDS_I:
        // this is integer
        printf("INT: %d\n", *((int*)data));
        printf("INT PRINTED AS STRING: %s\n", (int*)data);
        printf("INT AS STRING: %s\n", (char*)data);
        break;
    case PDS_TYPE::PDS_PCH:
        //this is null terminated string
        printf("STRING: %s\n", (char*)data);
        break;
    default:
        break;
    }

}

整数的实数值为7,输出如下:

INT: 55
INT PRINTED AS STRING: 7
INT AS STRING: 7

对我来说,似乎第一个,我想成为"7",如果我已经像_1080738那样对其进行了malloced,那么就会打印出来,然后尝试将其像 *((int*)ptr) 一样转换为int .

我的问题是:在将它转换为int时,我有什么问题吗?据我所知,数据作为 void* 返回的原因是为了让人们能够以这种方式使用强制转换 .

2 回答

  • 0

    55是"7"的ascii值 . http://www.asciitable.com/

    在C:

    int a = atoi(data);
    

    在C 11:

    int myint1 = std::stoi(data);
    

    因为你在C中使用数据是一个无效的*做_1080745这样的:

    int myint1 = std::stoi(reinterpret_cast<char*>(data));
    

    在C:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        // to get a void* like you
        char *tmp = "7";
        void *data = (void*)tmp;
    
        // what is matter for you
        int a = atoi((char*)data);
        printf("a = %d\n", a);
        return 0;
    }
    

    在C 11:

    include <iostream>
    
    int main()
    {
        // to get a void* with "7" like you we could get the same with a std::string
        char *tmp = new char [1]();
        tmp[0] = '7';
        void * data = reinterpret_cast<void*>(tmp);
    
        // what is matter for you
        int a = std::atoi(reinterpret_cast<char*>(data));
        std::cout << "a = " << a << std::endl;
        return 0;
    }
    
  • 0

    当你说“将一个char *转换为int”时,你会给出一个“没有很好定义的规范”,因为char *意味着提供与int完全不同的语义 .

    当你“强制”一个演员表时,你会在不同的语义下重新解释相同的位模式 . 当您“转换”某个值时,您正在将位模式更改为另一个保留语义的模式 .

    现在,字符文字(和字符串文字)应该是"readable text": '7'7 不同, 7+29 ,但 '7'+'2''e' .

    那是因为是整数运算,'7'是53,'2'是48,101是'e' .

    现在,你有一块内存,你在其中放置了值'7'(这是对应于整数53的相同位模式:内存本身是不可知的类型语义:它只包含00110101),其地址被称为 void* .

    现在,由于 printf 如何工作,%d需要int,并使用数字语义,而%s需要char *并使用文本语义 .

    您作为第二个参数放置的所有内容都将根据这些规范进行阅读 .

    在你的第一种情况下,你拿 void* ,使用它,因为你是一个 int* ,你顺从(通过粗心 * )得到一个对应于00110101 53的int值,并将此给予printf将其视为一个数字,并转换它进入显示的文本("53") .

    在第三种情况下,您将 void* 视为 char* 并将其作为"sequence of chars"将其读取(因为%s),因此打印"7" .

    在你的第二种情况下,你取一个int *并将它提供给printf,它需要一个char *(因为%s,它会这样对待),因此仍然给你“7” .

    如果要将值 "7" (文本)转换为数字 7 (整数),则必须使用 atoi 之类的函数,并使用"%d"打印返回值(现在为整数) . 使用%s会崩溃,因为 7 被视为char *几乎肯定是在程序存储空间之外的地址

相关问题