初始c语言03

本章重点

  • 常见关键字
  • define 定义常量和宏
  • 指针
  • 结构体

注意:本篇内容可能会相对之前复杂一些,但现在仅仅是带大家认识c语言的基础知识,后面还会出些比较深层次的知识文章。

本篇文章是初始c语言的最后一篇,后面将分享初阶c语言的知识,循序渐进,慢慢来才比较快。

1、常见关键字

auto   break   case   char   const   continue   default   do   double else   enum  
extern float   for   goto   if   int   long   register     return   short   signed
sizeof   static struct   switch   typedef union   unsigned   void   volatile   while

常见关键字:C语言本身内置的,关键字不是自己创建出来的,也不能自己创建。

关键字是c语言内定的,所以当你定义变量时,不可以用关键字作为变量名称,

如:int for = 0;就是错的

下面会挑一些比较常见的关键字解释一下,后期遇到会详细讲解

Static 静态的

在c语言中:static是用来修饰变量和函数的

  1. 1、修饰局部变量  称为静态局部变量
  2. 2、修饰全局变量  称为静态全局变量
  3. 3、修饰函数          称为静态函数

1.1 typedef 类型重命名

typedef 类型重命名,就是给类型重新起个名字,就比如你叫王多鱼,别人给你重新取了一个名字叫老王。下面就是一个例子:

#include <stdio.h>

typedef unsigned int uint;
//把unsigned int 重新命名为uint 


int main()
{
	unsigned int num = 0;//和下面表达的意思一致
	uint num2 = 1;
	return 0;
}

1.2 Static 静态的

在c语言中:static是用来修饰变量和函数的

  1. 1、修饰局部变量  称为静态局部变量
  2. 2、修饰全局变量  称为静态全局变量
  3. 3、修饰函数          称为静态函数
1.2.1 修饰局部变量 

用static修饰后变为静态变量,

static修饰局部变量的时候,变为静态变量,使变量出了作用域是不销毁的。就是在作用域用完后不销毁,保存下来了原本的值,也就是开辟了一个独立的空间保存a的值。

本质上,static修饰局部变量的时候,改变了变量的存储位置(变为存在静态区)。

影响变量的生命周期,生命周期变长了,变得和程序的生命周期一样

栈区、堆区、静态区是存储数据的区域,一般局部变量存在栈区,用static修饰后就存在静态区

对比下面的连个程序,理解静态变量(注意看注释)

#include <stdio.h>

//void 表示不需要任何返回值,后面会讲
void test()
{
	int a = 1;
	a++;
	printf("%d ",a);
}

int main()
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}
	return 0;
}

程序1结果为:

程序2:

#include <stdio.h>

//修饰局部变量
void test()
{
	static int a = 1;//变成静态变量结果是什么呢
	a++;
	printf("%d ", a);
}

int main()
{
	int i = 0;
	while (i < 10)
	{
		test();
		i++;
	}
	return 0;
}

结果为:

分析一下为什么会这样呢? 其实是因为第二个程序的a用static修饰 变为静态变量,出了void test()函数后不销毁而被保存下来了,而第一个程序的局部变量,出了作用域便自动销毁了,所以再次进去的时候还是1,加1所以输出的一直都是2。自己好好理解一下。

1.2.2 修饰全局变量

全局变量是具有外部链接属性的

一个程序要经过:编译+链接  -->可执行程序

static修饰全局变量的时候,这个变量的外部链接属性就变成了内部链接属性

其他源文件(.c)就不能再使用到这个全局变量了,

换句话来说就是,static修饰的全局变量的作用域不再是整个程序,作用域变成仅仅在当前所处的这个(.c)文件。

这里说明一下:

后缀(.h)为:头文件(函数的声明、类型的声明、头文件的包含)

后缀(.c)为:源文件(函数的实现)

例子:

没加static修饰前,g_val正常当全局变量使用

加入static修饰后,其他文件就不能用g_val这个变量了:

所以:

一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件中使用

1.2.3 修饰函数

函数是具有外部链接属性的,运用static修饰时,不再具有外部链接属性,跟上述修饰全局变量时是同理的,好好理解一下。

下面的程序正常运行:

而static修饰后,就会报错,就是因为不用在其他文件用这个函数了

1.3 register  寄存器

电脑上的储存设备都有哪些?

电脑上大概有这四种储存设备(硬盘、内存、高速缓存、寄存器),他们的关系如上图所示

寄存器是集成到芯片上的,具有很高的存取速度,我们可以利用register关键字向电脑申请把数据存进寄存器中,注意是申请,不是命令!最终数据是否储存在寄存器还是由编译器决定的。

#include <stdio.h>
int main()
{
	register int num = 3;//建议:3存放在寄存器中
	//只是建议放在寄存器中,最终还是要编译器决定是否放在寄存器上
	return 0;
}

1.4 其他的关键字(后续会详细讲)

struct 结构体

Union 联合体(公用体)

Void 无(函数的返回类型,函数参数)

Sizeof -计算大小

Break   一般在(for;while; do...while),(switch case)中当作结束(跳出标志)

Const  常属性变量(常变量),上一篇文章有介绍。

Extern  声明外部符号的

return   函数放回值

Signed 有符号的

Unsigned 无符号的

auto  使变量在作用域 自动创建自动销毁,一般来说都可以省略,毫无存在感

例子:int a =0; 相当于 auto int a=0;

2、#define 定义常量和宏

定义常量在前面的文章(初始c语言01-常量)中已经讲过,不记得请及时回去查看。

