《C Primer Plus》学习笔记

第二章:C语言概述
在这里插入图片描述
第三章:数据和C
在这里插入图片描述

enum关键字
枚举型是预处理指令#define的替代,枚举和宏其实非常类似,宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。
枚举成员的是常量,所以不能对它们赋值,只能将它们的值赋给其他的变量。
第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。在当前值没有赋值的情况下,枚举类型的当前值总是前一个值+1.
在这里插入图片描述

  1. 枚举列表中的 Mon、Tues、Wed 这些标识符的作用范围是全局的(严格来说是 main() 函数内部),不能再定义与它们名字相同的变量。
  2. Mon、Tues、Wed 等都是常量,不能对它们赋值,只能将它们的值赋给其他的变量。

goto 关键字
goto XXX:可以跳出多重循环,会跳过一段代码,不执行,直接执行“XXX:”后面的代码。

register关键字
修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其存储速度。
在这里插入图片描述

typedef关键字
为一个数据类型起一个新的别名。
在这里插入图片描述
volatile关键字
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。(简洁的说就是:volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错)

第四章:字符串和格式化输入/输出
在这里插入图片描述

第五章:运算符、表达式和语句
在这里插入图片描述

++ – 运算
在这里插入图片描述

多个++和–运算会产生不同结果
在这里插入图片描述
运算符优先级
在这里插入图片描述

第六章:循环

while(); 此格式只执行while()
while()
a=1;
此格式只执行a=1;

for(; test ; )
等价于
while(test)

逗号运算符
逗号是一个序列点,逗号左侧项的所有副作用都在程序执行逗号右侧之前发生。
a=249,500;
等价于
a=249;
500;

b=(249,500);
等价于
b=500;

数组
int debts[20]
scanf(“%d”, debts);
scanf(“%d”, &debts[5]);
int a=1;
scanf(“%d”, &a);
char类型数组如果末尾包含\0,则内容为字符串;否则为字符。

第七章:分支与循环

char ch;
ch=getchar();
等价:scanf(“%c”,&ch);
putchar(ch);
printf(“%c”,ch);
scanf() 输入非数字字符时返回值为0。

ctype.h头文件专门处理字符
在这里插入图片描述

if-else配对:不能依赖缩进来判断。
如果没有{},else与最近if配对;有{},else与if按照{}配对。
在这里插入图片描述
此时,无{},else与第二个if配对。
在这里插入图片描述
此时,有{},else与第一个if配对。

&& || !
在这里插入图片描述
C保证逻辑表达式的求值是从左到右,且前一个逻辑表达式为假,就不再对后面的表达式进行判断。
在这里插入图片描述
image.png
!a 等价于 a==false
continue 在循环中,结束下面的语句,判断条件重新进行语句;
break 在循环中,结束本次循环。
所有的循环和switch都可以使用break;
continue只能在循环中使用,不能在switch。
在这里插入图片描述

第八章:字符输入/输出和输入验证

第九章:函数
在这里插入图片描述

实参:常量,变量,表达式;任何形式都要求值,传递给形参。
scanf()返回成功读入的数据个数,如果为非字符,则返回-1。
return: 1. 返回值给主函数;2.终止子函数运行,return后面的语句不执行。
在这里插入图片描述

递归:函数自己调用自己,难点是如何结束递归,一般使用if判断。
最简单的递归为尾递归,即正好在return之前,相当于循环。
递归优点:为某些编程问题提供简单方案;缺点:某些递归会快速消耗计算机的内存资源。
在这里插入图片描述

头文件使用:将多个函数申明放在头文件中进行调用。
&运算符求变量的地址
%p是输出地址的转换说明
return只能将函数中的一个值进行返回,若返回多个,需用指针。
在这里插入图片描述图1
在这里插入图片描述图2

图1是值传递,调用函数处理的值与主函数无关;图2是地址传递,此时实参与形参是同一个地址,值同时改变。

参数传递两种方式–传值&传址
传值方式:将实参的值拷贝给函数或方法,在函数内对形参进行操作,操作的对象是实参的拷贝,对实参本身没有影响,在函数结束返回后,形参被丢弃释放,实参的内容不会被改变。
传址方式:将实参的地址传递给函数,在函数内对形参进行操作等同于对实参进行相同的操作,在函数调用结束返回后,形参被释放,实参的内容是对形参进行操作后的结果。

