正确示范:使用传址调用,运用 .操作符 和 ->操作符 )
//访问 #include <stdio.h> #include <string.h> struct Stu { int age; char name[20]; }; //第一种方法:对地址解引用,再使用 .操作符 //定义一个函数,对结构体成员进行赋值 void set_stu(struct Stu* ps)//t 的类型就是struct Stu { (*ps).age = 20; //因为成员 name 是数组,数组名是首元素地址 //t.name = "张三"; //所以不能这样写,不能把 张三 放在地址上 //应该把 张三 放在地址的空间里 //strcpy()函数:字符串拷贝 strcpy((*ps).name, "张三"); //strcpy:把字符串拷贝到一个地方 //把 张三这个字符串 拷贝到 t.name这个空间去 } //第二种方法:直接使用 ->操作符 //定义一个函数,对结构体成员进行赋值 void set_stu(struct Stu* ps)//t 的类型就是struct Stu { ps->age = 20; //因为成员 name 是数组,数组名是首元素地址 //t.name = "张三"; //所以不能这样写,不能把 张三 放在地址上 //应该把 张三 放在地址的空间里 //strcpy()函数:字符串拷贝 strcpy(ps->name, "张三"); //strcpy:把字符串拷贝到一个地方 //把 张三这个字符串 拷贝到 t.name这个空间去 } //定义一个函数,打印结构体变量 void print_stu(struct Stu t) { printf("%s %d\n", t.name, t.age); } int main() { struct Stu s = { 0 }; //定义一个函数,对结构体成员进行赋值 set_stu(&s); //定义一个函数,打印结构体变量 print_stu(s); return 0; }
3. 结构体传参
(演示代码:传值和传址调用)
//传参 #include <stdio.h> struct S { int data[1000]; int num; }; struct S s = { {1,2,3,4}, 1000 }; //方案1:结构体传参 void print1(struct S s) { printf("%d\n", s.num); } //方案2:结构体地址传参 void print2(struct S* ps) { printf("%d\n", ps->num); } int main() { print1(s); //传结构体(变量) print2(&s); //传地址 return 0; }
结论:
结构体传参的时候,要传结构体的地址。
练习:
1. 写一个函数返回参数二进制中 1 的个数
(第一种方法:%2 和 /2 取出每一位并判断)
//写一个函数返回参数二进制中 1 的个数。 //比如: 15 0000 1111 4 个 1 #include <stdio.h> int number_of_1(unsigned int m)//要设置成无符号的,不然无法判断 负数 { int count = 0; //计数器 while (m) //如果 m 不为0,说明二进制还有1 { if (m % 2 == 1)//判断最低位 { count++; //为1则计数器++ } m /= 2; //相当于二进制去了一位 } //一直判断直到m等于0,返回统计的1的个数 return count; } int main() { int n = 0; //输入: scanf("%d", &n); //定义一个计算二进制中1个数的函数 int ret = number_of_1(n); printf("%d\n", ret); return 0; }
(第二种方法:使用 移位操作符 和 位操作符 )
#include <stdio.h> int number_of_1(int m)//要设置成无符号的,不然无法判断 负数 { int count = 0; //计数器 int i = 0; for (i = 0; i < 32; i++) //二进制有32位,判断32次 { if ( ( (m >> i) & 1) == 1) //移动 i位 后再 按位与1 ,判断最低位二进制值是否为 1 //移动后 m 的值并没有变,所以可以一直移动 { count++; //是 1 则计数++ } } return count; } int main() { int n = 0; //输入: scanf("%d", &n); //定义一个计算二进制中1个数的函数 int ret = number_of_1(n); printf("%d\n", ret); return 0; }
(第三种方法:
n = n & (n - 1) -- 这个表达式会让n的二进制中最右边的1消失,
所以在n变成0之前,能执行几次,
就说明n二进制上有几个1)
#include <stdio.h> int number_of_1(int m)//要设置成无符号的,不然无法判断 负数 { int count = 0; //计数器 while (m)//如果 m 不为0,说明二进制还有1 { m = m & (m - 1);//去掉最右边的1 count++; //计数器++ } return count; } int main() { int n = 0; //输入: scanf("%d", &n); //定义一个计算二进制中1个数的函数 int ret = number_of_1(n); printf("%d\n", ret); return 0; }
2. 打印整数二进制的奇数位和偶数位
//获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列 #include <stdio.h> int main() { int n = 0; scanf("%d", &n); int i = 0; //打印奇数位 printf("奇数位:"); for (i = 30; i >= 0; i -= 2) //循环时是 偶数位:30 28 26.。。。 { printf("%d ", (n >> i) & 1); //这里移位后是奇数位,按位与1 取出最低位 打印 } printf("\n"); printf("偶数位:"); //打印偶数位 for (i = 31; i >= 1; i -= 2) //循环时是 偶数位:31 29 27.。。。 { printf("%d ", (n >> i) & 1); //这里移位后是偶数位,按位与1 取出最低位 打印 } return 0; }
3. 求两个数二进制中不同位的个数
//编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同? //输入例子 : //1999 2299 //输出例子 : 7 #include <stdio.h> int number_of_1(int m) { int count = 0; //计数器 while (m)//如果 m 不为0,说明二进制还有1 { m = m & (m - 1);//去掉最右边的1 count++; //计数器++ } } int main() { int m = 0; int n = 0; //输入 scanf("%d %d", &m, &n); //异或:相同为0,相异为1 //把 m 异或 n 后,有几个相异就有几个1,再计算下二进制中有几个1即可 int ret = number_of_1(m ^ n); printf("%d", ret); return 0; }