自用Linux/C高级学习笔记(三)

一、C数据类型及语句

1、C语言的程序框架

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

int  main(int arg,char * argv[])
{
      //用户自己的代码
 
    return 0;
}

  1)头文件说明

      #include             //头文件----包含一些函数的声明,或者说是一些数据类型的声明。C语言中用       一个东西用之前必须要先有(声明,定义)

      #include      "xxxx.h"      //自己写的头文件用”"包含

2、C语言的注释

  1)单行注释      //

   2)批量注释代码   /*    注释的内容  */       注意:/*和*/是就近匹配原则

   3)批量注释代码    

        #if    0

            注释的代码内容

        #endif

int  main(int arg,char * argv[])
{
    //自己写的代码
#if  0
    //如果#if  后面跟的是0  表示#if  0  到#endif之间的内容为注释,如果#if后面跟的是1,表示#if  1到#endif
    //之间的内容为代码内容
    printf("%s","you  are  my  world\n");
    printf("%s","you  are  my  world\n");
#if  1
    printf("%s","you  are  my  world\n");
    printf("%s","you  are  my  world\n");
#endif
    printf("%s","you  are  my  world\n");
#endif
    printf("%s","you  are  my  world\n");
    printf("%s","you  are  my  world\n");
    printf("%s","you  are  my  world\n");
    printf("%s","you  are  my  world\n");
    printf("%s","you  are  my  world\n");
    return 0;
}

3、程序的编译过程

编译的4个过程:

1) 预处理         会将头文件、宏原地展开,去掉注释

2) 编译            将.i的预处理文件编译成汇编文件

3) 汇编             汇编将汇编文件转换成二进制文件

4)链接               将各个函数的二进制文件按照规则组织起来

预编译:

gcc    -E    xx.c     -o    xx.i           //.i是预处理文件

编译:

             gcc      -S     xx.i     -o     xx.s        //.s是汇编文件

汇编:(只编译,不连接)

            gcc       -c      xx.s    -o     xx.o         //.o是二进制文件

链接:

          gcc      xx.o     -o      xx.out           //.out是可执行文件

参数:

      -o        指定输出可执行程序的名字

     -Wall     编译优化,语法的严格检查

-I 后面跟头文件的路径,说明头文件查找的路径(大写的i)

-lxxx 说明程序编译链接的库名

-L 添加三方库的路径

gcc      xxx.c    xxx.c       -o     输出程序名字

程序的执行:

./可执行程序的名字

4、关键字

 1、关键字的定义

          用来表示特定内容的,特定语法的符号,一般C语言里面有32关键字,分别表示存储类型、数据类型、控制语句、以及其他。

  2、存储类型关键字

              auto       static       extern        register       const    volatile

主要去说明数据存储在什么位置,或者限定变量或者函数作用的范围 (能作用在哪个文件)

  3、数据类型关键字

             char:单字节整型数或字符型数       short:短整型数             int:基本整型数         long:长整型数

             float:单精度浮点型数           double:双精度浮点型数        signed:有符号数(默认的就是有符号)       unsigned:无符号数数据

            void:无数据类型、空数据类型           typedef:重新进行数据类型定义

             struct:结构体类型数据                enum:枚举类型数据          union:联合类型数据

主要说明,修饰的符号(一般都是修饰变量的),内存分配分配多大。

  4、控制语句的关键字

           if:构成选择语句      else:构成选择语句      switch:构成选择语句        case:构成选择语句

            break:跳出最内层循环        default:构成选择语句        for:构成循环语句

            do:构成循环语句          while:构成循环语句        continue:转向下一次循环

             goto:无条件转移语句       return:函数返回

   5、其他的

             sizeof

5、用户标识符

用来表示一些自己想表示的内容的一些符号。比如说后面变量的命名。比如说我想在程序中表示成绩,可以用socre这样的一些符号等等。

用户标识符定义:

     1)以数字字母下划线组成

     2)不能以数字打头

     3)不能和关键字重名

VOid   void      a            A        A8      A_8        9A    _A    IF if