#include <stdio.h>
//#define 定义标识符常量
#define NUM 100

int main()
{
	printf("%d\n",NUM);
	int n = NUM;
	printf("%d\n",n);
	int arr[NUM] = {0};

	return 0;
}

下面讲讲宏,其实宏的作用有点像函数,不过宏的参数使无类型的。

3、指针

3.1 内存

说到指针就不得不说一下内存,电脑的内存大家可能多多少少都有些了解,所以不过多介绍,

程序运行内存是必不可少的,内存就是一个大房子,内存会划为一个个的内存单元(一个内存单元的大小为:1 byte),相当于被分成了很多的小房间,数据就是存储在这其中的房间里。

比如,有个数据存储在某个房间里,要怎么找到这个数据呢,难道要一个房间一个房间的去找吗,当然不是,我们把每个房间都编号,每个房间都有门牌号,相当于“地址”,这样我们找数据的时候就非常快速,直接访问他的地址。

内存单元

编号-->地址-->地址也被称为指针

存放指针(地址)的变量就是指针变量,指针变量也是变量,也分全局变量和局部变量

比如一个32位的电脑

地址线(1/0)每根地址线只能取0(无电流)、1(有电流)

有32根地址线

可以控制2^32个地址序列

当我们需要取出a的地址的时候:

#include <stdio.h>

int main()
{
	int a = 10;
	&num;//取出num的地址
	//这里 a 的4个字节,每个字节都有地址,取出的是第一个字节的地址
	printf("%p\n",&a);//打印地址,%p是以地址的形式打印
	//所以10转化为十六进制为 0x00 00 00 0a 和监视器上的一致
	return 0;
}

打开监视器查看a的地址,

 注意第一行为a的地址,存放的数据是10的十六进制(4个字节):0x00 00 00 0a(倒着写,以后会解释),取地址是取第一个字节的地址!

当我们需要储存a的地址的时候,要把地址放在(int*) 变量上

Int a =10;

int* p = &a;//p就是指针变量

*  说明p是指针变量,int 说明p指向的对象(a)是int类型的

所以,再比如:

char ch = ‘w’;

//它的指针变量如下

char * p = &ch

接下来说一下储存了地址后怎么应用(注意看注释)

#include <stdio.h>

int main()
{
	int a = 10;//向内存申请4个字节(32bit),存储10
	int* p = &a;//p就是指针变量
	*p = 20;//(*p就是p指向的对象,既a=20)
	//解引用操作符,意思就是用过p中存放的地址,找到p所指向的对象(a),*p就是a(p指向的对象)
	printf("%d\n", a);

	return 0;
}

程序的结果为: 20

3.2  指针变量的大小

不管是什么类型的指针,都是在创建指针变量

指针变量是用来存放地址的

指针变量的大小取决于一个地址存放的时候需要多大空间

  • 32位机器上的地址:32bit位 -4 byte,所以指针变量的大小是4个字节
  • 64位机器上的地址:64bit位 -8 byte,所以指针变量的大小是4个字节
#include <stdio.h>

//指针变量大小
int main()
{
	//int* p;
	//char* p2;
	//不管是什么类型的指针,都是在创建指针变量
	//指针变量是用来存放地址的
	//指针变量的大小取决于一个地址存放的时候需要多大空间
	//32位机器上的地址:32bit位 -4 byte,所以指针变量的大小是4个字节
	//64位机器上的地址:64bit位 -8 byte,所以指针变量的大小是4个字节

	printf("%zu\n", sizeof(char*));
	printf("%zu\n", sizeof(short*));
	printf("%zu\n", sizeof(int*));
	printf("%zu\n", sizeof(long*));
	printf("%zu\n", sizeof(float*));
	printf("%zu\n", sizeof(double*));

	return 0;
}

结果为:

4、结构体

生活中的对象都是具有很多复杂信息的,(比如:一个人:名字+年龄+性别+地址+电话等信息

一本书:书名+作者+出版社+定价+书号)

对于这些复杂对象,c语言就给了自定义类型的能力,自定义类型中就有一种叫:结构体(关键字:struct)结构体是c语言中特别重要的知识点,结构体使得c语言有能力描述复杂类型。

结构体是把一些单一类型组合在一起的做法

下面举个例子说明:

#include <stdio.h>

struct Stu
{
	//结构体成员
	char name[20];
	int age;
	char sex[10];
	char phone[12];
};

int main()
{
	//结构体struct Stu相当于一个数据类型
	struct Stu s = {"zhangsan",20,"nan","15915912080"};//注意20是整数型,不用写双引号
	//结构体对象.成员名
	printf("%s %d %s %s\n",s.name,s.age,s.phone,s.sex);

	return 0;
}

运行结果为:

下面举个相对复杂一点的应用

#include <stdio.h>

struct Stu
{
	//结构体成员
	char name[20];
	int age;
	char sex[10];
	char phone[12];
};
void print(struct Stu* ps)
{
	printf("%d %s %s %s\n",(*ps).age, (*ps).name, (*ps).phone, (*ps).sex);
    //(*ps)表示指针指向的对象
	//->
	//结构体指针变量->成员名
	printf("%d %s %s %s\n",ps->age,ps->name,ps->phone,ps->sex);
}

int main()
{
	//结构体struct Stu相当于一个数据类型
	struct Stu s = { "zhangsan",20,"nan","15915912080" };//注意20是整数型,不用写双引号
	printf("%d %s %s %s\n", s.age, s.name, s.phone, s.sex);
	print(&s);

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值