C学习笔记 知识集锦(二)

 1. 数组和指针 2. 字符串赋值 3. memset&memcpy 4. 机器数和真值,原码,反码和补码 5. 文件指针和文件描述符 6. 内存泄露和内存损坏 7. 什么是不可移植的程序 8. 动态库文件和静态库文件 9. make的行为

10. 库函数调用和系统调用

  数组和指针

    数组:同类型的数的集合

      特点: 1. 数据类型一致 2. 大小固定 3. 内存空间连续 4. 数组名本质是指针常量,是该组的地址

      初始化: int a [10] = {‘\0‘} = 0; 也可以使用循环来赋空,也可以使用memset来赋空,全部赋为0的时候可以使用memset,当有不同值的时候不可以

        void *memset (void *s, int ch,size_t n);

        void *memcpy (void *dest, void *src,size_t n);

        一维数组的初始化,后面可以决定前面

          int a[5] = {1,2,3,4,5};  //合法

          int a[5] = {1,2,3,};    //合法

          int a[] = {1,2,3,4,5};    //合法,后面决定前面的大小

        二维数组的初始化,二维数组不可以缺省行,但可以缺省列,且二维数组名是行指针,即a+1是跳一行

          int a[2][3] = {1,2,3,4,5,6};    //合法,很标准的二维数组的赋值

          int a[2][3] = {1,2,3,4,5,};    //合法,后面一个默认为0

          int a[2][3] = {{1,2,3,}{4,5,6}};  //合法,每行三个

          int a[2][3] = {{1,2,}{3,4,5,6}};  //合法,第一行最后一个默认为0

          int a[2][3] = {1,2,3,4,5,6,7};  //不合法,赋值的个数多余数组的个数

          int a[][3] = {1,2,3,4,5,6};    //不合法,不可以缺省行的个数

          int a[2][] = {1,2,3,4,5,6};    //合法,可以缺省列的个数

      使用: int a[10] = 0;

          1. a表示数组名,是第一个元素的地址,也就是元素a[0]的地址,等价域&a,查找元素直接a[1]/a[2]

          2. a是地址常量,因为a一直指向的是a[0]的地址,所以出现a++,或者是a=a+2赋值的都是错误的

          3. a是一维数组名,所以它是列指针,也就是说a+1是跳一列//二维数组是跳一行

    指针:指针变量是存储其他变量地址的变量

      指针举例:char *p,*q;

          p = "xyz";  //p并不等价于字符串"xyz",而是指向一个由xyz+\0四个字符组成的起始元素的指针

          q=p;    //把p赋值给q,只是复制这个指针并不复制指针指向的字符串,p,q指向的是同一块内存区域,即q,p的取值是相同的

          q[1] = ‘y‘;  // &是取地址运算符,该操作符返回对象所在的内存地址 指针不能等同数组

        int *p,a[5] = {1,3,5,7,9,};最好分开定义,因为标识符是靠右结合的

        *p++:地址会变而值不变; (*p)++:是数值会变而地址不变, *p++:先执行++,再*取值,++的优先级更高

        *p++ = 3;因为本身数值为1,但是地址加1,所以移到3那里

        (*p)++ = 2;先取值再加1

        二级指针:只存放一级指针的地址

          指针的赋值与比较:在C++中指针变量的赋值和比较是基于指针变量的值,也就是说它所存储的地址,这样依赖,如果两个指针指向的是同一个对象,那么它们就是相等的

          如果指向不同的对象,那么即使指针变量指向的对象本身是相等的,指针变量也是不等的,举例,如果lhs和rhs是指针变量(兼容的类型),那么lhs = rhs 是使lhs指向rhs指向

          的同一个对象,数组事实上是一个指向内存的地址,而不是基本数组类型,对数组使用 = 的结果是复制两个指针的值,而不是复制整个数组

          ey:int x =7;

          int *p = &x,**q = p;

          答:*p = 7;*q=p;**q=7;

          简言之:int x = 7; int *p = &x, int **q = p;

          p = &x,推导出*p = 7;

  字符串赋值

    把s指针中的字符串复制到t指针中的方法

    1. while ((*t=*s)!=null) {  //完整版本

      s++;

      t++;

      }

    2. while(*t++ = *s++)    //高级版本 ++权限比*高,先执行++再执行*

  memset&memcpy  

    memcpy函数的用法 void *memcpy(void *dest, void *src,size_t n);

    函数的功能是从源src所指向的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

    注意size_t是字节数,一般都是sizeof()形式

    memset函数的用法 void *memset(void *s, int ch, size_t n);

    函数的功能是将s所指向的某一块内存中的前n个字节的内容全部设置为ch指定的ASCII码值,第一个值为指定的内存地址

    块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作,其返回值为指向s的指针,注意内存的相关事情:

  机器数和真值,原码,反码和补码

    机器数:一个数在计算机中的二进制表示形式,叫做这个数的机器数,机器数是带符号的,在计算机中用一个数的最高位存放符号,正数为0,负数为1,

      例如:十进制中的+3,计算机中的字长为8位,转换成二进制即是00000011,如果是-3,则是10000011

    真值:机器数对应的真正数值就是机器数的真值  //原码,反码,补码的基础概念和计算方法,只有有符号数才有这三种码

    原码:符号位加上真值的绝对值,即用第一位表示符号,其余位表示值

      举例:拿1作为int型的八位来计算,一般情况下,int对于16位编译器来说就是16位

        [+1]原=0000 0001; [-1]原= 1000 0001

    反码:正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各个位取反

        [+1]原=0000 0001; [+1]反= 0000 0001

        [-1]原=1000 0001; [-1]反= 1111 1110

    补码:正数的补码就是其本身,负数的补码是在其原码的基础上,符号位不变,其余各个位取反,最后加1(补码是在反码的基础上加1)

        [+1]原=0000 0001; [+1]补= 0000 0001

        [-1]原=1000 0001; [-1]补= 1111 1111

  文件指针&文件描述符

    文件指针:C语言中使用文件指针作为I/O的句柄,文件指针指向进程用户区中的一个被成为FILE结构的数据结构

      FILE结构包括一个缓冲区和一个文件描述符

    文件描述符:文件描述符表的一个索引,因此从某种意义上说文件指针就是句柄的句柄(在windows系统上,文件描述符被称作文件句柄),在linux系统中打开文件就会获得

      文件描述符,它是个很小的正整数(一般在0-255),每个进程在PCB(Process Control Block)中保存着一份文件描述符表

      文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针

  内存泄露&内存损坏

    内存泄露:未释放不再使用的内存称为内存泄露

    内存损坏:释放或改写正在使用的内存称为内存损坏

  什么是不可移植的程序

    例如我们把int的值看做一个确定不变的已知值定义了一个变量,那么这种程序就是不可移植的,程序也应该避免这种依赖于实现环境的行为

    如果依赖于实现环境,那么在另一个环境下此int如果与之前定义变量不同,那么就会进行类型转换,就此会导致不可知行为,像qint16等类型即是为移植而生

  动态库文件与静态库文件

    动态库文件:动态库文件的扩展名是.so

    静态库文件的扩展名是.a(静态库文件很大,比动态库文件大的多)

      不论静态还是动态,都是由.o文件创建的,都以lib开头, 当静态库文件与动态库文件同名时gcc会优先使用动态库,在程序编译时会被链接到目标代码中,程序运行时

      不再需要该静态库文件,而动态库文件在程序编译时并不会链接到目标代码,而是在程序运行时才被载入,因此在程序运行时还需要动态库文件存在

  make的行为

    输入make进行编译时,make程序在当前目录寻找名为makefile的文件,该文件作为工程文件已经被建立,这个文件列出了源代码文件间的依赖关系,make程序观察文件的日期,

    如果一个依赖文件的日期比它所依赖的文件旧,make程序执行依赖关系之后列出的规则  //makefile文件中的所有注释都从"#"开始一直延续要本行的末尾

  库函数调用与系统调用

    库函数调用:在所有的ANSI C编译器版本中,C库函数是相同的;它调用函数库中的一个程序;与用户程序相联系;在用户地址空间执行;它的运行时间属于"用户时间"

      属于过程调用,开销较小;在C函数库libc中有大约300个程序

    系统调用:各个操作系统的系统调用是不同的;它调用系统内核的服务;是操作系统的一个进入点;在内核地址空间执行;它的运行时间属于"系统时间";需要在切换到内核

      上下文环境然后切换回来,开销较大;在UNIX中大约有90个系统调用

      函数调用速度:系统函数调用<库函数调用<普通函数调用

    编译预处理不是C语言的一部分,不占运行时间,不要加分号,C语言编译的程序称为源程序,它以ASCII码数值存放在文本文件中

