1.常见关键字
熟知常见的关键字可以避免在定义变量时误用
- auto 局部变量通常前面省略了auto 如下
int main(){
auto int a = 10;//通常来讲省略了auto 局部变量及自动变量
return 0;
}
- const break case default do double extern(引入外部符号) float for goto if int long void union(联合体) volatile while sizeof
- register(寄存器关键字)
举个例子,假设未来a需要频繁被访问,但是每次需要从内存取数据需要花费大量的时间,所以可以“建议””将a存储到寄存器中,并不是一定能放到寄存器中
register int a = 10;//建议把a定义成寄存器变量
- signed
int定义的变量时有符号的,通常都为signed int 只不过常常都会把signed省略掉 - unsigned
- struct结构体关键字
- extern引入外部符号
可以创建两个源文件,来进行如下两个小例子
1.源文件1可以创建一个int型的变量,在源文件2中可以使用
2.源文件1可以创建一个函数,源文件2中可以调用
extern int Add(int ,int); - typedef类型定义
举个例子
unsigned int num = 20;//若未来会多次用到unsigned int,可以选择定义一个别名
typedef unsigned int u_int;
u_int num1 = 20;
- static
作用:
修饰局部变量,也就是让局部变量的生命周期变长了;
修饰全局变量,限制了全局变量的作用域,让静态的全局变量只能在自己所在的源文件内部使用,出了源文件便不可使用了;
修饰函数,改变了函数的作用域(其实正确说法是改变了函数的连接属性,使用static就从外部连接属性变为了内部链接属性)
void test(){
int a = 1;//注意a为局部变量,出了这个括号,局部变量的生命周期结束,也就是说第二次调用test函数时,a的值为1
//局部变量进去创建,出去销毁
a++;
printf("a = %d\n",a);
}
int main(){
int i = 0;
while(i<5)
{
test();
i++;
}
return 0;
}
最后的输出结果为5个2
倘若加入了static关键字:
void test(){
static int a = 1;//a此时变为了一个静态的局部变量
//此时a不进行销毁,最后输出结果为23456
a++;
printf("a = %d\n",a);
}
int main(){
int i = 0;
while(i<5)
{
test();
i++;
}
return 0;
}
2.#define
- 定义标识符常量
#define Max 100
- 定义宏----实现起来更加简洁
#define MAX(X,Y) (X>Y?X:Y)
3.指针
学习指针之前,需要先了解内存
3.1内存
内存被划分了一个一个小的内存单元,有如下问题
- 如何找到内存单元?—编号
- 如何编号?/即如何产生地址?-----买电脑有32位、64位,其中32位即为32跟地址线/数据线,一旦通电就有正电和负电的区分,1/0,即电信号转化为了数字信号
列出所有可能的32位:000…000~111…111(总共有2^32个编号,对应内存单元的地址) - 每个内存单元多大?-----一个内存单元空间大小为1个字节单位划分的
- int a = 10;也就是申请了4个字节的空间,那我如何知道4个字节放到哪里去了,用到&操作符
int a = 10;
//&a取地址
printf("%p\n",&a);
要注意,这个地址打印出来是十六进制的,可以换算成二进制,能不能将这个打印出来的地址存起来呢?可以
3.2指针定义
有一种变量就是用来存放地址的——指针变量
如何定义呢?
int*p = &a
注意此时p的类型是int * 并不是int
p = 20 解引用操作符 –
来看一个其他指针类型的例子
char ch = 'w';
char *pc = &ch;//注意这里是char 不是int
*pc = 'q';
printf("%c\n",ch);
double d = 3.14;
double* pd = &d;
*pd = 5.5;
printf("%lf\n",d);
3.3指针变量的大小
前面说过,指针是存放的变量的地址,如果是32位机器,那么地址为32个bit,即为4个字节;如果是64位机器,地址为64个bit,即为8个字节。
所以指针大小在32位平台是4个字节,64位平台是8个字节
printf("%d\n",sizeof(char*));
printf("%d\n",sizeof(short*));
printf("%d\n",sizeof(int*));
printf("%d\n",sizeof(double*));
最后打印都是4
4.结构体
已经学习了多种数据类型,如int double
那如何去表达一个复杂对象,如人、书呢?
可以用结构体来描述,结构体是自己创造出来的类型
//创建一个结构体类型
struct Book{
char name[20];//书名
short price;//定价
};//别忘记这里的分号,当前创建的是类型,并未创建一本书
int main(){
//利用结构体类型创建一个该类型的结构体变量
struct Book b1 = {"c语言程序",55};
printf("书名:%s\n",b1.name);
printf("价格:%s\n",b1.price);
b1.price = 15;
printf("修改后的价格:%s\n",b1.price);
return 0;
}
思考:如何能改结构体中的name?
在上例中不难看出,结构体中的price是可以更改的,因为pirce是变量,那如果按照同样的方法能不能修改name呢?不可以,因为name是数组名,本质上是地址
//创建一个结构体类型
#include<stdio.h>
#include<string.h>
struct Book{
char name[20];//书名
short price;//定价
};//别忘记这里的分号,当前创建的是类型,并未创建一本书
int main(){
//利用结构体类型创建一个该类型的结构体变量
struct Book b1 = {"c语言程序",55};
strcpy(b1.name,"母猪的产后护理");//传入的两个参数
//strcpy-----string copy 字符串拷贝--需要用到库函数 string.h
return 0;
}
加入指针之后
struct Book{
char name[20];//书名
short price;//定价
};//别忘记这里的分号,当前创建的是类型,并未创建一本书
int main(){
struct Book b1 = {"c语言程序",55};
struct Book* pb = &b1;
//利用Pb打印出我的书名和价格
printf("%s\n",pb->name);//->为指向,即指向b1的name
printf("%d\n",pb->price);
//下面为比较常规繁琐的写法
printf("%s\n",(*pb).name);
printf("%s\n",(*pb).price);
}
在上述案例中,用到了两种操作符
- . ------结构体变量.成员
- -> -----结构体指针->成员