zoukankan      html  css  js  c++  java
  • 0.0C语言重点问题回顾

    1. 左值和右值得区别:左值是用来表明变量的身份的,右值更加侧重于值本身;

    2. void*是个例外,它只有基地址没有类型信息,所以无法解引用。

     int *p = malloc(100);
     char *s = malloc(100);
    

    很显然,p和s本身的值就是内存基地址的数值,但是p[3]和s[3]值是不相同的,因为p和s的类型不相同,p是int型指针,所以p[3]是把后面这段内存当做int数组,s[3]则是看做char数组,所以p++一次增加数值为4(32bit),而s++增加1;

    1. C语言参数传递的方式为值拷贝。函数形参拷贝实参的值后,与实参再无关联。正确的方式是采用指针,交换T类型的变量,那么swap函数的形参就要用T*类型的参数也就是说,交换两个int*,就要使用int**才可以达到目的。

    4.关于数组传参:

    a)一维数组用int做参数。在数组退化成int的过程中,数组仍可以正常使用,但是丢失了长度信息。
    b)二维数组int a[4][3],采用int()[3]作为参数,int()[3]作为参数,int(*)[3]是一个数组指针。这里丢失了第一维,所以需要手工指定第一维的长度。

    二维数组传参问题:一位数组可以看做是指针int*,二维数组也是指针但是不是int**而是一维数组的指针。

     void print_array(int (*a)[3], int m)
     {
    	 int i,j;
    	 for(i=0; i !=m; ++i)
    	 {
    		 for(j=0; j !=3; ++j)
    			 printf("%d", a[i][j]);
    	 }
    	 printf("
    ");
     }
    

    这种做法的缺陷就是只能传递第二位为3的数组,要使其更加通用,可以用如下解决方案:
    a.把数组用一个结构体包装起来,传参数的时候传递它的指针。
    b.数组用动态内存去分配。
    使用数组做参数,必须丢失最外围的长度信息,传递int a[10],丢失长度10,如果是int a[10][4],那么只能保留4,如果是int a[3][5][6],必须使用参数int ()[5][8],丢失最外面的3.
    二维数组 int a[10][5] a[i]等价于
    (a+i),而a[i][j]等价于((a+i)+j);
    二维动态数组的构造方法:

     int **a = (int**)malloc(5 * sizeof(int*));
     int i;
     for(i=0; i != 5; ++i)
     {
    	 a[i] = (int*)malloc(4 * sizeof(int*));
     }
    

    先生成一个数组,每个数组元素都是一个指针,然后我们依次为每个指针分配一段内存空间。

    1. 函数指针:我们过去所接触的指针通常是指向变量,但是在C语言中函数也可以是具有指针的。
     int *p = &i;
    

    这里仅仅是不能通过p修改i,例如*p = 2是错误的,但是i的值可以任意修改的,i = 34是正确的。
    这里做了两个工作:
    a.声明了一个int类型的指针,这个指针指向任何类型的int类型变量。
    b.用i的地址去初始化p(这里是初始化而不是赋值),这样p就指向了i这个变量。
    函数指针也是一样:

     void(* pfunc)(int, int);
    

    这里我们声明了一个变量pfunc,它的类型是void(*)(int, int)。只需要pfunc = &test就能够让指针指向一个函数。这里指针函数看起来比较繁琐,我们可以尝试用typedef进行简化:

     typedef void(* func)(int, int);
    

    需要注意的是:func是个类型不是变量。
    5. C语言内存本身没有属性:没有所谓的int、char、float等,指针的本质:一个是内存的基地址,一个是变量的类型。

     int *p1 = malloc(1000);
     char *p2 = malloc(1000);
    

    这两段做的内存工作完全是一样的,都是向操作系统申请一块大小为1000的内存空间。并不存在说第一块内存是int类型,第二块是char类型。那为什么p1++和p2++指针变动的数值会不一样?原因是指针的类型不一样,这与他们只想的内存没有任何关系,所以可得结论:C语言中内存都是相同的,如何解释他们,依据的是采用什么指针操控他们

    1. 程序从编写到运行:
      a)预编译:主要处理了以#开头的指令,#include #ifndef #define
      b)编译:编译针对的是单个源文件,生成.o目标文件
      c)链接:将每个目标文件链接起来,生成可执行文件
      头文件中不加预编译指令,造成重复定义是编译期错误;头文件中定义int a = 10;之类的语句属于链接期间错误。

    8.解决互斥问题的方案是:
    a)互斥锁、信号量
    b)原子操作,gcc提供CAS
    互斥是一种竞争关系,同步则是一种合作关系。有可能产生互斥问题的场景称为竞态条件。

    1. Linux中创建进程的方式有:fork、Vfork、clone
      fork:采用了一种“写时复制(COW)”技术,传统的UNIX进程模型中,fork进程是把整个进程的项赋值一份,开销巨大。COW就是在以前的基础上,子进程仅仅复制父进程的页表,然后设置为只读,任何一方试图修改项就将该项单独复制一份。
      clone用于创建线程。在linux中线程是采用了一种轻量级进程的实现,所以linux中的线程有两个ID,pthread_self()的pthread_t类型是所谓的线程id,然而还有一个真实的进程id,类型pid_t,获取方式为gettid().我们采用的线程模型叫做NPTL,它采用的是1:1线程模型

    2. 大小端问题:TCP传输,对于字符串不需要考虑大小端,对于int等需要考虑。总之就是对于以字节为逻辑单位的数据不需要考虑大小端。

  • 相关阅读:
    使用 JDBC 驱动程序
    (转载)SQL Server 2008 连接JDBC详细图文教程
    (转载)VB中ByVal与ByRef的区别
    (转载)Java里新建数组及ArrayList java不允许泛型数组
    在VS2008环境下编写C语言DLL,并在C++和C#项目下调用 (转载)
    近期计划
    在服务器上使用python-gym出现的关于显示的问题
    字符串匹配
    Ubuntu18.04 桌面系统的个人吐槽(主要是终端)
    Ubuntu18.04上安装N卡驱动、CUDA、CUDNN三连
  • 原文地址:https://www.cnblogs.com/stardujie89/p/3995763.html
Copyright © 2011-2022 走看看