时间: 2024-11-06 09:55:36

C学习笔记 知识集锦(二)的相关文章

C++学习笔记 知识集锦(一)

1.内存管理的开销 2.函数调用框架 3.类为什么要定义在头文件 4.C++的组合 5.在类的外部定义成员函数 6.bool类型为什么可以当做int类型 7.无符号保留原则 8.C++类型检查 9.何时会发生隐式类型转换 10函数的返回值 11.浅拷贝 12.对数组无效的指引 13.cout的使用 14.文件的读写 15.名字查找 内存管理的开销 当在栈里自动创建对象时,对象的大小和它们的生存期被准确地内置在生成的代码里,这时因为编译器知道确切的类型,数量和范围,而在堆里创建对象还包括另外的时间

【Unity Shaders】学习笔记——SurfaceShader(二)两个结构体和CG类型

[Unity Shaders]学习笔记——SurfaceShader(二)两个结构体和CG类型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5596698.html 写作本系列文章时使用的是Unity5.3. 写代码之前: 当然啦,如果Unity都没安装的话肯定不会来学Unity Shaders吧? 阅读本系列文章之前你需要有一些编程的概念. 在VS里面,Unity Shaders是没有语法高亮显示和智能提示的,VS党可以参考一下这篇文章使代码高亮显示

