#include <stdio.h>
void set_flag(int* flag_holder, int flag_position){
*flag_holder |= (1 << flag_position);
}
void set_flag(int* flag_holder, int flag_position);
int main(int argc, char* argv[])
{
int flag_holder = 0;
int i;
set_flag(&flag_holder, 3);
set_flag(&flag_holder, 16);
set_flag(&flag_holder, 31);
我对下面的内容感到困惑?我认为它调用void set_flag()中的指针,我不确定它是否将该值设置为3,然后是16然后是31?
set_flag(&flag_holder, 3);
set_flag(&flag_holder, 16);
set_flag(&flag_holder, 31);
答案 0 :(得分:1)
让我们摆脱按位的东西,只关注指针。
void set_flag(int* flag_holder, int flag_position) {
*flag_holder = flag_position;
}
此功能的目的是更改呼叫者的变量。你这样称呼它:
int *flag;
set_flag(&flag, 5); // flag is now 5
&
生成一个指针,*
将指针转回其指向的位置。
flag_holder
是一个指向整数的指针,它是整数在内存中的位置,有32或64位数。 flag_position
是一个常规整数。
如果set_flag
尝试flag_holder = flag_position
表示说&#34;请将flag_holder
指向内存位置5&#34;并且很可能计算机会说'不,你不能这样做,那不是你的记忆&#34;并使程序崩溃。
相反,它必须说&#34;将您指向的数字改为等于5&#34;这是*flag_holder = flag_position
。
答案 1 :(得分:0)
&
获取应用它的变量的地址,*
获取指针提供的地址的值。
在函数声明中int *
声明参数为指针,即整数的地址。然后在函数内获取修改后的值并将其写回给定的地址。
当您在main中传递flag_holder
的地址时,此地址的值将在set_flag(...)
内修改。
答案 2 :(得分:0)
调用者正在传递整数的地址。被调用者解除引用传入的地址以为该整数分配新值。传递地址而不是直接传递值的原因是子例程可以修改整数。
新值恰好基于旧值加上翻转各个位,具体取决于传递的内容。但这实际上是与帖子主题相关的一个单独问题。
答案 3 :(得分:0)
函数set_flag
有两个参数:
int*
- 指向int 然后它对数据执行一些按位OR运算。
因此,在您的示例中,您将flag_holder = 0
作为第一个值,将第3个,第16个和第31个作为第二个值。这导致(假设32bit
int):
flag_holder = 00000000 00000000 00000000 00000000 = 0 in binary
(1 << 3) = 00000000 00000000 00000000 00001000 = 1 left shifted by 3
OR result = 00000000 00000000 00000000 00001000 = result of | binary operation
另一个例子,如果你有另一个flag_holder值:
flag_holder = 00000000 00010000 00001000 10000001
(1 << 3) = 00000000 00000000 00000000 00001000
OR result = 00000000 00010000 00001000 10001001
答案 4 :(得分:0)
set_flag()
函数使用按位运算符来操作位级别的flag_holder值。
按位OR |运算符可用于设置单个位。用于设置标志的类似技术是:
#define flag1 0x01
#define flag2 0x02
#define flag3 0x04
#define flag4 0x08
#define flag5 0x10
... you get the idea.
然后我们可以使用OR运算符设置一个单独的位:
char flags = 0;
flags |= flag1
如果你想到二进制方面的标志值 - 想象一下:
flag1 = 00000001
flag2 = 00000010
flag3 = 00000100
flag4 = 00001000
你明白了! OR运算符会将rvalue中设置的任何位复制到左值,有效地设置位或标志。
这样做flags |= (flag1 | flag3)
会导致我们的标志:
flags 00000101
我们可以使用类似的东西来指定是否指定了特定选项。
您的示例使用不同的技术,它始终应用位移值1 ...想象一下,如上例中的0x01 == 00000001
如果我们转移00000001&lt;&lt;我们有一次获得00000010。
你的set_flag()函数正在接受指向int
的指针,这意味着它可以更改flag_holder
的值,第二个参数指定向左移动1的位置并隔离特定的位。
你应该阅读有关按位运算符的信息。