传址又分为:引用传递&指针传递。
在这里插入图片描述

第七章:分支与循环
char ch;
ch=getchar();
等价:scanf(“%c”,&ch);
putchar(ch);
printf(“%c”,ch);
scanf() 输入非数字字符时返回值为0。
scnaf()返回的是输入的数字个数。
ctype.h头文件专门处理字符

image.png

if-else配对:不能依赖缩进来判断。
如果没有{},else与最近if配对;有{},else与if按照{}配对。
在这里插入图片描述
此时,无{},else与第二个if配对。
在这里插入图片描述
此时,有{},else与第一个if配对。

&& || !
在这里插入图片描述
C保证逻辑表达式的求值是从左到右,且前一个逻辑表达式为假,就不再对后面的表达式进行判断。
在这里插入图片描述
在这里插入图片描述

!a 等价于 a==false
continue 在循环中,结束下面的语句,判断条件重新进行语句;
break 在循环中,结束本次循环。
所有的循环和switch都可以使用break;
continue只能在循环中使用,不能在switch。
在这里插入图片描述
第八章:字符输入/输出和输入验证

char ch;
ch=getchar();
putchar(ch);

判断文件结尾:

  1. 文件结尾有特殊字符;
  2. 根据文件大小;
    getchar()和scanf()读取文件检测到文件结尾时会返回一个特殊值:EOF
    #define EOF -1;
    重定向输入: ./echo_eof < words
    重定向输出: ./echo_eof > words

第九章:函数
实参:常量,变量,表达式;任何形式都要求值,传递给形参。
scanf()返回成功读入的数据个数,如果为非字符,则返回-1。
return: 1. 返回值给主函数;2.终止子函数运行,return后面的语句不执行。
image.png
递归:函数自己调用自己,难点是如何结束递归,一般使用if判断。
最简单的递归为尾递归,即正好在return之前,相当于循环。
递归优点:为某些编程问题提供简单方案;缺点:某些递归会快速消耗计算机的内存资源。
在这里插入图片描述

头文件使用:将多个函数申明放在头文件中进行调用。
&运算符求变量的地址
%p是输出地址的转换说明
return只能将函数中的一个值进行返回,若返回多个,需用指针。
在这里插入图片描述
图1
在这里插入图片描述
图2

图1是值传递,调用函数处理的值与主函数无关;图2是地址传递,此时实参与形参是同一个地址,值同时改变。
参数传递两种方式–传值&传址
传值方式:将实参的值拷贝给函数或方法,在函数内对形参进行操作,操作的对象是实参的拷贝,对实参本身没有影响,在函数结束返回后,形参被丢弃释放,实参的内容不会被改变。
传址方式:将实参的地址传递给函数,在函数内对形参进行操作等同于对实参进行相同的操作,在函数调用结束返回后,形参被释放,实参的内容是对形参进行操作后的结果。
传址又分为:引用传递&指针传递。
在这里插入图片描述

第十章:数组和指针
在这里插入图片描述
指定数组的大小:[]中为整型常量表达式,其值必须大于0,sizeof被视为整型常量,const值不是。
int n=5;
float a[n];//C99之前不允许,C99允许,为变长数组,变指的是用变量定义数组的维度。
初始化数组:
C99增加了指定初始化器,可以初始化指定的数组元素。
int arr[6]={[5] = 1};即arr[5]=1,其余元素为0。
const修饰数组,只读,不能改变元素的值。

二维数组初始化:
在这里插入图片描述
二维数组与指针的关系:
int zippo[5][12];
数组名为zippo,有5个元素(一维数组),每个元素都是内含12个int的一维数组。
在这里插入图片描述
公式:
zippo[m][n]((zippo+m)+n)
**zippo
*&zippo[0][0]

指向多维数组的指针
在这里插入图片描述
数组名为数组首元素的地址: a=&a[0]
一维数组与指针的关系:
data+2==&data[2];//相同地址
*(data+2)==data[2]//相同的值
注意:
*(data+2)为data第三个元素值
*data+2为data第一个元素加1
data++与++data区别
*data++为指针data当前位置的值;
*++data为指针data偏移一个地址的值。