注:在C语言里面区分大小写

 6、常量

常量一般是指一些固定的不能变化的量,在程序语言中可以体现为数值(eg:1,2,3,4,5......),也可以是字符常量(eg:'a','b','c'.....),也可以是字符串常量("hello world","hahahhahah",......)

1、数值常量

数值型常量在C语言中除了用十进制表示之外,还可以用二进制,八进制和十六进制来进行表示。当然对于数值来说,我们还分为:整数、浮点数(小数)、正数、负数等等

2、正整形数值的表示方法

正整数在C语言中通常使用十进制、二进制、八进制、十六进制进行表示

3、各种进制数据的表示

 1、二进制(0~1)

       满2进1,在计算机中使用的比较多。二进制以0b开头,在二进制中不能有超过2的数据值

     eg:0b110     0b01110

2、八进制(0~7)

      满8进1,在计算机中八进制以0开头,在八进制的数据中不能有超过8的数据值

      eg:0134   

3、十进制(0~9)

       满10进1,我们生活中常见的数据值就是10进制的,生活中怎么表示的,计算机中就怎么表示

      eg:11    12

4、十六进制(0~F)

      满16进1。在计算机中十六进制以0x开头   (A---10    B--11   C--12   D--13   E---14   F--15)

     eg:0x3344

4、进制的转换

   1、 二进制转换十进制:

            每位的数据值*位权值进行加和得到。

    2、十进制转二进制

3、八进制转十进制

        方法和二进制转换一样

4、十进制转8进制

      方法和二进制差不多,除8倒取余,直到商为0

5、十六进制和二进制之间的转换

       十六进制和十进制的转换参照二进制(略),我们主要研究和二进制的转换。

        一个十六进制位代表4个二进制位。

5、正整形数值在内存中的存储方式

大端存储模式:(0x12345678)

高字节存储在低地址上,低字节存储在高地址上

小端存储模式(Linux):

高字节存储在高地址上,低字节存储在低地址上

6、负整形数值在内存中的存储方式

负数,最高位表示符号位,符号位为1表示负数。在C语言中表达的时候,只需要在正数前添加负号即可。在内存中存储的时候,存储的是补码。

补码得到的方式:

源码:在正数的基础上添加符号位

反码:对源码按位取反得到反码(注意符号位不变)

补码:对反码+1得到补码

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

int  main(int arg,char * argv[])
{
    int  a = -18;
    printf("---%u\n",a);
    printf("-- %d\n",a)     
    printf("%u\n",-18);
    printf("%d\n",-18);
    return 0;
}

7、小数

小数在C语言中的表现形式: xx.xx 1.3

科学计数法: 1e-3 表示1*10^-3

1.3f 表示单精度浮点数

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

int  main(int arg,char * argv[])
{
    printf("%f\n",1.3);
    printf("%f\n",13e-1);
    return 0;
}

8、字符常量

1、单个字符常量

单个字符常量用单引号引起来

eg:

‘a' 'c' '1' 'abc'(错误的,单引号中只能是单个字符)

2、多个字符常量(字符串常量)

多个字符用双引号引起来

eg:

"hello" "world"

注意的是:

一般来说一个字符占一个字节,在内存中存的时候字符串中多包含一个'\0',即存储时要多开辟一个字符的内存

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

int  main(int arg,char * argv[])
{
    char  a='a';
    printf("%c\n",'a');
    printf("%ld\n",sizeof(a));
    printf("%s\n","hello");
    printf("%ld\n",sizeof("hello"));
    return 0;
}
3、字符及字符串在内存中存储的方式

字符在内存中以ASCII码值的形式存储

man ASCII

对于我们需要记住的是:

’0‘ -------48

’a'---------97

'A' --------65

空格 --------32

0 '\0' NULL '0'的区别

((void *) 0)

4、转义字符

1、常见的转义字符:

'\t' ----table键 '\n' 换行 '\0' -------ASCII码值0 ‘\r' 回到首行符号 '\a' 发出警报

2、八进制的转义:

