零碎的C语言基础第三部分(结构体、数据存储、字符串与内存函数)

结构体

  • 函数传递的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销会比较大。
  • 结构体传参时,要传结构体的地址。
  • 栈区:局部变量、函数的形式参数、函数调用也开辟空间
    默认由高到低使用地址
  • 堆区:动态内存分配、malloc/free,realloc,calloc
  • 静态区:全局变量、静态变量

数据的存储

类型的意义:

  • 使用这个类型开辟内存空间的大小(大小决定了适用范围)
  • 决定了看待内存空间的视角(如:使用int和float存储相同数据内存数据会不一样)

数值计算

  • 内存中用补码对整数数据进行存储
  • 使用补码可以让减法更加方便(cpu只有加法器)
  • 1-1
    1+(-1)
    //原码相加
    00000000000000000000000000000001
    10000000000000000000000000000001
    10000000000000000000000000000010
    //补码相加
    00000000000000000000000000000001
    11111111111111111111111111111111
    00000000000000000000000000000000

大小端存储

  • 大端模式,数据的地位保存在内存的高地址中,而数据的高位保存在内存的低地址中
  • 小端模式,是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中

整形提升

#include<stdio.h>
int main()
{
	char a=-1;
	singned char b=-1;
	unsigned char c=-1;
	printf("a=%d,b=%d,c=%d",a,b,c);
	return 0;
}//输出为-1,-1,255
  • 对于char a=-1
    在内存中a的数据为11111111;补码表示
    由于打印数据为int则发生整形提升
    char为有符号整型,则在a前面填充24个符号位数值1
    得到(int)a内存数据为:11111111111111111111111111111111(此处依旧为补码)
    将该补码同样的转换回原码时得到10000000000000000000000000000001即-1
  • 对于singned char b=-1同上
  • 对于unsigned char c=-1
    与char a=-1类似
    只是由于unsigned为无符号数,则在整形提升时填充24个0(无符号默认正数)
    得到了(int)c内存数据为:0000000000000000000000011111111(补码)
    计算原码得到255

浮点数

  • 浮点数在计算机内存中的存储通常遵循IEEE 754标准。根据这个标准,一个浮点数通常由三部分组成:符号位、指数部分和尾数部分。
  • 符号位:用于表示数的正负,占据一个比特位,0代表正数,1代表负数。
  • 指数部分:用于表示数的阶码(指数),通常以偏移值的形式存储,这个偏移值可以确保指数可以表示负数。指数部分用来调整浮点数的数量级。
  • 尾数部分:也称为尾数或尾数部分,用来存储浮点数的有效数字部分,决定了浮点数的精度。
  • 单精度浮点数(32位)通常按照以下格式存储:
    符号位(1位)
    指数部分(8位)
    尾数部分(23位)
  • 双精度浮点数(64位)通常按照以下格式存储:
    符号位(1位)
    指数部分(11位)
    尾数部分(52位)
int main()
{
	float f = 5.5;
	//5.5
	//101.1;二进制写法
	//(-1)^0*1.011*2^2;IEEE 754写法
	//S=0;符号位
	//E=2;指数部分,此处加上偏移量127(2^7-1)为129即100000001
	//M=1.011;尾数部分
	//0 10000001 01100000000000000000000;内存存储数据
}

字符串与内存函数

字符串函数

strlen

  • size_t strlen(const char * str);
  • 字符串以’\0’作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数 (不包含’\0’)。
  • 参数指向的字符串必须要以\0’结束,
  • 注意函数的返回值为siz_t,是无符号的

strcpy

  • char* strcpy(char * destination,const char * source);
  • 源字符串必须以’\0’结束。
  • 会将源字符串中的’\0’拷贝到目标空间
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须修改

strcat

  • char * strcat(char * destination,const char* source)
  • 源字符串必须以’\0’结束。
  • 目标空间必须足够大,以确保能存放新字符串
  • 目标空间必须修改

strcmp

  • int strcmp(const char* str1,const char * str2)
  • 第一个字符串大雨第二个字符串,返回大于0的数字
  • 第一个字符串等于第二个字符串返回0
  • 第一个字符串小于第二个字符串,返回小于0的数字

strstr

  • char* strstr(const char * ,const char *);查找字符串

strtok

  • char * strtok(char * str,const char * sep)
  • sep参数是给字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符的标记
  • strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针
  • strtok函数的第一个参数部位NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回NULL指针

内存函数

memcpy

  • void * memcpy(void * destination,const void * source,size_t num)
  • 函数memcpy从source的位置开始向后复制num个字节的数据到destionation的内存位置。
  • 这个函数在遇到’\0’的时候并不会停下来
  • 如果source和destination有任何的重叠,复制的结果都是未定义的

memmove

  • void *memmove(void *dest, const void *src, size_t n);
  • (能够处理内存重叠区域的复制类似memcpy)

memcpy

  • int memcmp(const void *ptr1, const void *ptr2, size_t num);
  • 按字节比较 ptr1 和 ptr2 所指向的内存区域的前 num 个字节。
  • 如果两个内存区域在前 num 个字节上完全相同,则返回值为0;
  • 如果不同,返回值为第一个不同字节的差值(ptr1 的字节值减去 ptr2 的字节值)。

memset

  • void *memset(void *ptr, int value, size_t num);
  • 用于设置一块内存区域的值
  • 注意此处num表示为字节数
注意上述函数中的修改区域是按某数据类型还是字节划分
#include <stdio.h>
#include <string.h>

int main() {
    int arr[5]={0};
    memset(arr, 1, sizeof(arr));
    return 0;
}
//会使得arr内存空间为(0x)01 01 01 01 01 01 01 01 01 01...

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值