千万不要引用未初始化的指针:
int * pt;//未初始化的指针
pt=5//错误
未初始化时,存储该指针的地址&pt是随机的, 就是说,该指针可能指向任意地方,包括系统使用的内存区。当
pt = 5时,就有可能造成无法预料的结果。
在定义指针的时候直接初始化,语句如下int *pt = 5;

复合字面量(C99):除符号常量外的常量,必须在创建的同时使用。
例如:5是int类型字面量,'Y’是char类型的字面量。
int a[2]={0, 1};的复合字面量:去掉数组名,还可以省略数组大小
(int [2]) {0, 1}
(int []) {0, 1}
image.png

第十一章:字符串与字符串函数
在这里插入图片描述

字符串是以空字符(\0)结尾的char类型的数组.
一、字符串输入函数
1.gets()
使用地址作为参数,它从系统的标准输入设备(通常是键盘)获得一个字符串,直到遇到一个换行符(\n)结束,并自动添加空字符(\0)。
例:
char name[81]; /分配空间/
printf(“Hi ,what is your name?”);
gets(name);
printf(“%s\n”,name);
返回值:如果读入正常,则返回的是读入字符串的地址(即一个指向char型的指针),如果出错或gets()遇到文件结尾,则返回一个空(或0)地址。这个空地址被称为空指针,并用stdio.h里定义的常量NULL来表示。
因此gets()中还加入了一些错误检测,这是它可以很方便的以如下形式使用:
while(gets(name) != NULL)
这样的指令使您既可以检查是否到了文件结尾,有可以读取一个值。如果遇到了文件结尾,name中什么也不会读入。

2.fgets()
gets()的一个不足时它不检查预留存储区是否能够容纳时间输入的数据。多出来的字符简单的演绎出到相邻的内存区。
fgets()函数改进了这个问题,它让您指定最大读入字符数。
fgets()和gets()有三个方面不同:
(1)需要第二个参数来说明最大读入字符数。如果这个参数值为n,fgets()就会读取最多n-1个字符或者读完一个换行符为止,有这两者中最先满足的那个来结束输入。
(2)如果fgets()读到换行符,就会把它存到字符串里,而不是像gets()那样丢弃它。
(3)它还需要第三个参数来说明读哪一个文件。从键盘上读数据时,可以使用stdin作为该参数,这个标识符在stdio.h中定义。
例:
char name[81];
char *ptr;
ptr = fgets(name,81,stdin);
printf(“%s”,ptr);

3.scanf()函数
scanf()函数使用%s格式读入一个字符串。scanf()使用两种方法决定输入结束。无论那种方法,字符串都是以遇到的第一个非空白字符开始。如果使用%s格式,字符串读到(但不包含)下一个空白字符(空格,制表符或换行符)。如果指定了字段宽度,比如%10s,scanf()会读入10个字符或知道遇到第一个空白字符,由二者中最先满足的哪一个终止输入。
scanf()函数返回一个整数值,这个值是成功读取的项目数;或者当遇到文件结束时返回EOF。

二、字符串的输出:puts(),fputs(),printf()
1.puts()函数
puts()函数使用很简单,只需要给出字符串参数的地址。
例:
char *name = “hellow wold”;
puts(name);
puts()函数显示字符串时自动添加一个换行符。puts()输出时遇到空字符(\0)停止,所以应确保输出的字符串中有空字符。

2.fputs()函数
fputs()函数是gets()的面向文件版本。两者之间的主要区别:
fputs()需要两个参数来说明要写的文件。可以使用stdout作为参数来进行那个输出显示,stdout在stdio.h中定义,与puts()不同,fputs()并不为输出自动添加换行符。

三、字符串函数

1.strlen函数:strlen函数返回的是在字符串中’\0’前面出现的字符的个数。
2.strcpy函数
image.png
3.strcat函数
在这里插入图片描述
4.strcmp函数
在这里插入图片描述
字符串转数字
atoi:把字符串nptr转换为int。
atol:把字符串nptr转换为long int。