'\ddd' 每个d的取值范围是0-7 这里只能有3个数据位

eg:以下字符描述正确的是:

A: '\123' B :'\18' C:'\1234' D:'\183'

3、十六进制的转义:

'\xhh' 每个h的范围是0~9或者是a~f 这里只能有2位十六进制

eg:以下字符描述正确的是

A:'\af' B:'\123' C:'\x3df' D:'\xab'

5、拓展

printf 的格式输出符号

形式:printf("格式控制符1 格式控制符2....",1的匹配变量/常量,2的匹配变量/常量...)

%d 十进制有符号整数 %u 十进制无符号整数

%x, 以十六进制表示的整数 %o 以八进制表示的整数

%f float 型浮点数

%lf double 型浮点数

%e 指数形式的浮点数

%s 字符串

%c 单个字符

%p 指针的值

特殊应用:

%3d

%03d

%-3d

%5.2f

%3d:要求宽度为 3 位,如果不足 3 位,前面空格补齐;如果足够 3 位,此语句无效

%03d:要求宽度为 3 位,如果不足 3 位,前面 0 补齐;如果足够 3 位,此语句无效

%-3d: 要求宽度为 3 位,如果不足 3 位,后面空格补齐;如果足够 3 位,此语句无效

%.2f:小数点后只保留 2 位

9、变量

在C语言中,有些符号需要去表示我们想表示的内容,但这些内容的数据值在程序运行的过程中可能会发生变化,这样的符号我们叫做变量。

1、变量的定义

变量的本质就是一片内存空间

存储类型 数据类型 变量;

2、修饰变量的存储类型

1、auto:

一般定义变量的时候,是省略的。自动存储类型,如果变量是局部变量,变量的内存分配就在栈内存中,如果是全局变量,变量的内存分配就在数据段。

2、 static:

1)修饰局部变量,内存分配在数据段,延长变量的生命周期

2)修饰全局变量,限制该全局变量在定义的文件中使用,别的文件不能使用

3)修饰函数,限制函数只能在定义文件中使用

3、 extern:

作用:主要是用来声明变量或者函数的。

声明变量:

一般extern声明的变量,定义在别的文件,在所要使用的文件中添加声明,添加的位置一般在头文中或者使用该变量文件的头文件下面

extern 数据类型 变量名;

4、 register:       

想将变量定义在CPU的寄存器中,但是不一定能实现,如果CPU的寄存器有空余的,就定义,没有就按auto这种存储类型来处理。

5、const:

const修饰的变量认为一个常量(不是说明变量存储在哪),而是变量不应该修改值

6、volatile:

一般是修饰易变的变量,作用是告诉编译器不要优化程序

7、sizeof :

主要是用来求数据类型,或者常量,变量的内存大小的。

注意:在进行变量赋值的时候,一定要注意数据类型表示的范围,数据有没有溢出。

3、变量的分类

全局变量:

定义在一对花括号外面的就是全局变量。在整个程序运行的过程中都有效(作用域:作用范围,程序任何地方都可以访问。生命周期:程序结束的时候)

局部变量:

定义在一对花括号里面的叫做局部变量。局部变量作用于所定义的花括号内部,出了定义的花括号就消亡了。

注意:

1)在同一个作用范围内,变量一般不能重名

2)如果全局变量和局部变量同名,在局部范围内,局部量说了算。出了局部范围,局部变量不存在,同名的全局变量说了算

4、修饰变量的数据类型

数据类似主要说明:

1)变量定义的时候开辟内存空间开辟多大

2)变量所存放的数据,限制数据的范围

3)解析数据的时候,按照什么样的格式进行解析

eg:

unsigned char: 占1个字节 0-255 0-2^8-1

unsigned char a = 256;

unsigned int: 占4个字节 0-2^32-1

unsigned short: 占两个字节 0-2^16-1

5、常见数据类型定义变量举例

1、char 用来修饰字符变量

char 字符型 ,用 char 定义的变量是字符型变量,占 1 个字节

char ch='a'; =为赋值号

char ch1= ‘1’; 正确

