Yinghuhu333333的博客

搬砖砖砖砖砖...........................................

1.数组和链表的区别2.栈和队列的区别3.static关键字的作用4.volatile关键字5.宏的优缺点6.assert断言7.引用和指针的区别8.EOF与feof的区别8.解引用空指针

数组和链表的区别

数组:
①数组的空间是一块连续的空间。
②对数组的读取快速方便,直接通过下表访问,时间复杂度为O(1)。
③使用数组时必须提前开辟好空间,但是如果使用不完,就会存在浪费空间。但是如果不够用,就要重新开辟空间,原来数组中的内容也必须拷贝过去。
④在数组中进行随意位置的插入和删除不方便,必须移动数据。
链表:
①链表的空间不是连续的,每个节点都保存着下一个节点的位置。
②对链表中的节点进行读取的时候,必须遍历整个链表,时间复杂度为O(n)。
③链表便于插入和删除。

栈和队列

栈:
①规则:先进后出。
②只能在栈顶进行元素的删除和插入。
队:
①规则:先进先出。
②一端进行插入,另一端进行删除。

static关键字

①修饰变量:如果在代码块内部,用static修饰时,其生命周期就会变为整个程序的生命周期,作用域不变。如果是一个全局变量用static修饰,生命周期和作用域都是整个程序,但是会改变链接属性(就是不可以在另外的文件中使用该变量)。
②修饰函数:只能在本文件中使用该函数,不可以在其他文件中使用。

volatile关键字

作用:保证内存的可见性。当用const修饰变量时,就会优化代码,将代码往寄存器中拷贝一份,当调用的时候就直接从寄存器中读取,但是如果想改变其内容的话,就只能改变内存中值,寄存器中的值却无法改变。所以此时就可以用volatile去修饰这个变量,当再次读取的时候就会从内存中读取。
记录一下杂碎的知识点。

宏的优缺点

  1. 优点
    ① 作为常量:增强代码的可维护性。
    ②作为函数:提高了效率(因为宏会在预处理阶段进行替换,没有栈帧开销)。
    但是,作为函数时,不能出现递归。否则会增加代码的冗余度。
  2. 缺点
    ①不方便调试。
    ②没有类型安全的检查(宏常量)。
    ③当宏作为函数时,代码的可读性差,可维护性差,容易错(优先级 )。
如何用宏写一个swap函数:
#define Swap(a,b) {int tmp = a;a = b;b = tmp;}

在C++中提供了inline(内联)函数,在宏的基础上可以进行类型的检查和便于调试(在dbug模式下有栈帧的开销)。在Release模式下会优化 不会展开没有栈帧的开销。 同样inline函数在使用内联函数的地方展开,使用时如果代码量过长,也会造成程序的膨胀。内联函数必须跟定义放在一起,如果跟声明放在一起并没有作用。

6.assert断言

程序一般分为Debug版和Release 版,Debug:用于内部调试;Release:发行给用户使用。
assert:仅在Debug版本中起作用的宏,用于检查“不应该”发生的情况。当assert条件为假,那么程序就会终止,这样就可以提示程序员程序在哪儿出错了。在函数的入口处使用断言可以检查参数的有效性(合法性)。下面我们写一个memcpy库函数来使用一下断言:
assert的头文件是:assert.h

void *my_memcpy(void* dest,const void* src,size_t count)
{
    char* to = (char*)dest;
    char* from = (char*)src;
    assert((dest != NULL) && (src != NULL));
    while(count-- > 0)
    {
        *to++ = *from++;
    }
    if(*to != '\0')
    {
        *to = '\0';        //如果没有拷贝整个src的字符串,就需要手动加上‘\0’
    }
    return dest;
}

当程序中有不能容忍的错误时,就用assert断言来给程序员们发出警报。

引用和指针

引用:别名(绰号)
指针:地址空间
引用和指针的区别:
这里写图片描述
我们来解释一下第三条:

int i = 3;
int j = 5;
int &k = i;
k = j; //错误

EOF与feof

EOF(end of file):其实就是一个宏,文件结束的标志.在文件的内部就有一个EOF,就是-1,当文件读到-1时,就表示文件读完了.类比:字符串中的’\0’.只可以用来判断文本文件是否结束.
feof:同样也可以用来判断文件是否结束,但是feof()是一个函数.若文件已经结束,就返回1,否则返回0.既可以来判断文本文件的结束,也可以判断二进制文件的结束.
相同点:都可以用来判断文本文件是否结束.

解引用空指针

我们编写的代码,都是在虚拟地址上,虚拟地址通过页表可以转换到对应的物理地址上.所以,在解引用空指针时,MMU在通过页表的转换为物理地址时,就会发现这是一个不合法的地址访问.所以硬件设备此时就会发送一个异常到内核.内核将其解释为SIGSEGV(11号信号)发送到对应的进程.从而就会引发程序崩溃.
下面这个例子:

  1 #include <stdio.h>
  2 #include<signal.h>                                                                                                   
  3 
  4 void Handler(int sig)
  5 {
  6     printf("sig = %d\n",sig);
  7 }
  8 int main()
  9 {
 10     //signal(SIGSEGV,Handler);   //如果使用这个自定义的信号捕捉函数,就会死循环
 11     signal(SIGSEGV,SIG_IGN);  //如果忽视,程序依然后崩溃.因为Linux操作系统对于每种的信号忽略的处理方式不同.
 12     int *p = NULL;
 13     *p = 10;
 14     return 0;
 15 }

在使用自定义的信号捕捉函数时,由于每次在执行解引用空指针进行赋值时,这条语句并没有执行完就去调用信号处理函数.然后又回到函数的上下文处进行执行,又发现了错误,又去调用信号处理函数.以此就会造成死循环.

指针数组&数组指针

指针数组:是一个数组,只是数组的每个元素都是指针.
例如:int *ptr[10].
数组指针:是一个指针.而这个指针指向了一个数组.例如:int (*ptr)[10];

阅读更多
个人分类: C语言
上一篇C++的String类的实现 &amp;&amp; 深拷贝 &amp;&amp; 写时拷贝
下一篇1.进程2.僵尸进程3.孤儿进程4.进程的优先级
想对作者说点什么? 我来说一句

C语言终极面试宝典(必看)

2014年02月25日 807KB 下载

c++中指针引用区别

2009年02月18日 14KB 下载

数组指针之间的区别与联系

2011年03月30日 30KB 下载

C++指针引用区别

2012年03月11日 72KB 下载

*,&的区别,输出*str,&str和str

2008年12月23日 379B 下载

没有更多推荐了,返回首页

关闭
关闭