学C的第十八天【指针初阶:5. 指针和数组、6. 二级指针、7. 指针数组;初识结构体:1. 结构体的声明、2. 结构体成员的访问、3. 结构体传参;练习:3道和整数二进制数相关的练习】-3

简介: 正确示范:使用传址调用,运用 .操作符 和 ->操作符 )

正确示范:使用传址调用,运用 .操作符 ->操作符 

//访问
#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;
}


a1dc5b92d0c44923b505ceb7fa6c7b75.png

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;
}


ffe77cc7deb24bce82f1e1bbd303a445.png

结论:

结构体传参的时候,要传结构体的地址

练习:

           

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;
}

image.png

(第二种方法:使用 移位操作符 位操作符

#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;
}

image.png

(第三种方法:

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;
}

665345614a3e4cdd97a0a72a2b34fbea.png

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;
}

image.png

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;
}

f7939d1ddeae48688563618537a7d8da.png

相关文章
|
15天前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
30 3
|
10天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
33 4
|
14天前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
27 2
|
22天前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
28 1
|
1月前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
1月前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。
|
5月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
24 0
|
2月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
3月前
|
C语言
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)