char ch2 = ‘1234’ ; 错误的

2、short 短整型 ,使用 short 定义的变量是短整型变量,占 2 个字节

short int a=11; -32768 - ---32767

3、 int 整型 ,用 int 定义的变量是整型变量,在 32 位系统下占 4 个字节,在 16 平台下占 2 个字节

int a=44; -20 亿---20 亿

4、 long 长整型 用 long 定义的变量是长整型的,在 32 位系统下占 4 个字节

long int a=66;

5、 float 单浮点型 (实数),用 float 定义的变量是单浮点型的实数,占 4 个字节

float b=3.8f;

6、 double 双浮点型 (实数),用 double 定义的变量是双浮点型的实数,占 8 个字节

double b=3.8;

7、signed 有符号(正负)的意思

在定义 char 、整型(short 、int、long) 数据的时候用 signed 修饰,代表咱们定义的数据是有符号的,可以

保存正数,也可以保存负数

例 :signed int a=10;

signed int b=-6;

注意:默认情况下 signed 可以省略 即 int a=-10;//默认 a 就是有符号类型的数据

8、unsigned 无符号的意思

在定义 char 、整型(short 、int、long) 数据的时候用 unsigned 修饰,代表咱们定义的数据是无符号类型的

数据只能保存正数和 0。

unsigned int a=101;

unsigned int a=-101; //错误

9、void 空类型的关键字

char、int 、float 都可以定义变量

void 不能定义变量,没有 void 类型的变量

void 是用来修饰函数的参数或者返回值,代表函数没有参数或没有返回值

例:

void fun(void)

{

}

10、typedef 重命名相关的关键字

关键字 ,作用是给一个已有的类型,重新起个类型名,并没有创造一个新的类型

用法:

typedef 原有数据类型 数据类型别名;

拓展:

批量定义变量:

数据类型 变量名1,变量名2;

数据类型 变量名1=变量值,变量名2=变量值;

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

int  main(int arg,char * argv[])
{
    float   a= 3.3, b=4.4;
    printf("%.2f  %.2f\n",a,b);
    return 0;
}

10、强制类型转换

一个变量可能是一种数据类型的,现在我需要按照其它的数据类型来进行解析这片内存。

表现形式:

(强转的数据类型)变量的名



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

int  main(int arg,char * argv[])
{
    int    a = 0x12345678;
    printf("%d\n",(unsigned  char)a);
    return 0;
}

11、隐式类型转换

1、什么是隐式类型转换

在进行一些算数混合运算的时候,操作数是不同数据类型的时候,数据类型会发生自动转换的问题。这种就叫做隐式类型转换

2、转换的原则

字节内存小的向字节内存大的去转,数据范围小的向数据范围大的转,单精度的向双精度转

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

int  main(int arg,char * argv[])
{
    int   a = 5;
    int   b = 2;
    float  c =a/b;   //数据类型相同,/表示整除
    printf("%.2f\n",c);
    float d = 2.0;
    c = a/d;    //2.5
    printf("%.2f\n",c);


    return 0;
}

12、运算符

1、运算符分类

根据操作数的数量(这的操作数指操作的变量),分为单目运算、双目运算、三目运算

2、算数运算符

+ - * / % += -= *= /= %=

% 取余数

/ 如果操作数中没有小数的话一般是整除

+= 注意符号与符号中间没有空格 eg: a += b; a=a+b;

3、关系运算符

(>、<、= =、>=、、!= )

!=为不等于

一般用于判断条件是否满足或者循环语句

a大于100 小300

数学里面: 300> a>100(程序中不能这样写)

程序里面:a>100 && a

4、逻辑运算符

逻辑判断中,真是非0值,假是0值

1、&& 逻辑与

两个条件都为真,则结果为真,两个条件中有一个条件为假,结果即为假。

