【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)

第一章 C语言概述

1.1

软件:计算机所使用的各种程序的集合及运行时所需的数据。
面向过程:程序设计是数据被加工的过程
面向对象:对象是类的实例,是数据和方法的封装,对象间通过发送和接受消息发生联系。

1.2 C语言的特点:

(1)语言简洁、紧凑、灵活
(2)运算符和数据类型丰富
(3)程序设计结构化、模块化
(4)允许直接访问物理地址
(5)生成目标代码质量高
(6)可移植性好

1.3基本语法单位:

(重点)类别:关键字、标识符、运算符、常量和分隔符、注释符。

1、字符集

(1)字母和数字;
(2)不可打印的字符:空格符、回车符、换行符、控制符;
(3)空字符:ASCII为0的NULL,常表示为‘\0’;
(4)标点和特殊字符。
【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第1张图片

2、标识符

合法标识符要求:
(1)只可含有’__'这个字符
(2)数字不可作为开头
(3)标识符不可是关键字或含有其他符号。
例题:

1.7 以下哪些标识符是合法的?

int_do,dO,DWMax_Value,TWO_AND_THREE,int,32data,one_$
答:合法的标识符有: int_do,dO,DWMax_Value,TWO_AND_THREE。
原因:int 为C 语言关键字;32data 是由数字开头;one_$ 含有’$’,不合法。

3、关键字

在c语言中,已预先定义具有特定含义的标识符,关键字称为保留字。
【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第2张图片

4、运算符和分隔符

注意:(1)“%”可作为取余的运算符,也可以作为输入输出的格式控制符;
(2)“,”可以作为逗号运算符,也可以作为分隔符。
(3)"*"可表示单目运算取值,也可以是双目的乘法运算。
这些有双重含义的运算符,称为运算符的重载或超载。
(4)分隔符主要指:空格、制表和换行符。

1.4 小结

编辑(.c文件)->编译(.obj)->链接(*.exe)

ASCII码表:

数据类型概要:
【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第3张图片

第二章 基本数据类型及运算

2.1基本数据类型

数据:程序处理的基本对象。
将数据和对数据的操作抽象为数据类型。

数据类型决定:(1)数据占内存字节数(2)数据取值范围(3)允许的操作
扩展:c++中的类就是这样的理。

2.2常量:数值常量和字符型常量

注:都在数据存储区,且按出现的顺序依次存放,并且重复常量只存放一次。
数值常量:整型常量和浮点数常量
字符型常量:字符常量、字符串常量、转义字符和符号常量。

2.2.1 常量

【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第4张图片

2.2.2

构成一个字符常量的字符要求:字符不可是有单引号、反斜杠或者双引号。
注:n个字符的字符串常量,strlen显示为n,sizeof为内存中的占用为n+1。

2.2.3 转义字符

分为简单转义字符、八进制转义字符和十六进制转义字符
(1)简单转义字符,如下图,
【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第5张图片
(2)八进制转义字符,由反斜杠\和1-3个八进制数构成。例如,’\071’(代表ASCII码是57)
(3)十六进制转义字符,有反斜杠\、字母x和1-2个十六进制数构成,用于输出128-255区间。例如’\xFE’(代表ASCII码为254)
注:每个转义字符应该看成一个单字符。

2.2.4

符号常量,用#define和const定义,而且一般用大写字母表示,便于区分。

2.3基本运算

【重中之重】

2.3.1运算符优先级:

【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第6张图片
注:(1)逻辑运算符,用0或1;关系运算符用0和非0。
(2)计算顺序自左向右&&、||、,****(逻辑短路的处理——||、&&)
例如表达式:++i||++j&&++k=>(++i)||(++j&&++k),因为自左向右,++i非0时,终止后面运算。
–x&&++y||z++=>(–x&&++y)||z++,–x为0停止且运算,此时z非0,或运算成1,之后再进行z++;
(3)逗号表达式运算,
如,表达式1,表达式2.求解过程是:先求解表达式1,再求解表达式2.表达式2的值是整个都好表达式的值。

