zoukankan      html  css  js  c++  java
  • C踩坑纪实——(一)

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

    字符类型变量的溢出

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

    int remain = 129
    do{
    	char d = remain%128;
    	remain /= 128;
    	if(remain > 0)
    		d |= 0X80;
    	*s++ = d;
    }while(remain > 0);
    printf("str:%x
    ",*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
    ",p,q,k);
    printf("value:%x--%x--%x
    ",*p,*q,*k);
    

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

    二维数组赋值

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

    char a[100][128];
    char *topic = "matt test";
    
    a[0] = topic;
    
    printf("a[0]:%s
    ",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
    ",a[0])
    

    指针地址变化

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

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

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

    清风 | 文 【原创】

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

  • 相关阅读:
    Xshell安装教程及Xshell安装程序集组件时出错的解决方法
    Xshell远程连接的具体操作和Xshell多会话设置小技巧
    VMware中出现物理内存不足,无法使用配置的设置开启虚拟机解决方案
    在Scrapy中如何利用Xpath选择器从HTML中提取目标信息(两种方式)
    Sublime Text编辑器配置Python解释器简易教程
    虚拟机创建后该如何获取IP地址并访问互联网实用教程
    关于Scrapy爬虫项目运行和调试的小技巧(下篇)
    Spring的xml和注解对比
    Spring5.X的注解配置项目
    Spring的AOP快速实现通用日志打印
  • 原文地址:https://www.cnblogs.com/wdg-blog/p/13376838.html
Copyright © 2011-2022 走看看