第十二章 存储类别、链接与内存管理
在这里插入图片描述
一、 储存类别
1、作用域
(1)、块作用域: 块是花括号内的代码,块作用域变量的可见范围是从定义处到包含该定义的块的结尾。
(2)、函数作用域: 仅用于goto语句的标签。
(3)、 函数原型作用域: 用于函数原型中的型参名。
(4)、 文件作用域: 变量定义在函数的外面,具有文件作用域。
2、链接
(1)、外部链接
文件作用域可以是外部链接或内部链接。
静态外部链接:所有函数外且没有使用static
(2)、内部链接
只能在一个翻译单元中使用。
静态内部链接:所有函数外且使用关键字static。
(3)、无链接
块作用域、函数作用域、函数原型作用域。
静态无链接:块内,使用关键字static
3、 储存期
(1)、静态储存期
static声明,程序执行期间声明变量的值一直存在。
(2)线程储存期
用于并发程序设计,程序执行可被分为多个线程。
(3)、自动储存期
块作用域有自动储存期,程序运行块时,为这些变量分配内存;退出块时,释放变量分配的内存。 动态分配储存期

静态存储期:在程序开始执行时分配内存,并在程序运行时都存在。
自动存储期:在程序进入变量定义所在块时分配变量的内存,在程序离开时释放内存。
动态存储期:malloc(), free()
4、变量
(1)、自动变量:auto或没有说明
(2)、寄存器变量:register声明,请求寄存器变量储存在CPU寄存器中,寄存器可以忽略
(3)、外部链接的静态变量:extern+函数名,将在其他文件定义的函数导入
(4)、外部变量:变量定义在main函数外,有全局性,任何函数可以调用此变量,变量在运行中一直存在
(5)、内部链接的静态变量:main函数外用static声明的变量,只能用于同一文件中。
5、 多文件处理
使用extern
使用#include"文件名.h"初始化引入程序中。
二、内存分配
1、malloc()
malloc函数是一种分配长度为num_bytes字节的内存块的函数,可以向系统申请分配指定size个字节的内存空间。
void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。
使用前要申明:#include <stdlib.h>或者#include <malloc.h>
调用free()释放内存。

       示例:
       double *ptd; ptd=(double *)malloc(30 *sizzeof(double));
       分配了30个double类型值的储存空间,malloc返回的是char类型的指针,要强制转换。如果分配内存失败则返回空指针。
       不会清理分配到的内存空间,不会为输入的值赋名,要用指针访问。

在这里插入图片描述
2、 free()
示例:free(ptd);
释放malloc分配的内存,使内存可以重复使用,一定要有。
没有free则此内存无法被释放,动态分配内存只会增加。
3、calloc()
示例:ptd=(double *)calloc(30 ,sizzeof(double));
calloc与malloc几乎一样,但它在分配内存时会清理内存。
三、限定符
1、const
(1)、const float *pf; 或 float const *pf
指向float类型的const的值,pf可以改变,但pf指向不能被改变的值。
(2)、float * const pf;
pf指向的地址不变,地址中的值可以改变。
(3)、const float * const ptr;
ptr指向的地址不变,地址中的值也不可改变。
(4)、对全局数据使用
const int A=2;定义常量。
2、volatile
volatile int loc;loc是个易变的位置。
用于由硬件地址以及在其他程序或同时运行的线程共享数据。
使用 volatile可以优化程序,编译器会假定变量进行优化。
3、 restrict
double * restrict ptd=(double *)malloc(30 *sizzeof(double));
允许编译器优化某部分代码已更好的计算。只能用于指针。