SaltStack 学习笔记 - 第十二篇: SaltStack Web 界面

SaltStack 有自身的用python开发的web界面halite,好处是基于python,可以跟salt的api无缝配合,确定就比较明显,需要个性化对web界面进行定制的会比较麻烦,如果喜欢体验该界面的可以参考下面的文章  http://rfyiamcool.blog.51cto.com/1030776/1275443/ 我是运用另一个python+php来进行web开发,具体需要的工具有在我的另一篇文章里面介绍过,这里再重新进行整个开发介绍 首先介绍php 跟python通信的工具 pp

【Unity 3D】学习笔记四十二:粒子特效

粒子特效 粒子特效的原理是将若干粒子无规则的组合在一起,来模拟火焰,爆炸,水滴,雾气等效果.要使用粒子特效首先要创建,在hierarchy视图中点击create--particle system即可 粒子发射器 粒子发射器是用于设定粒子的发射属性,比如说粒子的大小,数量和速度等.在创建完粒子对象后,在右侧inspector视图中便可以看到所有的粒子属性: emit:是否是使用粒子发射器. min size:粒子最小尺寸. max size:粒子最大尺寸. min energy:粒子的最小生命周期

马哥学习笔记三十二——计算机及操作系统原理

缓存方式: 直接映射 N路关联 缓存策略: write through:通写 write back:回写 进程类别: 交互式进程(IO密集型) 批处理进程(CPU密集型) 实时进程(Real-time) CPU: 时间片长,优先级低IO:时间片短,优先级高 Linux优先级:priority 实时优先级: 1-99,数字越小,优先级越低 静态优先级:100-139,数据越小,优先级越高 实时优先级比静态优先级高 nice值:调整静态优先级   -20,19:100,139   0:120 ps

【Unity 3D】学习笔记三十二:游戏元素——游戏光源

游戏光源 在3D游戏中,光源是一个非常具有特色的游戏组件.用来提升游戏画面质感的.如果没有加入光源,游戏场景可能就会显得很昏暗.在unity中提供了三种不同的光源类型:点光源,聚光灯,平行光. 点光源 顾名思义,点光源是从一个点向周围散发出光的光源,就像电灯一样.创建点光源在hierarchy视图中点击create--point light: 创建完以后,点击点光源对象,在右侧inspector视图中可以看到点光源的所有信息: type:光源的类型.有point(点光源),directional

《Javascript权威指南》学习笔记之十二:数组、多维数组和符合数组(哈希映射)

Array(数组)是JavaScript中较为复杂的数据类型,同Java.C#.VB等程序语言的数组相比,Javascript数组中的元素不必为相同的数据类型,可以在数组每个元素上混合使用数字.日期.字符串.Object,甚至添加一个嵌套数组. 一.创建数组 1.var arr1 = new Array(); /var  arr2 = new Array(length); /var arr3 = new Array(element1,element2...); var arr4 = [eleme

汇编入门学习笔记 (十二)—— int指令、port

疯狂的暑假学习之  汇编入门学习笔记 (十二)--  int指令.port 參考: <汇编语言> 王爽 第13.14章 一.int指令 1. int指令引发的中断 int n指令,相当于引发一个n号中断. 运行过程相当于: (1)取中断类型吗n. (2)标志寄存器入栈:设置IF=0,TF=0. (3)CS.IP入栈 (4)(IP)=(n*4),(CS)=(n*4+2) 样例1:编写.安装中断7ch.实现求一个word型数据的平方,用ax存放这个数据. assume cs:code code s

Android学习笔记(十二)——使用意图传递数据的几种方式

使用意图传递数据的几种方式 点此获取完整代码 我们除了要从活动返回数据,也常常要传递数据给活动.对此我们可以使用Intent对象将这些数据传递给目标活动. 1.创建一个名为PassingData的项目,在activity_main.xml文件中添加一个Button: <Button android:id="@+id/btn_SecondActivity" android:layout_width="fill_parent" android:layout_hei