2025/2/17--2/23学习笔记(week1)_C语言
1 整数的存储
- 只有整数才有原码,反码,补码,原码取反加一(除了符号位)得到补码。补码的补码会变成原码。 在任何位运算里,都是操作的补码,因为整数在内存里都是以补码存储的
2 移位运算符
- 移位运算符只能用与整数,且移动二进制位的补码,不改变这个数本身的值
- 左移,左边丢弃,右边补零
- 右移,分为逻辑和算数(一般)右移,与编辑器有关。1. 逻辑右移:左边⽤0填充,右边丢弃 2. 算术右移:左边⽤原该值的符号位填充,右边丢弃
- 在进行完位运算后,得到的仍然是补码。
3 位运算符
-
位操作符
&| ^ ~ -
& 有0则为0,同时为1则为1可以用真假来记
-
| 有1则为1,同时为0才是0
-
^ 相同为0,相异为1
-
~ 按位取反,包括符号位
-
异或的一些技巧
-
异或支持交换率,即与运算顺序无关
(3^3^5=3^5^3) -
a^a=0 0^a=a -
基于以上特点,可以用于交换两个变量但不使用第三个变量
-
int a = 5; int b = 10; a = a ^ b; b = a ^ b; a = a ^ b;
-
4 求一个正数在内存里存储的二进制中的1的个数
-
方法一:只能用于正数 int count = 0;int n = 15;while (n>0) {if (n % 2 == 1) {count++;}n /= 2;}printf("%d", count);方法二:一个数在&1之后,如果==1,则说明该位是1,否则则为0int count = 0;int n = -1;for (int i = 0; i < 32;i++) {if ((n >> i) & 1 == 1) {count++;}}printf("%d", count);方法三:n = n & (n - 1)这样写执行一次该代码,会去掉二进制里最右边的一个1(相当于将最右边的一个1拆成0……1)int count = 0;int n = -1;while (n != 0) {n = n & (n - 1);count++;}printf("%d", count);
5 逗号表达式
- (……,……,……)从左向右依次进行计算,整个表达式的结果是最后一个表达式的结果,常和while函数一起使用
6 结构体
- 创建结构体
struct stu {int age;char name[10];
}s2,s3;
- 初始化,使用{}
struct stu s1 = {10,"zhangsan"};。也可以不按顺序初始化struct stu s4 = { .name = "lisi",.age = 20 }; - 可以用 . 访问成员
printf("%d", s1.age);
7 整型提升
- C语言中整型算术运算总是至少以(int)整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。(在 C 语言中使用
char类型变量存储数字时,确实只能存储该数字二进制表示的前 8 位。) - 有符号整数提升是按照变量的数据类型的符号位来提升的
- 无符号整数提升,高位补0
- 在计算时提升,计算完在截断(char:只能在[-128,127])
- 在以%d 打印一个char类型的变量的时候,会先对该变量进行整型提升得到补码,在转化为原码进行打印(一般默认是有符号char)
8 算数转换
- 如果某个操作符的各个操作数属于不同的类型,那么除非其中⼀个操作数的转换为另⼀个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
- 在比较有符号整型和无符号整型时,有符号整数会被隐式转换为无符号整数。转换的方式是保留二进制位不变,但是将其解释为无符号数。(例如,在 32 位系统中,有符号整数
-1的二进制表示是0xFFFFFFFF(补码形式)。当把它转换为无符号整数时,同样的二进制位0xFFFFFFFF会被解释为无符号数4294967295。)
9 指针
- 如果对一个(int)类型取地址,取到的是最小那个地址(一个int4个字节,每个字节都有自己对应的地址,&a则代表最小那一个地址)
- 任何数字存入指针变量里,都会被当作指针处理
- 一个指针变量在32位机器上是32个0/1组成的序列,需要4个字节来存储,在64位机器上是64个0/1组成的序列,需要8个字节来存储
- 不同的指针类型,在解引用时访问的字节数与指针类型有关
- 不同的指针类型,会影响+1的步长
10 void*指针
- 泛型指针可以理解为⽆具体类型的指针(或者叫泛型指针),这种类型的指针可以⽤来接受任意类型地址。但不能对该指针进行解引用和±操作。经常用于接受不同类型的函数参数,在使用时可以先强制类型转化后在使用。
11 指针运算
-
指针±整数: *(p+i)或者 scanf(“%d”, p + i),这里的p+i本身就表示一个地址
-
不只可以加上一个整数,还可以减去一个整数,在这个程序里,
int* p = &arr[9];此时p里面存放的是最后一个元素的地址,也可以从这里向前访问。 -
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = &arr[9]; for (i = 0; i < sz; i++) {printf("%d ", *(p - i)); }
-
-
指针-指针:
-
-
只有指向同一块区域的指针才可以相减(比如指向同一个数组的内存)
-
相减的结果的绝对值是两个指针之间的元素个数
-
int arr[10] = { 0 }; int n = &arr[0] - &arr[9]; printf("%d ", n);
-
-
指针的关系运算:(可以用这种关系运算来判断一个数组是否已经结束)
-
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); int* p = arr; while (p < &arr[sz]) {printf("%d ", *p);p++; }
12 strlen函数的实现
方案一:(计数器)
size_t my_strlen(char* str){size_t num = 0;while (*str != '\0') {num++;str++;}return num;
}int main()
{char arr[] = "abcdef";size_t len = my_strlen(arr);printf("%zd", len);return 0;
}
方案二:(运用指针相减)
size_t my_strlen2(char* str) {char* start = str;while (*str != '\0')str++;size_t num = (size_t)(str - start);return num;
}
13 const修饰指针
-
对于
const int n = 10;会让n变成常变量,无法被修改,但仍然是一个变量。const修饰的变量不能直接被修改,但可以通过指针侧面进行修改 const int n = 10; int* p=&n ; *p = 1; printf("%d ", n);如果不想让这个值被指针修改,只需要在int*前也加上const const int n = 10; const int* p=&n ; *p = 1; printf("%d ", n); -
const int * p ,const放在左边,修饰的是整个(*p),也就是可以不能修改p指向的内容,但指针变量本身可以修改,即可以从指向a变为指向b
-
int * const p,const放在*的右边,修饰的是p本身,也就是不可以修改p本身,即p的指向,但可以通过p修改p指向的内容即 *p
14 野指针
-
这里面就造成p变成了一个野指针,因为在test结束的时候,n空间就释放了 int* test() {int n = 100;return &n; }int main() {int* p = test();printf("%d ", *p);return 0; }
15 assert断言
- assert包含在头文件
<assert.h>里,如果在开头加上#define NDEBUG
会直接让程序里所有的assert断言都失效
int* p = &a; assert(p != NULL)如果p为NULL,会直接终止程序- 该断言只有在debug模式里才有用,在release模式则会忽略该语句。
16 指针与数组
- 数组名是数组首元素的地址,但存在两个特殊情况
-
- sizeof(数组名) 在这种情况下,数组名表示整个数组,计算出的结果是整个数组的大小,单位是字节
- &数组名 这里的数组名也是表示整个数组,取出的是整个数组的地址(类型不是int*)
17 一维数组传参的本质
- 在实际以数组传参的时候,传递的就是一个地址,也就是如果数组经过传参,就彻底变成首元素的地址,没有特殊情况了,不可以用
sizeof(arr) / sizeof(arr[0])来计算数组长度了。所以如果想知道数组的长度,必须在传参的时候传过去
18 冒泡排序
-
两两相邻的元素进行比较
-
一趟解决一个数字,所以需要(n-1)次
-
void bubble_sort(int* pa,int len) {for (int i = 0; i < len-1; i++) {//控制一共运行几次,如果有n个元素,只需要运行n-1次即可,因为最后一个元素会自行有序int flag = 0;for (int j = 0; j < len-1-i; j++) {//控制在一次循环里比较几对数据if (pa[j] > pa[j + 1]) {int tem = pa[j];pa[j] = pa[j + 1];pa[j + 1] = tem;flag = 1;}}if (flag == 0) {break;}} }//flag是为了优化代码,如果有一次外层循环一次都没有交换(flag==0),则说明已经有序,可以直接结束(break)
19 二级指针
-
int** p就是二级指针,int *说明p指向一个int *类型的数据,而第二颗 *则说明p是一个指针变量
-
int a = 10; int* pa = &a; int** ppa = &pa;
20 指针数组
-
存放指针的数组
-
模拟二维数组(与二维数组有不同,因为二维数组每一行之间是连续空间)
-
int main() {int a[3] = { 1,2,3 };int b[3] = { 4,5,6 };int c[3] = { 7,8,9 };int d[3] = { 10,11,12 };int* arr[4] = { a,b,c,d };//数组名是首元素地址for (int i = 0; i < 4; i++) {for (int j = 0; j < 3; j++) {printf("%d ", arr[i][j]);}printf("\n");}return 0; }
21 字符指针
-
在打印字符串的时候,只需要传入该字符数组首元素的地址
const char* p = "hdjslds";printf("%s",p); -
字符指针可以被赋为字符数组,也可以直接用常量字符串赋值,两者的区别是常量字符串不可以被修改
-
char* p = "hdjslds";char arr[10] = "hdjslds"; char* p = arr; -
对于同一个常量字符串,即使使用多个指针变量指向它,都指向的是同一块内存空间(即同一个常量字符串,因为它无法被修改,所以没必要创建多个)
-
const char* str1 = "hello"; const char* str2 = "hello"; if (str1 == str2) {printf("same"); }
22 数组指针变量
- 指向整个数组的指针
int(*p)[5]其中(*p)说明p是一个指针变量,[5]说明p指向的是一整个数组,5代表元素个数,int 代表指向这个数组里边存放的元素的数据类型
相关文章:
2025/2/17--2/23学习笔记(week1)_C语言
1 整数的存储 只有整数才有原码,反码,补码,原码取反加一(除了符号位)得到补码。补码的补码会变成原码。 在任何位运算里,都是操作的补码,因为整数在内存里都是以补码存储的 2 移位运算符 移位…...
数据结构:二叉树的数组结构以及堆的实现详解
目录 一.树与二叉树 1.树的概念与相关术语: 2.二叉树: (1)定义: (2)特殊的二叉树: (3)完全二叉树 (4)二叉树的存储结构&#x…...
AWS S3 如何设置公开访问权限?
1.让整个bucket都有公开访问权限 1.1关闭【阻止公共读】 1.2关闭ACL访问控制 1.3打开桶策略 这样桶内所有的图片就能访问了 2.只开放特定文件让其具有访问权限? 2.1关闭【阻止公共读】 如之前的图示 2.2打开ACL控制 2.3单个文件打开公共读...
使用TortoiseGit配合BeyondCompare实现在Git仓库中比对二进制文件
使用TortoiseGit的比对工具可以直接右键,点击选择比对和上一版本的变化差异: 但是TortoiseGit只能支持比对纯文本文件的变化差异,如果尝试比对二进制文件,会提示这不是一个有效的文本文件: BeyondCompare可以比对二进制…...
8、HTTP/1.0和HTTP/1.1的区别【高频】
第一个是 长连接: HTTP/1.0 默认 短连接,(它也可以指定 Connection 首部字段的值为 Keep-Alive实现 长连接)而HTTP/1.1 默认支持 长连接,HTTP/1.1是基于 TCP/IP协议的,创建一个TCP连接是需要经过三次握手的…...
Rk3568驱动开发_开发环境的搭建_1
1、环境说明: 需要用官方的程序包,这个程序需要在虚拟机里编译再将镜像烧录到板子里,本质上是给板子上一套Linux操作系统,镜像是.img文件 Linux操作系统被分成了多个模块,编译好后储存在镜像里,本质上就和…...
Solr中得Core和Collection的作用和关系
Solr中得Core和Collection的作用和关系 一, 总结 在Apache Solr中,Core和Collection 是两个核心概念,他们分别用于单机模式和分布式模式(SolrCloud)中,用于管理和组织数据。 二,Core 定义&am…...
Visual Studio Code 远程开发方法
方法1 共享屏幕远程控制,如 to desk, 向日葵 ,像素太差,放弃 方法2 内网穿透 ssh 第二个方法又很麻烦,尤其是对于 windows 电脑,要使用 ssh 还需要额外安装杂七杂八的东西;并且内网穿透服务提供商提供的…...
如何看到 git 上打 tag 的时间
在 Git 中可以通过以下方法查看标签(tag)的创建时间: 使用 git show 命令: 运行以下命令可以查看某个特定标签的详细信息,包括创建时间: git show 输出中会包含 Tagger 的信息和 Date 字段,显示…...
【HarmonyOS Next】鸿蒙TaskPool和Worker详解 (一)
【HarmonyOS Next】鸿蒙TaskPool和Worker详解 (一) 一、TaskPool和Worker如何实现多线程?各自特点是什么? 在鸿蒙中通过TaskPool和Worker实现多线程并发,两者都基于Actor并发模型实现。 Actor并发模型,每…...
如何设置HTTPOnly和Secure Cookie标志?
设置HttpOnly和Secure标志于Cookie中是增强Web应用安全性的重要措施。这两个标志帮助防止跨站脚本攻击(XSS)和中间人攻击(MitM)。下面是关于如何设置这些标志的具体步骤: 设置方法 在服务器端设置 根据你的服务器端…...
几个api
几个api 原型链 可以阅读此文 Function instanceof Object // true Object instanceof Function // true Object.prototype.isPrototypeOf(Function) // true Function.prototype.isPrototypeOf(Object) // true Object.__proto__ Function.prototype // true Function.pro…...
Deepseek本地部署指南:在linux服务器部署,在mac远程web-ui访问
1. 在Linux服务器上部署DeepSeek模型 要在 Linux 上通过 Ollama 安装和使用模型,您可以按照以下步骤进行操作: 步骤 1:安装 Ollama 安装 Ollama: 使用以下命令安装 Ollama: curl -sSfL https://ollama.com/install.s…...
基于 DeepSeek+AutoGen 的智能体协作系统
用 AutoGen 实现智能体协作流程,假设团队里的 3 个角色,让 3 个角色相互交流后并给出不同方案,最后进行总结。下面是实现的思路,欢迎一起学习交流。 一、系统设计 1. sre_engineer_01 - 问题诊断与初步解决方案 职责:…...
博客系统笔记总结 2( Linux 相关)
Linux 基本使用和程序部署 基本命令 文件操作 显示当前目录下的文件 ls:显示当前目录下的文件 ll:以列表的形式展示,包括隐藏文件 进入目录 && 显示当前路径 cd:进入目录(后面跟相对路径或者绝对路径&…...
计算机毕业设计SpringBoot+Vue.js电影评论网站系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
精美登录注册UI,登录页面设计模板
精美登录注册UI,登录页面设计模板 引言 在网页设计中,按钮是用户交互的重要元素之一。一个炫酷的按钮特效不仅能提升用户体验,还能为网页增添独特的视觉吸引力。今天,我们将通过CSS和JavaScript来实现一个“精美登录注册UI,登录页面设计模板”。该素材呈现了数据符号排版…...
《Linux系统编程篇》共享内存(Linux 进程间通信(IPC))——基础篇
文章目录 引言什么是共享内存System V 共享内存 API 引入1. shmget2. shmat3. shmdt4. shmctl5. 结构体 shmid_ds 开始实操注意 结束 今天的你有没有前进一小步呢 ——家驹(StrangeHead) 引言 那么共享内存,我们如何去使用他呢,先来听笔者啰嗦一段话吧…...
【EB-03】 AUTOSAR builder与EB RTE集成
AUTOSAR builder与EB RTE集成 1. Import Arxml files to Tresos2. Run MultiTask Script3. Add Components3.1 Run EcuExtractCreator Script4. Mapping Component to Partitions5. Event Mapping/Runnables Mapping to Tasks6. Port Connect7. Run SvcAs_Trigger Script8. Ver…...
HTML——前端基础1
目录 前端概述 前端能做的事情编辑 两步完成一个网页程序 前端工具的选择与安装 HTML HTML5介绍 HTML5的DOCTYPE声明 HTML基本骨架 文字标签 标题之标签 标签之段落、换行、水平线 标签之图片 标签之超文本链接 标签之文本 列表标签之有序列表 列表标签之无序…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
