开发者社区> 问答> 正文

c语言函数参数泛类型指针参数问题? 400 报错

c语言函数参数泛类型指针参数问题? 400 报错

typedef long intptr_t;

int sapi_header_set_status(void *arg){ printf("%ld", (int)(intptr_t) arg); }

intptr_t status_code = 400; sapi_header_set_status(&status_code);


@中山野鬼 为什么不能正确打印出 400,而是 56686416?

展开
收起
爱吃鱼的程序员 2020-06-04 15:16:41 691 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    兄弟,你打印的是status_code变量的地址。######楼上说的正确呀。你打印出来的是,status_code里面的值copy到堆栈里的某个空间的地址。为啥是copy到堆栈里,你看看函数调用的原理就知道了。实在不行,反汇编一下你的函数调用。哈######

    @chen.sy @中山野鬼 多谢 多谢, 也解决了我所期望的结果

    sapi_header_set_status((void *) (intptr_t) status_code);
    ######

    引用来自“腾勇”的答案

    @chen.sy @中山野鬼 多谢 多谢, 也解决了我所期望的结果

    sapi_header_set_status((void *) (intptr_t) status_code);
    #include <stdio.h>
    typedef long intptr_t;
    
    int sapi_header_set_status(void *arg){
        printf("%ld", *((intptr_t*) arg));
    }
    
    int main()
    {
        intptr_t status_code = 400;
        sapi_header_set_status(&status_code);
    }

    你这个方法,虽然能得出你的结果, 但是不是一般void*指针的用法. 你想要的东西在上面.

    void *的一般用法是: 你可以传任何指针变量(注意是指针变量,你原来的做法, status_code并不是一个指针变量,你只不过强制转换骗编译器而已,&status_code才是指针);但是你其实知道你想要的是什么指针(int*还是char*);所以你在函数里将void*转化为你知道的指针(你的函数实际想要的是long*,所以我们转为long*);

    这也是一切变量无类型的脚本语言的基础.


    ######

    引用来自“周翼翼”的答案

    引用来自“腾勇”的答案

    @chen.sy @中山野鬼 多谢 多谢, 也解决了我所期望的结果

    sapi_header_set_status((void *) (intptr_t) status_code);
    #include <stdio.h>
    typedef long intptr_t;
    
    int sapi_header_set_status(void *arg){
        printf("%ld", *((intptr_t*) arg));
    }
    
    int main()
    {
        intptr_t status_code = 400;
        sapi_header_set_status(&status_code);
    }

    你这个方法,虽然能得出你的结果, 但是不是一般void*指针的用法. 你想要的东西在上面.

    void *的一般用法是: 你可以传任何指针变量(注意是指针变量,你原来的做法, status_code并不是一个指针变量,你只不过强制转换骗编译器而已,&status_code才是指针);但是你其实知道你想要的是什么指针(int*还是char*);所以你在函数里将void*转化为你知道的指针(你的函数实际想要的是long*,所以我们转为long*);

    这也是一切变量无类型的脚本语言的基础.


    是的,但是这里是需要调用别的api,这个api,没法去改变了。我提问时,只把没有问题的地方提取出来了,完整的代码是:


    typedef enum {					/* Parameter: 			*/
    	SAPI_HEADER_REPLACE,		/* sapi_header_line* 	*/
    	SAPI_HEADER_ADD,			/* sapi_header_line* 	*/
    	SAPI_HEADER_DELETE,			/* sapi_header_line* 	*/
    	SAPI_HEADER_DELETE_ALL,		/* void					*/
    	SAPI_HEADER_SET_STATUS		/* int 					*/
    } sapi_header_op_enum;
    
    static void sapi_update_response_code(int ncode TSRMLS_DC){
    } 
    SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
    {
        switch (op) {
            case SAPI_HEADER_SET_STATUS:
                /* 设置 HTTP 状态码 */
                sapi_update_response_code((int)(zend_intptr_t) arg TSRMLS_CC);
                return SUCCESS;
    
            case SAPI_HEADER_ADD:
            case SAPI_HEADER_REPLACE:
            case SAPI_HEADER_DELETE: {
                   /* 添加、替换、删除 HTTP 头 */
                    break;
                }
    
            case SAPI_HEADER_DELETE_ALL:
                /* 清除所有 HTTP 头 */
                return SUCCESS;
    
            default:
                return FAILURE;
        }
        ... ...
    }
    如果我只需要改变当前http的状态码,在调用 sapi_update_response_code 时,期望结果就是一个int,而在添加、修改时,期望救过就是一个 char 指针


    ######

    引用来自“腾勇”的答案

    引用来自“周翼翼”的答案

    引用来自“腾勇”的答案

    @chen.sy @中山野鬼 多谢 多谢, 也解决了我所期望的结果

    sapi_header_set_status((void *) (intptr_t) status_code);
    #include <stdio.h>
    typedef long intptr_t;
    
    int sapi_header_set_status(void *arg){
        printf("%ld", *((intptr_t*) arg));
    }
    
    int main()
    {
        intptr_t status_code = 400;
        sapi_header_set_status(&status_code);
    }

    你这个方法,虽然能得出你的结果, 但是不是一般void*指针的用法. 你想要的东西在上面.

    void *的一般用法是: 你可以传任何指针变量(注意是指针变量,你原来的做法, status_code并不是一个指针变量,你只不过强制转换骗编译器而已,&status_code才是指针);但是你其实知道你想要的是什么指针(int*还是char*);所以你在函数里将void*转化为你知道的指针(你的函数实际想要的是long*,所以我们转为long*);

    这也是一切变量无类型的脚本语言的基础.


    是的,但是这里是需要调用别的api,这个api,没法去改变了。我提问时,只把没有问题的地方提取出来了,完整的代码是:


    typedef enum {					/* Parameter: 			*/
    	SAPI_HEADER_REPLACE,		/* sapi_header_line* 	*/
    	SAPI_HEADER_ADD,			/* sapi_header_line* 	*/
    	SAPI_HEADER_DELETE,			/* sapi_header_line* 	*/
    	SAPI_HEADER_DELETE_ALL,		/* void					*/
    	SAPI_HEADER_SET_STATUS		/* int 					*/
    } sapi_header_op_enum;
    
    static void sapi_update_response_code(int ncode TSRMLS_DC){
    } 
    SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
    {
        switch (op) {
            case SAPI_HEADER_SET_STATUS:
                /* 设置 HTTP 状态码 */
                sapi_update_response_code((int)(zend_intptr_t) arg TSRMLS_CC);
                return SUCCESS;
    
            case SAPI_HEADER_ADD:
            case SAPI_HEADER_REPLACE:
            case SAPI_HEADER_DELETE: {
                   /* 添加、替换、删除 HTTP 头 */
                    break;
                }
    
            case SAPI_HEADER_DELETE_ALL:
                /* 清除所有 HTTP 头 */
                return SUCCESS;
    
            default:
                return FAILURE;
        }
        ... ...
    }
    如果我只需要改变当前http的状态码,在调用 sapi_update_response_code 时,期望结果就是一个int,而在添加、修改时,期望救过就是一个 char 指针


    C语言的编译原理没搞清楚啊。。。。。你把地址的地址传进去,再取出来不就得了。。。。



    ######是啊 那些不懂
    2020-06-04 16:20:38
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载