Loading

C语言日记② 初识 C的内存

第一节:
上一个笔记

有趣的恶搞小程序

定时关机

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
	//创建一个字符数组用于接收字符串
	char input[20] = { 0 };
	//使用system()执行定时关机的dos命令 命令库:#include <stdlib.h>
	system("shutdown -s -t 60");
again://跳到了这里
	printf("请输入我是猪,不然就关你电脑\n");
	scanf("%s", &input);//给input赋值
	if (strcmp(input, "我是猪")==0)//判断input数组是否为"我是猪" 命令库:#include <string.h>
	{
		//如果是,则取消
		system("shutdown -a");
	}
	else {
		//goto 可跳到对应代码段
		goto again;
	}
	return 0;
}

给两个数,返回最大值

int main() {
	printf("%d", checkNum(6, 2));
	return 0;
}
int checkNum(int num1, int num2) {
	return num1 > num2 ? num1 : num2;
}

其他操作符

- 负数
+ 正数
& 取地址
sizeof 取类型长度(字节)
~ 取反按二进制位取反
解释:
	int a = 2; //00000000000000000000000000000010
	int b = ~a;//11111111111111111111111111111101
	//~的解释为 按二进制位取反
	// 过程:
	//第一位为1 则是负数 0为正数
	//原码,反码,补码
	//在printf 中打印的是原码 而~所得的是补码
	//补码二进制减一得到反码
	//11111111111111111111111111111100
	//补码第一位不变,其他取反则为原码
	//10000000000000000000000000000011
	//此时输出-3
	printf("%d", b);

-- 省略 x=x-1
++ x=x+1

int main() {
	int a = 10;
	int b = a++;
	printf("a= %d  b= %d", a, b);
	return 0;
}

这里后置位++ 所以先使用再加减
反之如此

* 与上面取地址操作符是一对

(类型)xxx 强制转换
	int c = (int)3.14; //3
	printf("%d\n", c);

原码反码和补码

概念
在电脑中,只要是整数,在内存中存储的都是二进制的补码

正数:
原码,反码,补码相同

负数:
原码)
直接按照正负写出的二进制序列
反码)
原码符号位不变,其他按位取反得到反码
补码)
反码+1得到补码
比如说-3
源码:
1000000000000000000000000000011
反码
1111111111111111111111111111100
补码
1111111111111111111111111111101

常见关键字

auto 局部变量省略的关键字
break 停止循环 或者 跳出case
case 选择switch
char 字符
const 常量
continue 跳过本次循环
default switch 的默认
do while 先做再循环

    do{
        先做的方法块
    }
    while(循环条件);

double 双精度浮点
else 否则
enum 枚举
extern 引入外部符号
float 单精度
for 循环
goto 跳转到某行
if 如果
int 整数型
long 长整数

register 寄存器关键字

  • 计算机存储数据:
    1. 寄存器
    2. 高速缓存
    3. 内存
    4. 硬盘
  • cpu的速度越来越快,但是内存的访问速度跟不上
  • so-> cpu想要处理数据,取寄存器,高速缓存中拿
  • 拿数据的过程:
    • 内存->高速缓存->寄存器->cpu
	//如果使用量大,每次都要去内存中拿,所以效率会不理想
	//int a = 10;
	//接下来
	//把a定义为一个寄存器变量
	register int a = 10;

return 返回
short 短整型
signed 声明有符号数

	//int a = 10;
	//a = -2;
	//int是有符号的
	//所以定义时将signed省略掉了 完整的声明
	int signed a = 10;

unsigned 无符号数 这个数字永远都是一个正数

sizeof 计算类型大小
static 静态 :

  • 修饰的变量 生命周期会变长
  • static 修饰全局变量 会改变变量的作用域-让静态的全局变量只能在自己所在的源文件内部使用 方法也一样
  • 实现原理类似于 java 的 private 和 public

struct 结构体 简易的对象
switch 选择
typedef 类型定义 类型重定义 也可以叫起别名

	typedef unsigned int u_int; //定义一个无符号数的整数类型为u_int
	u_int a = 10;//声明一个u_int类型的变量

union 联合体 公用体
void
volatile 不被优化的

volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存

while 循环
循环十次:

	int b = 0;
	while (b<10) {
		b++;
	}

补充

关键字是不能和变量名冲突的

#define 定义常量和宏

定义常量:

#define MAX 100
int main() {
	int a = MAX;
	printf("%d", a);
	return 0;
}

定义宏

#define MAX(X,Y) (X>Y?X:Y)

	printf("%d\n", MAX(10, 20));

指针

内存

c语言操作地址指针方法:

	int a = 10;
	//输出对应地址
	printf("%p\n", &a);

	int* p = &a;
	//输出被赋值的p指针变量
	//与上面&a相同
	printf("%p\n", p);
int main() {
	//首先把a变量存放到地址中,存放10
	int a = 10;
	//取到a变量的地址 赋值给指针变量
	int* p = &a;
	//通过*p 解引用 直接指向指针对应的地址 然后修改里面的数值为20
	//此时a存放的值就变成了20
	*p = 20;
	//打印出来
	printf("%d\n", a);
	return 0;
}

指针内存的大小

指针大小:
32位机器 32个bit位序列
也就是4个字节

64位 则为64个bit
8个字节

vs2019 可在这里修改平台的位数

结构体

类似于java的类
*取到结构体指针
可以通过->属性名得到属性值

#include <stdio.h>
struct Book {
	int bookId;
	char name[];
};
int main() {
	//printf("%s", "我是你爹");

	//首先创建一个结构体 给俩属性赋值
	struct Book book1 = { 1,"钢铁是怎样炼成的" };

	//通过结构体变量.属性名称点出来对应属性值
	printf("书编号:%d,书面:%s\n", book1.bookId, book1.name);

	//创建一个结构体指针变量
	struct Book* pb = &book1;
	printf("%p\n", pb);
	
	//通过(*结构体指针变量).属性名 得到对应属性
	printf("书编号:%d,书面:%s\n", (*pb).bookId, (*pb).name);

	//通过结构体指针变量->属性名 得到对应属性
	printf("书编号:%d,书面:%s\n", pb->bookId, pb->name);

	return 0;
}

补充

在c中,数组的本质是个地址
所以pb->name=xxx代码是不行的,我们可以这样修改name

#include <string.h>

	//此方法可以修改char数组
	strcpy(pb->name, "骆驼祥子");

posted @ 2021-10-10 23:38  Micah666  阅读(104)  评论(0编辑  收藏  举报