题目1:
题目2:
1. 有符号和无符号char类型取值范围
有符号:-128~127
无符号:0~255
2. 有符号和无符号int类型取值范围
有符号:-2^31~2^31-1
无符号:0~2^32-1
3. 字符串与字符数组的区别
字符串有’\0’作为结束标记,字符数组没有结束标记
4. 宏定义的含义
将一个常量或者常量表达式标识成另一个字符,使用这个标识符就相当于使用这个常量或者常量表达式,也将称之为宏定义,这个标识符一般使用大写字母表示,并且满足标识符的命名规则。一般直接整体替换。
5. 四种存储类型
auto register extern static
6. sizeof与strlen的区别
sizeof计算类型或变量所占用字节数;
strlen计算字符串长度。
7. -128-1?
8. 数据在存储与取出的顺序
存储时:源码->反码->补码
取出时:补码->反码->源码
9. 支持bool类型的头文件
stdbool.h
10. &&与&的区别
&&表示逻辑运算,&表示按位进行与运算
# 一 第一个程序
1.1 代码注释
方法1:注释一行
//.....
方法2:注释多行(给函数加注释,一些不确定的代码,或者给某些变量加解释)
/*
...
*/
方法3:注释多行(条件编译,功能的开关)
#if 0
...1
#endif
1.2 中文切换
ctrl + space
1.3 代码讲解
#:预处理标识符,在gcc编译的第一个阶段就会执行的代码
#include :要包含的头文件,要使用哪个函数,就需要包含声明所在的头文件
<>:包含系统或者第三方提供的头文件,可以使用""来包含。
寻找路径顺序:到系统指定的路径寻找(/usr/include/)
"":包含自定义的头文件,不能使用<>
寻找路径顺序:默认到当前路径或者自己指定的路径中寻找,找不到再去系统指定的路径中寻找。
stdio.h:标准输入输出头文件,printf函数的声明就是在这个头文件中。
#include <stdio.h>
int:整数类型,返回值类型
main:主函数,函数的入口地址,一个程序只能由一个主函数,而且必须有。
():里面存放函数的形参
int argc, const char *argv[]:命令行参数
{}:里面包含这个函数的执行代码(函数体)
函数里面每一行代码执行完毕之后,需要加上;
作用域:通常以{}为分割
生命周期:
int main(int argc, const char *argv[])
{
printf("hello world!\n");
return 0;
}
1.4 gcc编译出现的问题
正确编译:编译完成没有任何现象
出现警告:警告还是会生成可执行文件,一般警告可以忽略不管,但是能处理还是要处理
出现错误:出现错误不会生成可执行文件,必须要处理,可以根据报错的行号和报错提示进行定位解决。
二 计算机的数据表示
分类:
数值型数据
非数值型数据
2.1 数值型数据
数值型数据的表示方法:二进制,八进制,十进制,十六进制
[1] 二进制:由 0和1表示的数据,称之为二进制数据,使用前导符0b
例如:0b10011010001
[2] 十进制:由0-9表示的数据称之为十进制数,我们人类所能直接识别的数就是十进制数
例如:256
二进制转十进制:
0b11011 --> 1*2^0 + 1*2^1 + 0*2^2 + 1*2^3 + 1*2^4 = 27
十进制转二进制:
凑数或者除商取余倒着往上数
[3] 八进制 由0-7组成的数称之为八进制数,使用0作为前导符
例如:0756
八进制转十进制:
0627 ---> 7*8^0 + 2*8^1 + 6*8^2
八进制转二进制:一位八进制可以用三位二进制表示(7 -->111)
0627-> 0b110010111
二进制转八进制:
0b 10 100 010 001 110 -->024216
[4] 十六进制 由0-9和a-f组成的数称之为十六进制数,使用0x作为前导符
例如:0xa6cd
十六进制转十进制:10 11 12 13
0xa6cd->13*16^0 + 12*16^1 + 6*16^2 + 10*16^3
十六进制转二进制:一位十六进制可以由四位二进制表示(1111 -->15)
0xa6cd-> 0b1010 0110 1100 1101
二进制转十六进制:从右往左取四位转为十六进制
0x1010 0110 1100 1101-->0xa6cd
2.2 非数值型数据
理论上非数值型数据计算机是不能识别的,只能识别二进制码,也就是数值型数据,但是在写代码的过程中,会需要使用非数值型数据,所以别人规定了一套方法:每一个非数值型数据都用数值型数据表示,表示方法称为ascii,我们将非数值型数据也称为字符。
'\0': ---> 0
'\n': ---> 10
'0' - '9' --> 48 - 57
'A' - 'Z' --> 65 - 90
'a' - 'z' --> 97 - 122
三 词法符号
任何高级语言都是由词法符号和若干数据类型组成的,词法符号是语言的基本单位,数据类型是数据的基本属性。
词法符号也是程序设计语言的最小单位,按照词法符号作用的分类,大致可分为:
关键词,标识符,分隔符,运算符,标点符号,但凡涉及到单词,大小写敏感
3.1 关键词
关键字是系统预定义的此法符号,有特定的含义,不允许用户重复定义,必须都是小写并且可以直接使用
char,short,int,long,float,double,enum,struct,union,void,signed,unsigned 12个
auto register const static volatile extern 6个
typedef 1个
sizeof 1个
if else switch case default for while do goto return break continue 12个
3.2 标识符
标识符就是给代码中一些常用的东西取名字,例如:变量名,函数名,结构体名,宏定义名,取别名等,且这个名字最好与要表示的东西的含义一致。
标识符的命名规则:
只能由数字,字母,下划线(_)组成
开头不能是数字
不能与关键词相同
注意:严格区分大小写
3.3 分隔符
分隔符是用来分割其它的词法符号的。
空格符,制表符,换行符,注释
通过对分隔符的恰当使用,使得代码的外观格式更加清晰易读,还可以帮助程序员分析语法错误。
3.4 运算符
运算符是表示运算的词法符号
按功能分:
算术运算符,逻辑运算符(关系运算符),位运算符,赋值运算符,自增自减运算符(++ --),地址运算符(&),逗号运算符,
sizeof运算符。
3.5 标点符号
逗号,分号,冒号,花括号,圆括号,标点符号和分隔符的功能相似,但是用法非常严格,有着明确的语法规定,有些标点符号出现在表达式中,可以当做运算符使用。
四 数据类型
基本数据类型:char(1),short(2),int(4),long(8),long long(8),float(4),double(8),(unsigend,signed),enum(4)
构造数据类型:struct,数组,union
指针类型:复杂数据类型
空类型:void类型,也称为缺省型,用于描述空集
4.1 bool类型
#include <stdio.h>
#include <stdbool.h>
int main(int argc, const char *argv[])
{
//定义一个bool类型变量并赋值为10
//注意:c语言默认不支持bool类型需要添加stdbool.h头文件
//bool类型只有两个0和1,非0即为真,
//bool类型主要用于判断语句,判断条件是否成立
bool b = 10;
//%d:输出整型数据
printf("b = %d\n",b);
bool c = 0;
printf("c = %d\n",c);
bool d = 0.00000045;
printf("d = %d\n",d);
return 0;
}
4.2 整数类型
4.2.1 char
char类型占一个字节
有符号:char 或者signed char
取值范围:-2^7 ~ 2^7-1 --->-128 ~ 127
无符号:unsigned char
取值范围 0 ~ 2^8-1 --> 0 ~ 255
4.2.2 short
short 占2个字节
有符号:short 或者signed short
取值范围: -2^15 ~ 2^15-1 --->-32,768 ~32767
无符号:unsigned short
取值范围:0 ~ 2^16-1 --->0 ~ 65535
4.2.3 int
int类型占4个字节
有符号:int 或者signed int
取值范围: -2^31 ~ 2^31-1
无符号:unsigned int
取值范围:0 ~ 2^32-1
4.2.4 long
long在32位操作系统中占4个字节,在64位操作系统中占8个字节,以64操作系统进行讲解
有符号:long 或者signed long
取值范围: -2^31 ~ 2^31-1
无符号:unsigned long
取值范围:0 ~ 2^32-1
4.3 数据在内存中的存储
原码 反码 补码
我们人为设置的数据称之为原码
存储在计算机中的我们称之为补码
为了实现原码和补码之间的转换,加入了反码
存储数据的顺序:原码--->反码--->补码
取出数据的时候:补码--->反码--->原码
如果一个数为正数,原码 反码 补码都一样
如果一个数为负数,其最高位为符号位,符号位为1表示负数,符号位为0表示正数,反码等于原码取反,补码等于反码+1
unsigned char a = 100;
存储时:
原码:0110 0100
反码:0110 0100
补码:0110 0100
取出时:
补码:0110 0100
反码:0110 0100
原码:0110 0100
signed char b = -10;
存储时:
原码:1000 1010
反码:1111 0101
补码:1111 0110
取出时:(unsigned char c = b;)
补码:1111 0110
反码:1111 0110
原码:1111 0110 = 246
取出时:(char d = b;)
补码:1111 0110
反码:1111 0101
原码:1000 1010 = -10
unsigned char d = -74
存储时:
原码:1100 1010
反码:1011 0101
补码:1011 0110
取出时:
补码:1011 0110
反码:1011 0110
原码 1011 0110
五 常量
常量是指在程序运行期间其数值不会放生变化的数据(左值)
左值:可以被修改的值(等号左边的值)
右值:不可以被修改的值(等号右边的值)
5.1整数常量
十进制:%d
八进制:%o
十六进制:%x
#include <stdio.h>
//整数输入方式:2进制,8进制,10进制,16进制
//整数输出方式:8进制,10进制,16进制
int main(int argc, const char *argv[])
{
int num = 1000;
//此处#表示输出前导符
printf("num = %d\n",num); //以10进制输出
printf("num = %#o\n",num); //以8进制输出
printf("num = %#x\n",num); //以16进制输出
int num1 = 0xaabbccdd; //输入16进制数
int num2 = 0567; //输入8进制数
int num3 = 0b10011111; //输入2进制数
printf("num1 = %d\n",num1); //以10进制输出
printf("num1 = %#o\n",num1); //以8进制输出
printf("num1 = %#x\n",num1); //以16进制输出
return 0;
}
5.2 浮点常量和指数常量
float :%f
double:%lf
指数常量就类似于科学计数法:
678900 --->6.789*10^5 -->6.789e+5,使用%e输出指数常量
指数常量的格式:<+/-> m.ne <+/->i
例如:-3.14*10^-7 --->-3.14e-7
#include <stdio.h>
int main(int argc, const char *argv[])
{
float a = 345641.12345;
printf("a = %f\n",a);
printf("a = %e\n",a);
float b = -1.78e-5;
printf("b = %f %e\n",b,b);
return 0;
}
5.3 字符常量
字符:将一个单一的非数值型数据用单引号引起来,就将其称之为一个字符
例如:'a' 'y' '9'
#include <stdio.h>
int main(int argc, const char *argv[])
{
char a = 'w';
printf("a = %d, %c\n",a,a);
char b = 97;
printf("b = %d, %c\n",b,b);
char c = 'w';
c = c - 32;
printf("c = %c\n",c);
return 0;
}
5.4 字符串常量
将一个或者多个字符通过双引号引起来,将其称之为一个字符串,每一个字符串的结尾都会自动加上\0
例如:"helloworld", "a","abc","1234"
注意:
a:是一个变量
'a':是一个字符常量,占一个字节
"a":是一个字符串常量,占2个字节
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main(int argc, const char *argv[])
{
//定义一个字符数组保存字符串
char ch[] = "hello\0world";
//使用%s来输出字符串
//字符串结束的标志就是\0,换言之,就是输出到第一个\0之前
printf("ch = %s\n",ch);
char a = 'w';
printf("sizeof(ch) = %ld\n",sizeof(ch)); //sizeof用于计算数据类型所占内存空间的大小
printf("strlen(ch) = %ld\n",strlen(ch)); //用于计算字符串长度(不计算\0)
printf("sizeof(int) = %ld\n",sizeof(int));
printf("sizeof(bool) = %ld\n",sizeof(bool));
printf("sizeof(float) = %ld\n",sizeof(float));
printf("sizeof(double) = %ld\n",sizeof(double));
printf("sizeof(char) = %ld\n",sizeof(char));
printf("sizeof(short) = %ld\n",sizeof(short));
printf("sizeof(a) = %ld\n",sizeof(a));
return 0;
}
5.5 标识常量–宏定义
将一个常量或者常量表达式标识成另一个字符,使用这个标识符就相当于使用这个常量或者常量表达式,也将其称之为宏定义,这个标识符一般使用大写字母表示,并且满足标识符的命名规则。
格式:
#define 标识符 常量或者常量表达式
例如:
#define N 32
#include <stdio.h>
#define M 128
#define N 32
#define SUM M+N
#define SUM1 (M+N)
#define SUB(a,b) (a-b)
int main(int argc, const char *argv[])
{
int i = M + 5;
printf("i = %d\n",i);
int a = M + N;
printf("a = %d\n",a);
int b = SUM *10; // M + N *10 --->128 + 32 *10
printf("b = %d\n",b);
int c = SUM1 *10; // (M + N) *10 --->(128 + 32) *10
printf("c = %d\n",c);
int e = SUB(10,5) + 100;
printf("e = %d\n",e);
return 0;
}
练习:
一个水分子的质量约为3.0*10^-23g,1夸脱水大约有950g,编写一个程序,要求输入水的夸脱数,然后在终端显示这么多水中包含多少水分子(科学计数法输出)。
要求:一个水分子的质量和1夸脱水大约有950g使用宏表示.
#include <stdio.h>
#define WATERWIGHT (3.0e-23)
#define QUATERWIGHT 950
int main(int argc, const char *argv[])
{
int num; //夸脱数
double sum;
printf("请输入水的夸脱数:\n");
//从终端获取一个整数
scanf("%d",&num);
sum = QUATERWIGHT/WATERWIGHT * num;
printf("%d 夸脱水中有%e个水分子\n",num,sum);
return 0;
}
六 变量
6.1 概念
变量就是我们自己定义的可以改变其值的量(右值)
变量名是一个标识符,所以需要满足标识符的命名规则
在程序运行时,变量会占据一定的内存空间,其大小由数据类型来决定
例如:int a--->变量a在内存中占4个字节,char b --->在内存中占1个字节
#include <stdio.h>
int main(int argc, const char *argv[])
{
int i; //未初始化
i = 100; //赋值
int a = 100; //定义的同时并且赋值:初始化
a = 999;
return 0;
}
6.2 变量定义的格式
格式:
存储类型 数据类型 变量名
存储类型:四种
auto register extern static
数据类型:就是之前学习的数据类型,char ,int等等
变量名:就是起的名字
#include <stdio.h>
//初始化:定义变量的时候同时赋值
//赋值:在使用该变量的时候改变其值
//生命周期:从一块空间被分配到一块空间被回收
//作用域:可以使用到这块内存空间的区域
int main(int argc, const char *argv[])
{
auto signed int sum; //未初始化
printf("sum = %d\n",sum);
sum = 200; //赋值
int sum2 = 100; //将sum2初始化为100
int sum3 = sum2; //用sum2去初始化sum3
return 0;
}
6.3 类型转换
原本的变量在使用的过程中需要改变他的类型,转换之后这个变量的类型以及存储空间都会发生改变
类型转换的方法:
隐式类型转换:是操作系统或者编译器自动进行转换的
显示类型转换:又称为强制类型转换,是我们人为直接转换的
显示类型转换实现的一般形式:
(数据类型名称)<表达式>
#include <stdio.h>
//左右等价一致原则
//强制类型转换的本质:截断
int main(int argc, const char *argv[])
{
float f = 3.84;
int a = f;
printf("a = %d\n",a);
int i = -20; //会先将i的转成无符号数进行运算
unsigned int j = 9;
if(i + j > 0)
{
printf("i + j > 0\n");
}
else
{
printf("i+j < 0\n");
}
int m = 9,n = 4;
float f2 = m/n; //隐式类型转换
float f3 = (float)m /n; //显示类型转换
printf("f2 = %f\n",f2);
printf("f3 = %f\n",f3);
int num = 0xaabccdd;
char ch = num;
printf("ch = %#x\n",ch);
/*char ach = 'w';
int anum = ach;
printf("anum = %d\n",anum);
*/
return 0;
}
七 运算符
6.1 算术运算符
双目运算符: + - * / %
单目运算符: ++ --
三目运算符:?:
%:取余,只能用在整数,浮点型数据不能取余
++:自增
--:自减
#include <stdio.h>
int main(int argc, const char *argv[])
{
float m = 12.67,n = 12.89;
printf("%f + %f = %f\n",m,n,m+n);
printf("%f - %f = %f\n",m,n,m-n);
printf("%f * %f = %f\n",m,n,m*n);
printf("%f / %f = %f\n",m,n,m/n);
//取余只能用于两个整数之间,浮点数据不能取余
//printf("%f %% %f = %f\n",m,n,m % n);
printf("************************\n");
int i = 100;
printf("i = %d\n",i);
int num = i++; //i = i +1
printf("num = %d,i = %d\n",num,i);
int num1 = ++i;
i+1;
printf("num1 = %d,i = %d\n",num1,i);
int a = 2,b = 3;
int num2 = a+++b;
printf("num2 = %d,a =%d,b = %d\n",num2,a,b);
int j = 100;
//最终j值不一定是多少,编译器不一样,最终结果也不一样
int num3 = ++j + ++j+ ++j; //204+103
printf("num3 = %d\n",num3);
return 0;
}
作业1:
输入一个三位数,求个位,十位,百位的和
729 ---> 7 + 2 + 9 = 18
729/100 = 7
729 %10 = 9
729 %100 /10 = 2
#include <stdio.h>
int main(int argc, const char *argv[])
{
int num;
printf("请输入一个三位数:\n");
scanf("%d",&num);
printf("num = %d\n",num);
int ge,shi,bai;
ge = num %10;
shi = num %100 /10;
bai = num /100;
int sum = ge +shi + bai;
printf("%d 的各位相加的和为 %d\n",num,sum);
return 0;
}
作业2:
输入两个数,实现这两个数的交换(要求三种方式实现)
int m,n
scanf("%d,%d",&m,&n);
m = 50,n = 100;
...
m = 100,n = 50;
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a = 100,b = 200;
printf("a = %d,b = %d\n",a,b);
//方法一:
#if 0
int tmp = a;
a = b;
b = tmp;
//方法二:
a = a + b;
b = a - b;
a = a - b;
#endif
//方法三:
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d,b = %d\n",a,b);
return 0;
}