易混淆(难点): 1)i=30 * 5,i * 6 整个表达式的值是900;方法是:按运算符的优先级运算即可。
2)i=(j=30,5 * 30) 此时i就是括号内整个表达式的值,取最右边的150.
3)i=(i=4 * 5,i * 3),i+50;i=20,整个括号内的值是60,但是整个表达式的值是70.
注:可能和编辑器有关,会出现出入,比如(1)最终输出可能是150,(3)可能最终输出是60
(难点二):!(by 运算顺序先处理xy 再处理(b

2.3.2

按位与运算符&:
用途:(1)清零(2)取指定位(3)保留某些位
按位或运算符|:
用途:(1)置1(2)取指定位
按位异或运算符^:
用途:(1)使特定位翻转(2)交换变量值,不用临时变量
比如:a^ =b;b^ =a;a^=b,实现数据交换。
按位取反运算符~:
(1)特定位清零
其它:
注:(1)定义时,不可以连续赋值。
(2)实现四舍五入: y=(long)(x+0.5);

2.4 转换情况

2.4.1自动转换类型

不同类型数据间的隐式转换:自动转换类型
算术运算式——低类型能够转换为高类型。
赋值表达式——右边表达式的值自动隐式转换为左边变量的类型,并赋值给它。
函数调用中参数传递——系统隐式地将实参转换为形参的类型后,赋给形参。
输出转换(函数有返回值)——系统将隐式地将返回表达式类型转换为返回值类型,赋给调用函数。

2.4.2

强制转换类型

2.5输出输入

输入输出格式控制:
printf输出:


scanf输入

普通字符:
空格字符、转义字符(\n、\t)、可打印字符
注(1)“*”,如scanf(“%d %*d %d”,&a,&b,&c);表示输入:45_27_90,则90赋值给b。
(2)l和h,l表示长型,h表示短型
(3)scanf(“%d%c”,&a,&b);会把空格作为字符输入,scanf(“%d %c”,&a,&b);用空格隔开,则不会出现类似输入问题。
(4)putchar(’\101’);输出’A’
(5)输入scanf时,浮点型不可以用m.n来指明精度,scanf(“%5.3f”,&a);就是错误的。
(6)printf("%5.3s",computer); 输出__com;

习题:

2.4 字符常量与字符串常量的区别:

(1)字符常量和字符串常量的表示方法不同:字符型常量是用单引号括起来的一个字符
字符串常量是用一对双引号括起来的零个或多个字符组成的序列
(2)最主要的区别是存储的不同:字符型数据在存储时,并不是把该字符本身放到内存单元中,而是把该字符的相应ASCII码值存放到该存储单元中;而字符串常量是将字符存储,并自动在其末尾加上’\0’作为字符串结束标志,所以字符串常量在内存中所占用的字节数为字符串长度+1。
比如:"ABC\n\TH\064?"长度9,占用内存单元数10。需要注意的是,在该字符串中有转义字符,\n 为换行,\为反斜杠字符,\064 为八进制转义字符,对应ASCII 码为52 的字符’4’。
注:
(1)字符加减运算
char c;
c=‘7’+‘9’ 输出%c c是‘p’。
(2)
char s[3]
s[0]=‘a’;
s[2]=‘b’;
puts(s);
输出:a
而且S[]表明只能存取两个字符,默认s[3]是‘\0’。

2.10(第一版)

输入一个整数number,然后把number的高八位和低八位交换输出。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<sstream>
using namespace std;
int main()
{
    int number;
    char high_eight,low_eight;
    scanf("%d",&number);
    printf("before exchange,number=0x%x\n",number);
    low_eight=number & 0xff;  //取出低八位
    number>>=8;     
    high_eight=number & 0xff;  //取出原来的高8位
    number=low_eight;             
    number<<=8;			//低位到高位
    number=number | high_eight;   //原高位到低位
    printf("after exchange,number =0x%x\n",number);
    return 0;
}

2.14

int y=-1;
y<<3;
printf("%d",y);

提示:
(1)负数的补码,除最高位,其余取反,最后加1;
(2)负数的反码,除最高位,其余取反。
(3)计算机都是以补码形式存放

答案:-8

第三章 控制语句

3.1

注:(1)break只能用于循环和swicth中,在switch中是break直接跳出switch。
(2)switch中的表达式只能是整数或者字符型表达式,不可以是逻辑表达式或者关系表达式。
(3)case 3而不是case3,后者是个一般标识符。

3.2应用:

(1)switch 通过字符判别,进行四则运算选择与计算。
(2)switch的多分支,便于面向用户的开发。
(3)switch 通过数值判断,输出字符,比如1——one/January

例题:

3.8把整数转化为二进制输出(用位逻辑运算)

#include<iostream>
#include<stdio.h>
using namespace std;

int main(){
    int i;
    unsigned number,temp;
    scanf("%u",&number);
    printf("%4x\n",number);
    for(i=15;i>=0;i--)
    {
        temp=(number & 0x8000); //值得学习一:取最高位
        temp>>=15;
        printf("%1x",temp);//值得学习二:二进制输出用16进制取一位
        number<<=1;
    }
    printf("\n");
    return 0;
}

3.15 字符串中,连续出现的字符不输出,以’.'为结束标志。

#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
    char ch_old,ch_new;
    ch_old='.';
    do{
        scanf("%d",&ch_new);
        if(ch_new==ch_old)
            continue;
        ch_old=ch_new;
        printf("%c",ch_old);
    }while(ch_old!='.');
    printf("\n");
    return 0;
}

3.3 控制结构分析及伪码表达 难点

(1)do S while(B)
伪码:

Begin
S_do:
	S
	goto S_exit
if B!=0 goto S_do
S_next;
End

(2)if(B) S1 else S2
伪码:

if B goto B.True (条件转移指令)
goto B.false	(无条件转移指令)
B.true: S1的代码
	goto S.next
B.false: S2的代码
S.next:

(3)for(i=1;i 伪码:

i:=1;
again: if i<n 
{	S的代码
	...
	i:=i+1;
	goto again;
}
S_next:

(4)正整数的累加
伪码:

Begin
SET 0->sum
SET 0->count
WHILE count<10
BEGIN
	READ a integer data to x from keyboard
	IF x>0
	sum+x->sum
	END IF
	count+1->count
	END-WHILE
PRINT sum
END

(5) while(B) S
伪码:

Loop:if B goto B.true
	goto S.next
B.true:(S的代码)
	...
	goto Loop;
S.next:

(6)switch(E)
{
case N1:S1;break;
case N2:S2;break;
default S3;
}
E代表常量表达式,N代表常量,S代表执行语句。

t=E;
if t=N1 GOTO S1
goto N2
S1_do;
goto S.next
if t=N2 goto S2
goto S3
S2_do;
goto S.next
S3_do;
S.next;
习题:

3.17 输入两个数i,j。表示j大于0时,i循环左移j位;j小于0时,i循环右移j位。
难点:如何处理循环。方法(1)对16-j单独取出得temp,(2)在循环移动j位,i这个数(3)把两个temp和i做或运算即可。

#include<iostream>
#include<stdio.h>
using namespace std;

int main(){
    int i,j,temp;
    scanf("%d %d",&i,&j);
    if(j>0)
    {
        printf("shif left %d bits\n",j);
        temp=i>>(16-j);
        i<<=j;
        i|=temp;
    }
    else{
        j=-j;
        printf("shif right %d bits\n",j);
        temp=i<<(16-j);
        i>>j;
        i|=temp;
    }
    printf("result %d",i);
    return 0;
}

3.18 求一个数i的二进制第j位的数值
本题有两种方法:方法一,取余找出所有位,这是通法,但不是最快的。
方法二,找一个第j位恰为1,其余位是0的数,与i做与运算。

#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
    int i,j;
    scanf("%d %d",&i,&j);
    int flag=1;
    flag<<=j;
    if(flag&i)
        printf("THE %dth bit of %d is:1\n",j,i);
    else
        printf("THE %dth bit of %d is:0\n",j,i);
    return 0;
}

第七章 变量的存储类型

变量的存储类型决定了变量的(1)存储方式(2)生命期(3)作用域
【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第7张图片
(1)程序代码区:存储程序代码
(2)数据静态存储区:存储程序的全局数据和静态数据。
(3)数据动态存储区(stack area/heap area):
a、函数数据存储区:存储返回地址、CPU现场、形参、函数定义变量、临时变量
b、存储动态内存申请数据
变量的存储类型:
分为静态存储方式和动态存储方式。
细分:
自动(auto)、外部(extern)、静态(static)和寄存器(register)

7.1

7.1.1

自动变量又称局部变量,作用域在函数定义范围内,生命期是在函数调用期间,函数调用时,在动态存储区建立,存储空间在栈区间。

7.1.2

外部变量,作用域为全局,生命期为程序的整个执行期间,存储空间为数据区
(1)若某函数要在外部变量m定义之前使用,需要申明extern m;才可以在本函数中使用。
(2)若外部变量与函数中的内部变量同名,则在该内部变量的作用域内,外部变量不可见。

#include<stdio.h>
int m=100;
void f1()
{
    int m=200;
    printf("m=%d\n",m);
    {
        int m=300;
        printf("m=%d\n",m);
    }
}
int main()
{
    f1();
    printf("m=%d\n",m);
}

输出 m=200 m=300 m=100;

7.1.3

静态变量,作用域为函数区间,但是生命期是程序的整个执行期间,存储空间为固定的数据存储区。
分为内部静态变量和外部静态变量,
(1)内部静态变量是作用域在函数区间
(2)外部静态变量是全局,但是与extern不同的是只能在该源程序文件中,extern可以通过申明扩散到其他源程序文件中。

7.1.4

寄存器变量,生命期和作用域与auto是一样的,但存放在CPU寄存器中,速度更快。
小结:(1)未初始化时,static和extern的初值为0,register和auto初值不确定。
(2)auto和register的赋值可以是常量或者有效表达式,但是static和extern只能是常量。
【高效复习】C语言程序设计(UESTC) 黄迪明版 (第一章-第三章、第七章——基本数据类型及运算、控制语句、变量的存储类型)_第8张图片
7.2
动态存储分配是在堆区进行。

#include<iostream>
#include<stdio.h>
using namespace std;
#define KB 1024
int main(){
    char *block[KB];
    int i,k;
    block[i]=(char*) malloc(KB);
    while(block[i++]!=0)
    {
        k=i;
        block[i]=(char*)malloc(KB);
    }
    for(i=0;i<k;i++)
        free(block[i]);
    printf("Total free memory=%d kilobytes\n",k);
    return 0;
}

通过指针来检查动态存储区的空间大小。

你可能感兴趣的:(C,计算机基础)