第十三章:文件的输入与输出
在这里插入图片描述
fopen()函数
1、FILE *fp;fp=fopen(“文件名”,“模式字符串")
2、模式字符串
“r”:以读模式打开文件。
“w”:以写模式打开,删除文件中的内容,如果文件不存在,则创建一个新文件。
“a”:以写模式打开文件,在现有文件末尾添加内容,如果文件不存在,则创建一个新文件。
“r+”:以更新文件模式打开,可以读写,文件必须存在。
“w+”:以更新模式打开,可以读写,文件存在,将内容删除,如果文件不存在,则创建一个新文件。
“a+”:以更新模式打开,可以读写,只能在文件末尾添加内容,如果文件不存在,则创建一个新文件。
“rb”、“wb”、“ab”、“rb+”、“r+b”、“wb+”、“w+b”、“ab+”、“a+b”,与上一个模式类似,但是是以二进制模式打开文件
3. 常用文件打开方式:
if((fp=fopen(“file1”,“r”))==NULL)
{
printf(“cannot open this file\n”);
exit(0);
}

getc()和putc()函数
1、ch=get(fp):从fp文件中获得一个字符。
2、putc(ch,fp):把字符放入fp指定文件中。
3、putc(ch,stdout):与putchar(ch)作用相同。

fclose()函数
fclose(fp)是关闭文件。
fclose函数也带回一个值,当成功的执行了关闭操作,则返回为0,否则返回EOF(-1)。

文件I/O
1、fprintf()
fprintf(fp,“%s”,a):把a的值写入fp文件指向的位置中。
2、scanf()
scanf(fp,“%s”,a):把文件fp指向的位置的值赋给a。
3、gets()
(1)、一般输入fgets(xx,n,stdin):输入不丢弃/n,输入n-1个字符串,还有一个储存/n。
(2)、从文件中读入fgets(xx,n,fp):fp为文件指针,将fp写入xx指向的文件中的数据,以空格和回车分割。

4、fputs()
(1)、文件中写入fputs(xx,fp):将xx写入fp指向的文件中
(2)、一般输出fputs(xx,stdout):输出xx带/n

5、rewind()
rewind(fp):返回fp指向文件的开头。

随机访问:fseek()和ftell()
1、fseek(fp,0L,SEEK_SET)
将指针fpd定位在离文件开头0字节处,SEEK_CUP为当前位置,SEEK_END为文件末尾。0L是字节偏移量,为long类型值。
2、ftell(fp)
返回文件当前位置到文件开始的字节数,返回值是long类型。

二进制文件I/O:fread()和fwrite()
1、fwrite(&a,n,1,fp)//将地址a中n个内容上传1次到fp指向的文件中。
2、fread(&a,sizeof(doouble),10,fp)// 从文件中调用10个double的值拷贝进a数组中。

第十四章:结构和其他数据形式
在这里插入图片描述

一、结构体定义
1、可声明在函数外。
2、声明:
struct book
{
char title[10];
char author[10];
float money;
};
3、book结构体由两个字符串数组和一个float类型变量组成的结构
4、定义结构体:struct book a { };或struct (book) { }a;
5、结构体与结构体中可以层层嵌套:struct book{struct title{ };};
在这里插入图片描述

二、结构体使用
1、初始化:struct book a{“name”,“no”,11};或a.title=“xxx”;
2、a中有三个类型为a.title、a.author、a.money。a加点结构名进行赋值、访问和输出。
3、可以用a=b;把一个结构体赋给另一个结构体。数组不可以。
4、结构数组: struct book a[n];

三、结构数组
1、struct book a[10];a中有10个都有book的结构,以a[0].title访问
2、a[2].title[4]:数组a[2]元素的title成员的一个字符(第五个)。
3、可以以a[0].title的形式访问。

四、指向结构的指针
1、声明: struct book *pt; struct book a; pt=&a (a是结构变量名)
struct book *pt; struct book a[n]; pt=&a[0] (a[n]是结构变量名)

2、告诉编译器pt指针指向a结构。
3、pt->title;或pt=&title;pt指向title地址。
4、a.title==(*pt).titlept->title(pt=&title)
5、若a结构为a[2]数组,则pt指向a[0],pt+1指向a[1]。

五、结构与结构指针的选择
1、struct book {char title[20];char author[20];};
2、struct book {char *title;char *author;};
3、第一个声明要分配40个字节,而第二个分配16个字节。指针可以代替数组。

六、伸缩型数组成员
1、struct book
{
char title[10];
char author[];//伸缩型数组成员
};
2、成员规则
(1)、伸缩型数组成员必须是最后一个成员;
(2)、结构中必须至少有一个成员;
(3)、数组方括号中是空的。
3、分配空间用:malloc(),free()
4、伸缩数组成员要求
(1)、不能用结构拷贝或赋值
(2)、不要以值的方式把这种结构传递给结构,要把结构地址传递给函数
(3)、不要用带伸缩型数组成员的结构做为数组成员或另一个结构的成员

七、把结构体保存到文件中
1、pbook是标识一个文件流
2、fprintf(pbook,“%s %s %.2f\n”,a.book,a.author,a.money);//需要知道每个字段结束的位置,用%ns进行限制。
3、fwrite(&a,sizeof(struct book),1,pbook); fread(&a,sizeof(doouble),10,pbook)
4、rewind()函数确保文件指针处于开始处。
5、fwrite()和fread()函数使用二进制文件。

八、链式结构
1、创建新的数据形式。
2、队列、二叉树、堆、哈希表和图表,都是由链式结构组成的。

九、联合类型
1、联合(union)是一种数据类型,它能在同一个内存空间储存不同的数据类型
2、声明:
union hold
{
int digit;
double bigfl;
char letter;
};
3、union hold fit; hold 类型的联合变量。
4、声明联合只能存储一个int或一个double或char类型的值。
5、编译器在分配内存时,分配的是占用最大字节的类型。
6、fit.digit=23; 联合中,一次只存储一个值。
7、联合中还可以嵌套结构体 union data{struct hold fit; struct ···; };
8、初始化联合体:初始化联合的第一个元素;把一个联合初始化为另一个同类型的联合;使用指定初始化器。

十、枚举类型

1、枚举类型来说表示整型常量(int)。
2、声明:enum spectrum {red, orange, yellow, green, blue, violet}; enum spectrum color;
用枚举这些颜色时,从技术层面看它们是int类型的常量,如red为0、orange为1等。
color的值可能为red,orange等。如果color要为red,则color=0,即枚举列表中的第一个常量默认为0,依次加1;
3、若enum spectrum {red, orange=10, yellow, green}; 则red=0;yellow=11,green=12。

十一、typedef
1、typedef并没有创建任何新的类型,它只是为某个已存在的类型增加了一个方便只使用的标签。
2、typedef定义的作用域取决于定义的位置。在函数中,有局部作用域;在函数外,有文件作用域。
3、与#define三处不同
(1)、与#define不同,typedef创建的符号名只受限于类型,不能用于值
(2)、在受限范围内,typedef比#define更灵活。
(3)、typedef由编译器解释,不是预处理器。
4、使用
(1)、typedef char * STRING;
STRING name, sgin; 相当于:char * name, * sgin;
(2)、typedef struct complx { float real; int imag; }COMPLEX;
COMPLEX a={3.0,4 }; 则a为complex类型的结构。

十二、其他类型声明
1、int ** ptr; 声明一个指向指针的指针,被指向的指针指向int类型
2、int * risks[10]; 声明一个内含10个元素的数组,每个元素都是指向一个int类型的值。
3、int (* risks) [10]; 声明一个指向数组的指针,该数组内含10个int类型的值。
4、int (* uuf) [3] [4]; 声明一个指向3X4二维数组的指针,该数组内含int类型值。
5、int (* uof [3]) [4]; 声明一个内含3个指针元素的数组,其中每个每个指针都指向一个内含4个int类型元素的数组。
6、( )和[ ]的优先级相同,但比*的优先级高。

第十五章:位操作

image.png

一、二进制整数
C语言用字节表示存储系统字符集所需的大小,通常1字节为8位。
可以从左往右给这8位分别编号 7~0。在一字节中,编号是7的位被称为高阶位,编号为0的被称为低阶位,每一位的编号对应2的相应指数。
在这里插入图片描述
该字节能表示的最大的数字是把所有位设置为1:1111 1111,其值为255。最小值就是:0000 0000,其值为0。
所以1字节可以存储0~255范围内的数字总共256个值,在ASCII码中对应了256个状态。
unsigned char用1字节表示的范围是0~255,而signed char 用1字节表示范围是-128 ~ 127。

二、有符号整数
二进制原码的最高位是符号位(正数为0,负数为1),后面的位是整数的绝对值的二进制表示。
正数的二进制反码和原码一样。负数的二进制反码是原码的符号位不变,其余位按位取反(1变0,0变1)。
正数的补码和原码、反码一样。负数的二进制补码是反码+1,计算机通常使用二进制补码存储整数。

三、八进制,十六进制
八进制基于8的幂,用0-7表示数字。每个八进制位对应三个二进制位。
十六进制基于16的幂,用0-15表示数字,10-15分别用A-F表示(C语言中也可以用小写)。每个十六进制位对应四个二进制位。十六进制适合表示字节值。

四、位运算
~是按位取反,把1变为0,0变为1。该运算符不改变原变量的值。
&是按位与,当两个相应的位都为1时才为1,否则为0。
|是按位或,如果两个相应的位有一个是1,结果就是1。只有都是0时结果才是0。
^是按位异或,如果相应的位有一个是1,有一个是0,结果就是1。如果都为1或都为0,结果为0。

五、移位运算符

<<将左侧运算对象每一位向左移动右侧运算对象指定的位数。移出左端的位的值丢失,用0填充右端位置。左移不改变原变量的值。>>将左侧运算对象每一位向右移动右侧运算对象指定的位数。移出右端的位的值丢失,对于无符号整数,用0填充左端位置。有符号整数的效果取决于机器,可能用0填充,也可能用符号位填充。右移不改变原变量的值。

第十六章:C语言预处理和C库
在这里插入图片描述
一、#define
1、#define TWO 2,把TWO的值初始化为数字2。
2、#define STR “hello world!”,str替换hello world!
3、#define PX printf(“x=%d”,x),PX替换此内容;输出为:x=x的值。
4、#define FOUR 22,FOUR为4。
5、#define FOUR 2 * 2,FOUR 被解释为字符串。
6、#define SQUARE(X) X
X,SQUARE(2)=4; SQUARE(2+3)=2+32+3=11;
7、#define SQUARE(X) (X)
(X),SQUARE(2+3)=(2+3)(2+3)=25 X只仅仅为替换,100/SQUARE(2+3)=100/(2+3)(2+3)=100

二、#运算符
1、#define PSQR(x) printf(“square “#x” is %d”, (x)*(x)), #x转换为字符串"x"的形参名。
PSQR(2+4)为:square 2+4 is 36
2、#define STR(n) x ## n,int x1=2; printf(“x1=%d”,STR(1));输出为:x1=2。
##运算符把两个记号组成为一个记号(xn)。
3、变参宏:…和_ VA_ARGS _,#define PR(x, …) printf(“”#x":" _ VA_ARGS )
x=1; PR(1, “x=%d”, x);输出为 1 : x=1
把函数列表最后的参数写成省略号,预定义宏
VA_ARGS _可在替换部分,表明省略号代表什么。

三、其他指令
1、#undef MAS,取消已定义的MAS,变成未定义的。
2、条件编译:#ifdef、#else、#endif
#ifdef MAS
#include<stdio.h>
#else
#include<string.h>
#endif
//如果定义了MAS则引入stdio.h,否则引入string.h
3、#ifndef … ,与#ifdef逻辑相反,为如果没定义 …就…
4、#if 、#elif
#if t0
#include<stdio.h>
#elif t
1
#include<string.h>
#else
#include<stdlib.h>
#end if
//与if,else if,else;用法相似。
5、#line和#error
#line指令重置_ LINE FILE _宏报告的行号和文件名。
#line 100 //把行号重置为100
#line 10 “cool.h” //把行号重置为10,文件名重置为cool.h。
6、#pragma,把编译指令放入源代码中。

四、函数
1、内联函数
把函数变成内联函数意味着尽可能快的调用函数,其具体效果由定义实现。
内联函数的定义和调用必须在同一个文件中,有static说明符。
inline static void eatline(…) { }
2、exit( )和atexit( )函数
(1)、atexit( )
使用atexit( )函数,只要把要退出时的函数地址(即函数名)传递给atexit即可。
退出程序时才会返回到执行该函数。
(2)、exit( )
终止程序。
exit(EXIT_FAILURE)表示终止失败,或exit(1)不为0就是失败;exit(EXIT_SUCCESS)表示成功终止,或exit(0).
3、qsort( )函数
qsort 为排序函数。
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
第一个参数为指针,指向待排序数组的首元素。第二个参数是待排序项的数量,第三个参数是sizeof(类型),最后一个为函数指针,这个指针指向的比较函数用于确定排序的顺序(第1项值大于第2项,返回正数;相等则返回0;小于则返回负数)。
4、memcpy( )和memove( )
memcpy()和memmove()都是c语言的库函数(头文件保护#include <string.h>),作用是拷贝一定长度内存的内容。
它们唯一的区别是当内存发生局部重叠时,memmove可以保证拷贝正确,memcpy拷贝的结果是未定义的(取决于编译平台内部对memcpy的优化处理)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值