C语言基础-关键字
常用(return、extern等)
return返回函数的返回值
extern:表明该变量或函数都是在别的文件中定义的,提示编译器在其他文件中寻找定义。
extern “c”:为了能够正确实现C++代码调用其他C语言代码。
//不可以将extern"C" 添加在函数内部
break;continue;struct定义结构类型数据
循环结构语句、void无类型数据、sizoef计算表达式或数据类型的占用字节数
unsigned定义无符号数据、signed有符号数、auto 局部变量(自动储存)
和常类型数据类型
const(修饰的长类型数据)
为了取代预编译指令,消除它的缺点,同时继承它的优点,常类型的变量或对象的值是不能被更新。
const常量有数据类型,编译器可以进行类型安全检查,调试工具可以对const常量进行调试。
static(定义静态变量)
1.静态存储类型:
函数内定义(静态局部变量):仅定义一次,变量存在内存的静态区,函数结束静态变量的值也不销毁,函数下次运行时能仍用。
函数外定义(静态全局变量):变量的作用域只在定义该变量的文件中,不能被其他文件通过extern引用。
2 内部链接属性
静态函数只能在声明它的源文件中使用。
typedef换名
typedef(为一种数据类型定义一个新名字),包括基类型/自定义类型(struct等)
1.typedef int A;
⇒以后A出现等同于int出现(替换字符),A是类型
2.typedef struct str A;
⇒struct str是一个定义的结构体类型,换名为A(也是类型)
3.typedef struct str {}*A;
等同于typedef (struct str *)A
A是 指向struct str类型的指针类型
4.typedef int A[5];
等同于typedef int[5] A;
A是一个指向五个整形变量的数组类型
if语句(非零即执行)
布尔变量:if(false) 不执行后面的语句
true被翻译(定义)为1,false被翻译为0
也就是说if本质上判断的是否为0
指针变量:if(NULL) 不执行后面的语句
NULL被定义为0
注意未赋值(野指针,随机指向),会执行后面的语句
整形变量:if(0) 不执行后面的语句
注意int a;if(a) 会执行后面的语句
a随机指向一个数字,有相应的内存空间,不为0
if(-1),if(100) 会执行后面的语句
java中仅支持if(bool表达式)
switch case
switch语句原理:跳转到caseX位置执行剩下的语句,直到最后或者遇见break为止。
switch case会生成一个跳转表来指示实际的case分支的地址,而if…else却需要遍历条件分支直到命中条件,
int k=1;
switch(k)
{
case 1:
case 2: printf("执行2");
case 3:printf("执行3");break;
case 4:printf("不执行4");
}
先跳转到case,没有再跳到break执行剩下的语句
int k=3;
switch(k)
{
case 1:
default: printf("不执行default");
case 3:printf("执行3");break;
}
循环结构
while(表达式)
其中,表达式是循环条件,语句为循环体。
计算表达式的值,当值为真(非0)时,执行循环语句,然后在判断表达式,直到表达式为假(0)时结束循环。
while(2)
{
cout<<"hello";break;
}
do语句;while (表达式);
先执行循环语句一次,在判别表达式的值,若为真,则继续循环;否则中止循环。
do-while 至少要执行一次循环体
do{
cout<<"hello";
}
while(0);
for循环
形式:for(; ; ) 语句;
一般语法格式:
for(初始化;条件表达式;增量){循环体}
其中,表示式可以省略,但是分号不可省略。
表达式1:初始化,是一个赋值语句,它用来给循环控制变量赋初值;
表达式2:条件表达式,是一个关系表达式, 它决定什么时候退出循环;
表达式3:增量,定义循环控制变量每循环一次后 按什么方式变化。
循环区别与转换
for:知道循环次数,先判断后循环
while:不知道循环次数,先判断后循环
dowhile:不知道循环次数。先循环后判断
while有时候不能换成for,for都能换成while。
因为for循环适用于已知循环次数,while循环还适用于未知循环次数的时候
跳过循环(break、continue)
跳过当前循环:
1)使用continue来跳过当前循环,直接进入下个循环
2)使用break来跳出当前循环;结束当前for循环
跳出多重for循环:
1)label语句
跳出多重for循环:
jump:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) {
break jump;
}
跳出代码块:
jump: {
console.log(1);
break jump;
console.log('不会输出');
}
2)使用function
function jumpFor() {
for(var k=0;k<8;k++){
for(var j=0;j<4;j++){
if(k == j ){return false;}
console.log(k,j)
}
}
}
数据类型
定义变量而未赋值
字符型指向NULL 输出空格
整型与指针已经有了内存空间,指向随机(上一次使用过的内存空间)
int a;随机一个值(有相应的内存地址)
int *p; 随机指向一个地址数字(野指针,有相应的内存空间)
char *p;
printf("%c",p);//输出D
int a;
printf("%d",a);//输出8
用NULL来避免野指针(C语言和C++中默认被替换为0)。
int *p=NULL 等于 int *p=0;
就是指向一个空指针。这个p的值为0,有相应的地址。
1.基本数据类型
数值类型
整形(表示整数:short、int、long)
一种数据类型占用的字节数,称为该数据类型的长度。例如,short 占用 2 个字节的内存,那么它的长度就是 2。
short int a =3;
printf("%d\n",sizeof(a)); // 输出为2
短整型short 或 short int
长度:固定为2字节 可表示正的2的16次方-1 个数(可以再表示同样数量的负数)
int 和 long 的长度无法确定,在不同的环境下有不同的表现。
整形int
int的长度不能小于 short,一般为4字节
长整型long
long 的长度不能小于 int。一般32位编译器将long编译为4字节,64位编译为8字节
注:64位系统可兼容32位软件
long long类型
长度固定为8字节
总结起来,它们的长度(所占字节数)关系为:
2 ≤ short ≤ int ≤ long
一般来说64位为 2 4 8
32位为 2 4 4
有符号整数、无符号整数
无符号整数与有符号整数 相加结果默认为无符号数(运用补码运算)
%d输出,printf默认这个数是有符号整数(可将无符号数转变为有符号数输出)
unsigned i=-10; //unsigned:无符号整数
printf("%d",i);//输出-10
浮点型/实型(表示实数:float、double)
printf("%f\n",b); // 默认输出小数和点后六位
printf("%.6f\n",b); // 输出小数和点后六位
实数:有理数和无理数的总称,包括整数和小数点数
单精度浮点型float:32位 4bytes
可以输出小数点后6位
双精度浮点型double:64位 8bytes
可以输出小数点后15位
字符型(表示一个字符:char 1byte)
1、字符仅为单引号
2、字符与ASCII码一一对应(char类型相当于小范围的整形类型,0-127)
如ASCII码98与‘b’,相互对应
char ch=98;
printf("%c\n",ch);//输出b
printf("%d\n",ch);//输出98
int a='b';
printf("%d\n",a);//输出98
printf("%c\n",a);//输出b
因为字符等同于相应的ASCII码,所以字符可与整数/字符进行运算,理解为ASCII码的运算
printf("%c\n",'a'+1);//输出b
printf("%d\n",'a'+1);//输出98
printf("%d\n",'a'+'b'); //输出195(97+98)
printf("%c\n",'a'+'b'); //输出?(97+98,没有对应的ASCII码)
printf("%d",'1'+'2'); //输出99(49+50)
printf("%c",'1'+'2'); //输出c(ASCII码为99)
‘0’-‘9’:ASCII码从48到57
‘A’:ASCII码为65
‘a’:ASCII码为97
//输出ASCII码为0的字符
printf("%c\n",0);//输出空白,实际是(null)
printf("%s\n",0);//输出(null)
字符串(C++)
2.指针类型(长度等同机器字长,如32为4bytes)
1)数组指针(数组的指针,可写)
数组指针(数组的指针 即数组被指针指向,指针中存放的是数组的基地址)
当一个指针变量被初始化成数组名时,就说该指针变量指向了该数组(p中存放str的首地址)
如 char str[20], *p; p=str;
2)字符型指针(C语言,不可写)
char * str = “I love China!”;
或
char * str; str = “I love China!”;
指向的一个固定常量字符串(第一个字符的地址即字符串的首地址) 不可写仅可读(不可再替换成其他字符)
对字符型指针str做输入字符串的命令,就会将常量字符串全部输出。(打印完第一个字符会自动打印完整个字符串)
数组与字符串指针取值与输出:
*(p+i), p[i]都是第(i+1)个元素的值
printf("%d\n",*p++); //先*p,再p++
printf("%d\n",*(p++)); //先*p,再p++
printf("%d\n",(*p)--); //先*p,再*p指向的值-1
C输出:
printf(“%s”,p); printf(p); →输出字符串(p指向的字符串)
printf(“%d”,p); →输出指针p值
C++ 输出:
cout <<*p ; →输出字符串(指针指向的内存空间)
cout <<p ; →输出指针中存放的地址
3.构造类型
数组
声明:type arrayName [ arraySize ];
arraySize 必须是一个大于零的整数常量,type 可以是任意有效的 C/C++ 数据类型
int ch[5]; //通用,声明数组需设置内存空间
ch[0]=1; //通用,声明后赋值
int b[]={1,23,4}; //通用,声明时初始化赋值,内存空间为成员数量
int c[5]={1,23,4}; //通用,声明时初始化赋值,内存空间为5
char c[10]="12312312"; //通用
string d[10]={"123","456"}; //仅C++
字符数组(C中替代字符串)
由于C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中
char b[10]={'1','2','3'}; //通用
char c[]="12312312"; //通用
结构体
struct结构:一种可以存放不同数据的集合
C语言结构体中不能包含函数, 只能包含函数指针。
C++的结构体才可以包含函数
集合:元素仅有“同属于一个集合”的关系
结构包含多个变量或数组变量,称为结构体的成员(理论上各个成员在内存中是连续的)
1)结构体直接定义
如strut stu{int num;char *name;}stu1;
成员在定义时不能初始化
成员类型可以为基类型,也可以为其他构造类型
struct stu为结构体类型名(定义的新数据类型/构造类型)
stu1为结构体类型的变量
若stu结构体只使用一个变量stu1就足够 不打算再定义新变量 定义结构体名字可省略 只留变量名如strut {}stu1;
2)定义+typedef换名
typedef struct Stu{}a;
为结构体类型struct Stu 增加(换)一个新的名字a
→struct Stu,a都是该结构体类型名。
可省略:(Stu)定义时可以省略(a作为类型名即可)
不可省略:但如果定义结构体时,内部需要用本身的结构类型(名)定义变量,则不可以省略本身的结构名
结构体类型指针 换名
typedef struct Stu{}*a;
⇔ typedef (struct Stu *)a;
将struct Stu指针类型(如整形指针类型,int *)
换名为a
a a1; 定义了一个struct Stu 类型 的指针变量a1
3)结构体类型声明变量
①定义结构体后声明变量如strut stu stu1;
②在定义结构体时声明变量如 strut stu {}stu1;
若stu结构体只使用一个变量stu1就足够
不打算再定义新变量 定义结构体名字可省略 只留变量名如strut {}stu1;
③使用typedef 换名后 声明变量
typedef struct stu a
a stu1(a是结构体类型struct stu)
stu1是结构体类型的声明变量
成员的赋值和获取
初始化
struct tag
{chara;int b;
}x = {‘A’, 1};/*初始化*/
按字段,变量名.成员名
如输出 stu1.name
通过指针访问
结点结构体定义一个指针指向一个 特定结点结构体类型 变量
如elm *p=&stu1;(等同于elem *p;p=&stu1;)
可通过(*p).name 来访问 stu1.name:
(*p).name ⇔ p→name :p所指结构体变量(结点)的name成员
(5)notes
①(整体赋值/同数组 只可在定义整体时进行)
如 strut {}stu1={12,‘栗波’};
使用变量过程中只能对成员逐一赋值
②结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间,结构体变量包含了实在的数据,需要内存空间来存储。