最近在项目过程中发现了几个c语言中没有注意到的小细节,成功入坑。下面记录的我遇到的问题,以及解决的方法,希望这个过程能给读者带来些许启发。

字符类型变量的溢出

首先来看下面这段代码,你认为会输出什么呢?

int remain = 129
do{
char d = remain%128;
remain /= 128;
if(remain > 0)
d |= 0X80;
*s++ = d;
}while(remain > 0);
printf("str:%x\r\n",*str);

你也许会和我的想法相同,这返回不是81么?要是一眼就被看出来我也就不会记录下来了,往往我们定义数据类型时都忽略了2个问题,数据类型的取值范围与加unsigned与不加的区别,下面就通过这个例子来聊聊这两点。

先揭晓答案,这段伪代码的返回FFFFFF81,为什么呢? 因为char类型占1个字节的大小,其取值范围为-128~127,1+(-128)=-127,而在计算机中,负数是由补码表示,也就是我们看到FFFFFF81,在计算机中表示-127,而81,在计算机中表示正数129,也许还有个疑问,char类型占1字节大小,而FFFFFF81占了4字节大小,这不是空间溢出了么? 其实并没有,当变量是负数时,在计算机中由32位表示,但其所占的空间内存还是一字节

如果*s的数据类型是unsigned char结果又是什么呢? 没错,这回就真是81了,因为unsigned char的取值范围为0~255。是不是若有所思呢?下面来检验下收获吧,请看下面代码

short int a=1234;
short int *p=&a;
char *q=(char *)p;
char *k=(char *)p+1;
printf("address:%p--%p--%p\n",p,q,k);
printf("value:%x--%x--%x\n",*p,*q,*k);

实验写出上面代码的输出结果吧!

二维数组赋值

二维数组赋值,你知道几种方法呢,用for循环逐个完成、初始化时完成,使用下面的赋值方式你觉得怎么样呢?

char a[100][128];
char *topic = "matt test"; a[0] = topic; printf("a[0]:%s\r\n",a[0])

上面伪代码是个错误的例子,因为数组首地址不可被改变这条规则,所以编译器不会通过这段代码。如果用数组首地址对数组赋值,有什么方便的方法呢? 见下面代码

char a[100][128];
char *topic = "matt test"; memset(a,0x0,sizeof(a));
memcpy(a[0],topic,strlen(topic)); printf("a[0]:%s\r\n",a[0])

指针地址变化

C语言中,指针是一大精华,也是一个难点,使用不当容易造成内存泄漏,使系统不稳定。若对已初始化但未分配内存空间的指针写值,易造成segmentation fault(段错误)。下面指针的地址你清楚么?

short int a=1234;
short int *p=&a;
char *q=(char *)p;
printf("address:%p--%p--%p--%p\n",p,p+1,q,q+1);

指针地址的变化与指针的的数据类型相关,而在不同操作系统中,数据类型也有所不同,在64位Windows与linux系统中,char与int分别占1字节与4字节内存空间,故(P+1)-p为4,(q+1)-q为1.

清风 | 文 【原创】

如果本篇博客有任何错误,请批评指教,不胜感激 !

C踩坑纪实——(一)的更多相关文章

  1. 在mac下初次使用pygame踩坑纪实(卡死)

    初次使用pygame实现绘图功能就踩坑 直接上代码 import pygame pygame.init() # 创建游戏的窗口 480 * 700screen = pygame.display.set ...

  2. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  3. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  4. 【踩坑速记】二次依赖?android studio编译运行各种踩坑解决方案,杜绝弯路,总有你想要的~

    这篇博客,只是把自己在开发中经常遇到的打包编译问题以及解决方案给大家稍微分享一下,不求吸睛,但求有用. 1.大家都知道我们常常会遇到dex超出方法数的问题,所以很多人都会采用android.suppo ...

  5. NPOI导出Excel (C#) 踩坑 之--The maximum column width for an individual cell is 255 charaters

    /******************************************************************* * 版权所有: * 类 名 称:ExcelHelper * 作 ...

  6. 我的微信小程序入门踩坑之旅

    前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...

  7. router路由去掉#!的踩坑记

    项目中在研究去掉router#!的过程中的踩坑过程.

  8. vue+ vue-router + webpack 踩坑之旅

    说是踩坑之旅 其实是最近在思考一些问题 然后想实现方案的时候,就慢慢的查到这些方案   老司机可以忽略下面的内容了 1)起因  考虑到数据分离的问题  因为server是express搭的   自然少 ...

  9. 记jQuery.fn.show的一次踩坑和问题排查

    最近很少已经很少用jQuery,因为主攻移动端,常用Zepto,其实很多细节和jQuery并不一样.最近又无意中接触到了PC的需求和IE6, 使用了jQuery,刚好踩坑了,特意记录一下. 本文内容如 ...

随机推荐

  1. Python 简明教程 --- 19,Python 类与对象

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 那些能用计算机迅速解决的问题,就别用手做了. -- Tom Duff 目录 上一节 我们介绍了Pyt ...

  2. 怎么更改maven工程jdk版本(默为1.5,怎么更改jdk版本为1.8)

    使用maven 创建工程更改默认jdk版本(1.5)方法 step1: 找到自己项目的pom.xml文件,添加下图黄色区域代码(文末附上的有代码:可以直接复制) step2: 保存一下更改后的的pom ...

  3. JS中字符串和数组的相互转化

    题目:利用var s1=prompt("请输入任意的字符串:") ,可以获取用户输入的字符串,试编程将用户输入的字符串“反转”,并且将字符串输出. 思路:字符串对象的方法中并没有实 ...

  4. Nuxt+Express后端api接口配置与实现方式

    Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用.本文带你了解在 Nuxt.js 中使用 Express 如何编写实现后端的 api 接口. 创建接口 ...

  5. 【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值

    [SpringCloud]Gateway 配置全局过滤器获取请求参数和响应值 实现Ordered接口getOrder()方法,数值越小越靠前执行,记得这一点就OK了. 获取请求参数RequestBod ...

  6. django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.2的最佳处理方法,亲测可用

    django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.2 ...

  7. Mybatis一对一映射resultMap子标签中顺序问题

    直接上图 鼠标点上红线出现如下提示 The content of element type "resultMap" must match  "(constructor?, ...

  8. python 请使用迭代查找一个list中最小和最大值,并返回一个tuple

    请使用迭代查找一个list中最小和最大值,并返回一个tuple: 要注意返回的值的类型是不是tuple def findMinAndMax(L): min=0 max=0 if len(L)==0: ...

  9. MobileNetV1/V2/V3简述 | 轻量级网络

    MobileNet系列很重要的轻量级网络家族,出自谷歌,MobileNetV1使用深度可分离卷积来构建轻量级网络,MobileNetV2提出创新的inverted residual with line ...

  10. Java中的堆和栈以及堆栈的区别

    在正式内容开始之前要说明一点,我们经常所说的堆栈堆栈是堆和栈统称,堆是堆,栈是栈,合在一起统称堆栈: 1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Jav ...