c语言函数参数泛类型指针参数问题

开源中国董事会主席 发布于 2013/04/26 16:12
阅读 618
收藏 1
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?

加载中
1
shouyong
shouyong
兄弟,你打印的是status_code变量的地址。
1
中山野鬼
中山野鬼
楼上说的正确呀。你打印出来的是,status_code里面的值copy到堆栈里的某个空间的地址。为啥是copy到堆栈里,你看看函数调用的原理就知道了。实在不行,反汇编一下你的函数调用。哈
0
开源中国董事会主席
开源中国董事会主席

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

sapi_header_set_status((void *) (intptr_t) status_code);
0
周翼翼
周翼翼

引用来自“腾勇”的答案

@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*);

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


0
开源中国董事会主席
开源中国董事会主席

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

引用来自“腾勇”的答案

@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 指针


0
中山野鬼
中山野鬼

引用来自“腾勇”的答案

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

引用来自“腾勇”的答案

@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语言的编译原理没搞清楚啊。。。。。你把地址的地址传进去,再取出来不就得了。。。。



开源中国董事会主席
开源中国董事会主席
是啊 那些不懂
返回顶部
顶部