问题起源:

  这几天在刷CCF的时候,图论那边经常用到赋最大值,一开始自己一直手工for循环赋值(INT_MAX或者是LONG_LONG_MAX),后来看到别人的代码,发现了一个比较高端的赋值  memset(起始地址,初始值,大小)(注:看到后才想起来OS里面有用到过)。代码简单啊,用的乐此不疲。

问题:

  直到赋值 memset(起始地址,INT_MAX,大小)的时候,调试的时候发现一直是负数,又用一个具体的数去赋值,发现还是负数(令我很懵。。)。有点得过且过的意思,就直接改用原来的for循环代替了。但问题是用此方法之前赋值0,-1的时候没有问题啊。好多次都这样,终于再也忍不了了,还是去查一查why

原因:

  1.为什么我赋值了INT_MAX,出来的却是负数?(或者是其他具体值)

    memset函数是以字节为单位来赋值的,即每个字节(注意是字节)的赋值是相同的。如果赋值的数值的二进制超过了一个字节,那么函数取的是该数值的最后一个字节的值

  EG:257的最后两个字节的二进制(补码)为:0000 0001 0000 0001,那么函数将0000 0001(最后一个字节),赋值给每一个地址,int 为4个字节,那么其计算十进制时,就有可能为负数(当字节最高位为1时)。

  2.为什么赋值0和-1的时候是没有问题的?

    本质还是1中的,0补码为全0,-1补码为全1,所以截取最后一个字节,在填充每个地址的时候,没有变化,所以值没有变。

用法:

  1.怎么用memset赋最大值?

    网上流传的是用 0x3f 来初始化,而不是用 0x7f(符号位为0,所以字节的最高为必须为0),至于为什么,大家说是因为:2个 0x7f7f7f7f 相加之后,会负溢出,所以还是用 0x3f 保险,而且用它来表示无穷大也是满足需求的(注:这个原因体会不深。。。还是看情况吧,我觉得根据实际情况而定,用 0x7f7f7f7f 也是可以的,等到出bug 了,体会就深刻了。。。)(刚刚写完说不深刻,果然真香,刚刚提交的代码就是因为这个原因出Bug——因为在图论中经常需要两个距离相加,所以还是用 0x3f好了)

    另外,有时候还能看到不用memset赋值,直接赋最大值为 0x7fffffff,也有些直接赋值为 0x7f7f7f7f 也都是可以的(只要满足你心中的MAX或者是题目中的要求了,都是可以的)

  2.怎么用memset对结构体或者结构体数组赋初始值?

    本质是一样的,所以用法跟平常的数组也是一样的。

EG:

关于memset函数--赋最大值的更多相关文章

  1. 如何给数组用fill函数和memset函数给数组赋初值

    fill是按照单元来赋值的,所以可以填充一个区间的任意值 #include<iostream> #include<stdio.h> #include<string.h&g ...

  2. 2018/08/23 cstring中memset()函数的运用

    好多东西其实以前已经查过了,然后当时理解的还行,可是过段时间没用有些又会忘记,然后又去找资料又查,浪费了不少的时间和精力,所以,我,曾国强,今天起,要好好做笔记了! 今天复习第一个知识点,为什么要叫复 ...

  3. memset函数的使用

    void *memset(void *s, int ch, size_t n); 说明:将s中前n个字节 (typedef unsigned int size_t)用 ch 替换并返回 s 关于mem ...

  4. memset函数用法

    1. memset()函数原型是extern void *memset(void *buffer, int c, int count) buffer:为指针或是数组 c:是赋给buffer的值 cou ...

  5. memset()函数及其作用(转)

    1. memset()函数原型是extern void *memset(void *buffer, int c, int count) buffer:为指针或是数组, c:是赋给buffer的值, c ...

  6. memset()函数

    memset需要的头文件 <memory.h> or <string.h> memset <wchar.h> wmemset  函数介绍 void *memset( ...

  7. memset()函数用法及其作用

    memset()函数原型是: extern void *memset(void *buffer, int c, int count) //buffer:为指针或是数组, //c:是赋给buffer的值 ...

  8. 一直误解的memset函数

    1.“想当然”导致的后果 今天犯了一个十分低级的错误,在对一个整型数组用memset进行初始化设置所有元素值为1.可是结果却大出所料,很意外啊!接着,我就做了代码测试. #include <io ...

  9. memset函数用法及注意事项

    头文件 #include<cstring>// or #include<memory.h> ------------------------------------------ ...

随机推荐

  1. class的真相

    Java中Class类及用法 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI.这项信息纪录了每个对象所属的类.虚拟机通常使用运行时类型信息选准正确方 ...

  2. ECMAScript课程

    ECMAScript的语法使用      https://blog.csdn.net/m0_37452696/article/details/78370504 ECMAScript 6简介说明   h ...

  3. hibernate HQL添加语句

    1.Hibernate HQL添加语句 save();方法使用HQL语句来完成插入操作是不能实现的,不管你使用insert into....values...还是insert into.....sel ...

  4. 为input标签绑定事件的几种方式

    为input标签绑定事件的几种方式 1.JavaScript原生态的方式,直接复制下面的代码就会有相应的效果 <!DOCTYPE html><html><head> ...

  5. xueping wang 记录

    https://www.bbsmax.com/A/lk5aVBod1O/ https://pkgs.org/statistics/ 在firefox的调试控制台, 下面有一个独立的分割的控制台窗口, ...

  6. Pormise

    //Pormisefunction MyPromise (executor) { var self = this self.status = 'pending' self.resolveValue = ...

  7. SQL Server監控与診斷

    僅為記錄工作中遇到的問題. 1. 字符串截斷: SQL server里很多job用於運行DTS,經常會收到系統出錯警報,如: ...String ) The statement has been te ...

  8. Vue-admin工作整理(十七):Mock模拟Ajax请求

    思路:使用Mock拦截actions请求,通过 Mock.mock(/\/getUserInfo/, 'post', getUserInfo) 进行拦截标示,然后将内容返回 export const ...

  9. 微信小程序点击列表添加 去除属性

    首先说一下场景:我所循环的数据是对象数组,设置了一个属性当作标记,通过这个标记的值判断是否给改元素添加样式 wxml: <view> <view wx:for="{{lis ...

  10. Socket编程 之使用fsockopen()函数

    fsockopen函数:初始化一个套接字连接到指定主机(hostname) get方式: client.php <?php //创建连接 $fp=fsockopen('localhost',80 ...