考虑以下堆栈数组的定义:
typedef struct larray{
int values[BSize];
struct larray *prox;
}*LArrays;
typedef struct stack{
int sp; //number of occupied positions in stack's top array
LArrays s; //stack top
}Stack;
我写了这个pop函数:
int pop(Stack *st, int *t){
if (st->sp == 0) return -1;
if (st->sp == 1){
LArrays newTop = st->s->prox;
free(st->s);
st->s = NULL;
st->s = newTop;
st->sp = BSize;
return 0;
}
LArrays l = st->s;
int *remover = l->values + (--st->sp);
*t = *remover;
*remover = NULL;
return 0;
}
有效。但是在编译时,gcc产生了这个警告:
警告:赋值在没有强制转换的情况下从指针生成整数[-Wint-conversion]
*remover = NULL;
为int *?
分配NULL是错误的主:
for (; i < 150; i++)
push(stack,i);
i = 0;
printStack(stack);
for (; i < 70; i++)
pop(stack,&r);
printStack(stack);
with * remover = NULL(产生所需的输出!)
//stack after push
100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|]
---------------------------------------------------------
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|]
//stack after pop
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|]
with remover = NULL(不产生所需的输出!)
//stack after push
100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|]
---------------------------------------------------------
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|]
//stack after pop
0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|]
打印功能:
void printArray(int *v, int N){
int *p = v;
int i = 0;
for(; i < N; i++)
printf("%d|",*p++);
printf("]\n\n");
}
void printStack(Stack *stack){
LArrays p = stack->s;
printf("Free Space on Stack's head: %d\n",BSize - stack->sp);
printf("\nStack:\n\n");
while(p->prox != NULL){
printArray(p->valores,BSize);
printf("------------------------------------------------\n");
p = p->prox;
}printArray(p->values,BSize);
}
答案 0 :(得分:1)
没有错误将NULL
分配给int *
,但将其分配给int
并不总是正确的。它是实现定义的行为。
详细说明,NULL
是
NULL
扩展为实现定义的空指针常量; [...]
然后,引用章节§6.3.2.3/ p6(强调我的)
任何指针类型都可以转换为整数类型。除了之前指定的, 结果是实现定义的。如果结果无法以整数类型表示, 行为未定义。
所以,你的编译器会警告你。
看起来,在这里,你只是误解了如何使用指针变量。你不需要去取消引用。你需要改变
*remover = NULL;
到
remover = NULL; // assign NULL to the pointer variable, not to the value it points to.
摆脱警告。
答案 1 :(得分:1)
您没有为int *
分配NULL。您将其分配给int
。
remover
的类型为int *
,而*remover
取消引用该指针且类型为int
。
将该行更改为以下内容:
remover = NULL;
实际上,您可以完全删除该行,因为在该点之后未引用remover
。
答案 2 :(得分:1)
您要将NULL
分配给int *
,而不是int
。您执行*remover = NULL;
,remover
为int *
,*remover
为int。
答案 3 :(得分:1)
这不是警告所说的。它表示*remover = NULL
正在将指针(NULL
)分配给整数(*remover
)(请参阅您的声明,它说“*remover
是int
” )。
您是否要将NULL
分配给名为int *
的{{1}},请执行以下操作:
remover
这是完全合法的。
答案 4 :(得分:1)
将NULL分配给int *?
是错误的
不,这样做是有效的。
然而,这不是编译器所抱怨的。
仔细阅读信息(人们应该做什么,BTW; - ):
warning: assignment makes integer from pointer without a cast [-Wint-conversion] *remover = NULL;
现在让我们分开警告:
... assignment makes integer ...
这转换为:“代码[尝试]分配给整数...... ”
... from pointer ...
这转换为:“ ...来自指针(值)...... ”
查看相关行:
*remover = NULL;
我们看到*remover
已分配,NULL
是已分配的值。
将所有这些放在一起我们可以得出结论,编译器正在进行
*remover
是一个整数,
NULL
成为指针(值)。
加上“编译器永不失败”,你应该能够理解这个问题。
: - )
答案 5 :(得分:0)
您正在指定卸妆指向的值。如果要为指针指定NULL,请使用此指针。
remover = NULL;