学习小总结

                                                                   学习小总结

       这两天看了《Linux C编程实战中的部分内容,主要有以下几个方面:

、gdb 调试器

      大部分初学者都对gdb调试这块很模糊,我个人认为简单的gdb调试对我来说是没有问题的作为一个菜鸟通过学习,我觉得这方面有了很大的提高。

      首先,gdb 调试是针对那些肉眼无法看到的错误所采用的方法,主要有结果错误或者出现段错误的问题而言的。

     gdb 调试的一般步骤为:

      

Linux@linux:~$ gcc 1.c -o 1 -g
Linux@linux:~$ gdb 1

如果成功进入调试阶段,就进行下面的步骤:

(gdb)list       //显示源代码,每次10行
(gdn)break      //断点的设置
(gdb)run        //程序从断点处开始run
(gdb)next       //让程序继续跑下去
(gdb)step       // 可以展开被调函数,让其分步执行
(gdb)q          // 退出调试阶段

上面这些就是gdb 调试的具体过程,其中next和 step可以交替使用,如果想看程序在被调函数中是如何执行的,建议使用step



二、程序中的常见错误及经典例题

1.这是一道数组和指针相结合的例题,很经典哦~

#include <stdio.h>

void main()
{
      int  a[5] = {1, 2, 3, 4, 5};

      int  *ptr = (int *)(&a + 1);          
  
      printf("%d, %d\n",*(a + 1), *(ptr -1))
                           
}

输出结果是:2,5     2很好理解,*(a + 1) <=>a[1],其中的5实际上就是由a[4]来的,( &a )指指针偏移了一个数组的大小,因此 (&a + 1) <=> &a[5],这样*(ptr - 1)的结果是5就不难理解了


2.这是一道改错题,很具有启发姓哦~

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
      char a;
      
      char *str = &a;
      
      strcpy (str, "hello");
     
      printf("%s\n",str);
      
      return 0
}

这个程序看起来很完美,但实际运行时却出现了大的错误,编译是可以通过的,但是程序会崩溃。正是由于str所指向的变量只占1个字节,而hello要占6个字节,所以需要更大的内存空间。聪明的你应该想到解决的方法了吧?

其实很简单,就是在使用str之前先申请内存空间,即  str =(char *)malloc(strlen ("hello") + 1);用完之后记得要释放内存哦,即free(str);嗯~ok!



、关于内存对齐的问题(Linux下64位机)

1.按8字节对齐

(1)

union data1
{
      double d;
      int i;
      char c1;
      char c2[9];
};

sizeof(union data1) = 16,由于double是8个字节而 char c2[9]占9个字节,所以为了内存对union data1就占16个字节。

(2)

struct data1
{
      double d;
      int i;
      char c1;
      char c2[9];
};
sizeof(struct data 1) = 24, 本应该是8 + 4 + 1 + 9 = 22,因为22不是8的倍数,为了内存对齐,所以应该是24而不是22.

2、按4字节对齐

(1)

union data2
{
      int i;
      char c1;
      char c2[9];
};
sizeof(union data 2) = 12,由于int 是4个字节,所以union data2的大小一定是4的倍数,char c2[9] 所占的字节数是9,所以整个union data2所占的字节数是12.

(2)

struct data2
{
      int i;
      char c1;
      char c2[9];
};
sizeof(struct data2) = 16, 由于4 + 1 + 9 = 14不是4的倍数,内存对齐所以答案应该是16.


3、交换顺序后的各种奇葩~~~

(1)

struct inner
{
     char c1;
     double d;
     char c2;
};

sizeof(struct inner) = 24;   内存的补齐原理,系统会给char c1分配8个字节的内存,同理char c2也一样,种种所有使得答案为24.

(2)

struct inner 
{
      double d;
      char c1;
      char c2;
};
si zeof(struct inner) = 16;    char c1和char c2各分配1个字节,其余6个字节的内存空闲,系统就轻而易举的给struct inner 分配了16个字节的内存。


4、复杂的嵌套问题,感觉不容易理解~~

(1)

struct inner
{
      char c1;
      double d;
      char c2;
};
union data4
{
     struct inner t1;
     int i;
     char c;
};
sizeof(union data4) = 24;   因为其中的sizeof(struct inner) =24,所以很容易理解到答案应该是24.

(2)

struct inner
{
      char c1;
      double d;
      char c2;
};
struct data4
{
      struct inner t1;
      int i;
      char c;
};
sizeof(struct data 4) = 3 2;   在整个结构体和共用体中,占内存最大的当然是double 了,所以是以8个字节为对齐标准,24 + 4 +1 = 29不是8的倍数,所以结果应该是32.


通过这两天的学习掌握了好多东西,这篇博客中可能会有很多不足,以后慢慢改进,加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值