库函数:

 

printf   system

总结:我们使用库函数去完成一些功能,库函数是编译器提供给我们使用的。但是我们如果要使用某一个库函数,就需要包含相应的头文件。

比如   printf 属于<stdio.h>   system 属于<stdlib.h>

 

关键字:

 

是C语言已经使用了的一些单词。

 

关于赋值时的类型转换:

我们在赋值的时候,如果赋值符号左右两边的类型不一致。

会自动的将右边的类型,转换为左边的类型,然后再赋值。这个叫做隐式转换。

缺点就是,当右边的类型范围大,左边的类型范围小的时候,有可能会丢失数据。

  int a = 10;
    short b = 0;
    a = b;
 
    int c = 100;
    short d = 20;
    d = c;
 
    int e = 65538;
    short f = 0;
    f = e;         //这里丢失数据了
    return 0;

 

显式类型转换:

#include  <stdlib.h>
int main()
{
    double a = 3.14;
    int b = 0;
    b = (int)a;//当我明确知道他俩类型不一样的时候,应该写显示转换,表示我是故意这么做的。
 
    return 0;
}

 

运算注意事项

1  /    在C语言中,两个整数相除,得到的只能是整数

如果要得到小数部分,应该有浮点数参与运算

自增或者自减 的前置后置问题

前置递增效率更高,后置式递增要拷贝一个临时对象。

1 int b = i++; 
2 //可以分解为一下过程:  
3 int temp = i;  
4 b = temp;  
5 i = i + 1;

同理n+=1的性能比n=n+1高

n+=1与n=n+1在结果上是等价的。但使用复合赋值操作符+=时,直接把1加到变量n的空间中去,左操作数只计算了一次加法;而使用长表达式 n=n+1时,先要去n这个变量空间中去取值(要寻址),与1做一次加法计算,然后做一次赋值计算把结果存入到n这个空间中,这样左操作数n计算了两次。因此,n+=1的性能更高。事实上,这也是复合赋值操作符存在一个基本原因。很多人刚开始八成会困惑,为什么会存在+=,-=,*=这样的操作符,能提高程序的性能就是其中的一个原因。

 

重载和句法区别

 

C++规定后缀形式有一个int类型参数,当函数被调用时,编译器传递一个0做为int参数的值给该函数。

一个例子可以说明一切

#include "stdafx.h"
 #include <iostream>

 class NumUpper
 {
 public:

   //前缀,返回引用
    NumUpper& operator++()
    {
      std::cout << "++ prefix\n";

      *this += 1; //operator+=
      return *this;
    }

    //后缀 返回const对象,int参数
    const NumUpper operator++(int)
    {
      std::cout << "postfix ++ \n";

      NumUpper preNum = *this;
      ++(*this);
      return preNum;
    }

     NumUpper& operator+=(int num)
     {
       mNum += num;
       return *this;
     }

  private:
    int mNum;
  };

  //main
  int main(int argc, char* argv[])
  {

    NumUpper upper;

    //前置
    std::cout << "-----------------------\n";
    ++upper;

    //后置
    std::cout << "-----------------------\n";
    upper++;

    //前置
    std::cout << "-----------------------\n";
    upper.operator++();

    //后置
    std::cout << "-----------------------\n";
    upper.operator++(0);

    std::cout << "-----------------------\n";
    system("pause");
    return 0;
  }

//output:

----------------------- 
++ prefix 
----------------------- 
postfix ++ 
++ prefix 
----------------------- 
++ prefix 
----------------------- 
postfix ++ 
++ prefix 
----------------------- 
请按任意键继续. . .

从上面的例子可以看到:

前缀形式返回一个引用

后缀形式返回一个const类型对象

 

 

 

 

 输出与输入

 

输出:

printf(“格式控制字符串”,参数列表);

 

格式字符串的形式为: % [输出最小宽度] [.精度] [长度] 类型 

例如,%d格式符表示 用十进制整形格式输出。%f表示用实型格式输出,%5.2f 格式表示输出宽度为5(包括小数点),并包含2位小数。常用的输出格式及含义如下:

%02X表示输出的16进制使用两个位置,如果只有一位的前面添0,比如15就输出0F

 

必背:

%d  整数

%c   字符

%s   字符串

%lf   双精度浮点

其他:

%x   十六进制整数  %X(大写方式表示)

%o   八进制整数

%p   输出地址

转义字符:

换行:  /n

”/”“ 打印:"

 

getchar()  获取一个字符

putchar()  输出一个字符

puts()    输出一个字符串

gets()    获取一个字符串

scanf 遇到空格,回车,跳格,宽度结束,非法输入,均会结束输入

 

我们如何掌握一个函数:

 

1  函数的功能是什么???

 

2  函数的这个功能,需要什么参数??

 

3  函数完成之后,你怎么得到结果??

 

 

 

 

 

 

字符串默认以0结尾(转义/0)

 

所有的安全版函数,都是针对字符串处理的。

strlen       求得一个字符串的长度

strcmp     比较两个字符串是否相等

strcat_s       拼接两个字符串

strcpy_s       将一个字符串拷贝一块缓冲区中

strcat_s(buf, 16 - strlen(buf), " End");

 

 

我们为什么要用无参宏:

 

好处1:便于修改

 

好处2:提高程序的可读性

 

 

 

指针

 

void *万能指针

p=0-255都是系统保留区域,不可读不可写

野指针指向未知空间,空指针指向编号为0的空间

 

int *p[5]   指针数组,是一个数组,里面全是指向int的指针

int (*p)[5]  数组指针,是一个指针,指向int [5]大小的数组

 

 

 

 

扩展补充:

 

按位与运算:

  0101

&0110

  0100

一般用于将某几个数清零(&0),或者取某几位(&1)

 

按位或

  0101

| 0110

  0111

经常用来将一个数的某一位设置为1

 

 

自动变量

auto num=1

必须初始化

全局变量:

在.h中声明:extern int a;  在cpp中定义int a = 0;

 

 

 

静态变量 static 作用类似,所有的全局变量均为静态变量,而局部变量只有定义时加上类型修饰符static才为局部静态变量。静态变量在整个程序执行过程中始终存在,在作用于之外不能使用。之初始化一次。

 

寄存器变量

register int nNum  

 

 

 

 

静态数据区

       已初始化区

       未初始化区

常量数据区

代码区

栈区

堆区                                     CPU寄存器组                    

为了加快速度常用寄存器变量(register),但是如果使用不频繁也会当初普通变量,不定义register如果使用频繁也会被当成寄存器变量

 

 

 

 

更多推荐

软件安全学习笔记——C语言