if((a>b) && (a

if(b这种表达方式是错误的

注:短择情况

if(表达式1 && 表达式2)

{

}

如果表达式1为假了,表达式2就不会判断执行

eg:

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

int main(int arg,char * argv[]) 
{ 
    int a = 1; 
    int b = 1; 
  if((--a) && (b++)) 
    { 
        printf("ddddddddd\n");
    } 
        printf("%d\n",b);

     return 0; 
}
2、|| 逻辑或

两个条件至少有一个为真,则结果为真,两个都为假的话,结果为假。

if((a>b) || (a

短则:

如果第一个表达式为真,后面的表达式就不会执行

3、! 逻辑非

对表达式的结果取反

if(!(a>b))

{

}

5、位运算符

1、& 按位与

      操作数1   &   操作数2,将操作数转换成二进制位,进行按位与

2、 |   按位或

 操作数1   |   操作数2,将操作数转换成二进制位,进行按位或

3、~ 按位取反

对每一位进行取反。

4、^异或

     题目:   两个变量进行交换,不引入第三个变量。

int    a = 0x12,b=0x13;

int   temp  = a;

a = b;

b = temp;

异或方式:

      a = a^b;   //0b 0001  0010  ^  0b0001   0011-------0000  0001

      b = a^b;  //0000  0001  ^    0b0001   0011 ------>0001 0010

      a = a^b; //0000  0001  ^  0001 0010 -------0001  0011

5、左移

6、>>右移

>>右移分为算术右移和逻辑右移

对逻辑右移:不管是正数还是负数都是左边补0,右边移出去的丢弃掉

对于算数右移:左边移动的位补符号位,右边移出去的丢失掉

(算术右移、逻辑右移 都是编译器决定,用户无法确定。 无符号数:右边丢弃 左边补0 有符号数: 正数:右边丢弃 左边补0负数:右边丢弃 左边补0(逻辑右移) 负数:右边丢弃 左边补1(算术右移))

证明:Linux中gcc使用的是算数右移

#include

#include

#include

int  main(int arg,char * argv[])

{

    char   a = 0b10101011;

    //1)注意赋值符号不管原码反码和补码,只管存储数据,等号的右边数据是什么,他就存储什么

    //2)定义一个变量的时候如果没有说明这个变量是无符号的,那么这个变量就是有符号的

    //对于该题,内存中存储的是:10101011---->说明它是补码----》10101010(反码)----》01010101--->1+4+16+64=85--->-85

    printf("%d\n",a>>1);  //-43   0010 1011---->1101 0100-->1101  0101    

    return 0;

}

执行结果:

edu@edu:/mnt/hgfs/Share/2401/C_Basic/cal_character$ ./a.out

-43

7、综合应用

  1、对某一个数中的某些bit位进行清零

       char      a = 0xff;   //bit2进行清零     0b1111   1111   

       a  &=  ~(10b1111  1011

  练习:

      a=0x99  的bit3清零       a &= ~(1       a=0xf4   的bit5清零      a &=~(1       a = 0x11的bit4和bit0清零    a &= ~((1       a= 0xffff   对bit13  和bit10进行清零   a &= ~((1       a=0xf56f  对bit12和bit3及bit2进行清零   a &= ~((1总结: a&= ~( 1

2、对某一个数中的某些bit位进行置1

总结:如果是对一个数(变量)的某些位进行置1,只需要这个数(变量)1=1a |=   1

6、三目运算符

表达式1?表达式2:表达式3

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

int  main(int arg,char * argv[])
{
   int   a = 10;
   int   b = 5;
   int   c = 0;
   scanf("%d%d",&a,&b);

   c = (a>b)?(a):(b);
   printf("%d\n",c);
    return 0;
}

7、逗号表达式

(表达式1,表达式2) 逗号运算中一般整体表达式的结果取最后一个表达式的结果

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

int  main(int arg,char * argv[])
{
    int  a = 1;
    int  b = 2;
    int   c = (a++,++b);
    printf("%d %d %d\n",a,b,c);
    return 0;
}

8、算数运算优先级

注意所有运算符号都是有优先级的,这就要求我们写代码的时候需要注意,一般解决方法不是靠记忆,靠的的是加括号,你想要什么先运算就把它们先括起来。

  • 23
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值