C语言快速入门(3)

目录

1.操作符

        1.2关系操作符

        1.3自增自减操作符

        1.3三目操作符 :exp1 ? exp2 : exp3

2.常见关键字

        2.1常见关键字

        2.2关键字typedef

        2.3关键字static

                2.3.1static修饰局部变量

                2.3.2static修饰全局变量

                 2.3.3static修饰函数

3.#define定义的宏和常量

        3.1#define定义的常量

        3.2#define定义的宏

4.指针

        4.1内存

         4.2指针变量

5.结构体


1.操作符

        C语言中很灵活因为C语言提供了非常丰富的作符,诸如: 算术操作符,移位操作符
位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符,逗号表达式
下标引用、函数调用和结构成员。
        1.1算术操作符

            + - * / %,这些都是算术操作符,我们需要注意的是,* 是乘法操作符,是除法操作符,如果除法的两个操作数是整数那么除法运算的结果也是整数,%是取余操作符,两个操作数必须是整数。如下:

 如果除法的两个操作数有一个是浮点数那么结果就是浮点数。

        1.2关系操作符

        >,>=,<,<=,!= (用于测试“不相等”),==(用于测试“相等”)这些都是关系操作符,要注意的是 == 判断等于的操作符,如果一个等号是赋值操作符。

        1.3自增自减操作符

前置++和后置++的区别,看代码:

#include<stdio.h>
int main()
{
	int a = 10;
	int b = ++a;
	printf("%d \n", a);
	printf("%d \n", b);

	int c = 20;
	int d = c++;
	printf("%d \n", c);
	printf("%d \n", d);

	return 0;
}

         代码运行的结果是什么呢让我们来看看!

        为什么会出现这样的结果呢,因为:前置++,是a先自增1然后将a的值赋值给b,后置++

,是c先将自己的值赋值给d,然后再自增。

        1.3三目操作符 :exp1 ? exp2 : exp3

        为什么将三目操作符呢因为它的操作数有三个,怎么运行呢?如果表达式1成立就执行表达式2,如果表达式1不成立就执行表达式3。比如求两个数的较大值:

int main()
{
	int num1 = 3;
	int num2 = 5;
	int c = num1 > num2 ? num1 : num2;//将两个数的较大值给c
	return 0;
}

        这段代码的意思是如果num1>num2,就将num1的值赋给从,否则就将num2的值赋给c。

2.常见关键字

        2.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

        sizeof关键字是求变量或者类型的大小,extern关键字是用来申明外部符号,auto关键字是每个局部变量前面都有的之所以现在看不到了是因为被省略了,register关键字是寄存器关键字,如果在变量的前面加上寄存器关键字意味着建议编译器将变量放在寄存器中,为什么要将变量放在寄存器中呢,因为在计算器中CPU是用来执行机器指令的,而CPU取指令是在内存中取,早期的时候CPU的处理速度慢所以不存在从内存中取指令慢的情况但是随着计算机的发展CPU取指令和执行指令的速度越来越快,内存已经不能满足CPU的需求,因此科学家发明了存取指令更快的高速缓存和寄存器,在这些存储器件中寄存器的存取数据的速度是最快的如果某个变量被大量频繁的使用就可以将它放到寄存器中来提升运行效率。

#include<stdio.h>
int min()
{
	auto int a = 10;
	register int c = 0;//建议将变量c放到寄存器中
	printf("%d ", sizeof(int));//求类型的大小
	return 0;
}

        2.2关键字typedef

        typedef关键字是用来对类型重定义的,就相当于给类型重新起了一个名字,比如:

typedef  unsigned int uint;//相当于给unsigned int 重新起名为uint
int main()
{
	unsigned int a = 0;
	uint s = 0;
	return 0;
}

        typedef  unsigned int uint;//相当于给unsigned int 重新起名为uint。

        2.3关键字static

        static关键字可以修饰变量也可修饰函数。

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

                2.3.1static修饰局部变量

        请看以下代码:

#include<stdio.h>
int test()
{
	int i = 2;
	return i++;
}
int main()
{
	int i = 0;
	while (i<10)
	{
		printf("%d ", test());
		i++;
	}
	return 0;
}

            上面代码打印的结果是什么,让我们一起运行起来看看!

         为什么会是这样的结果呢,这是由变量的声明周期来决定的,局部变量i的生命周期是进入test函数生命周期开始,出test生命周期结束,局部变量i被销毁,如果用static关键字来修饰局部变量i又是怎么样的呢,让我们接着往下看!

        这时候我们发现好像输出的结果变了这是有什么原因造成的呢!因为当static修饰局部变量i的时候改变了局部变量i的生命周期使得变量i出了函数test也没有被销毁,使得局部变量的生命周期变长了,变得和程序的生命周期一样长,本质上是改变变量i的存储位置,局部变量本来是存储在在栈上的,被static修饰后,i变量被存储在了静态区。(数据在内存中可以存储在栈,堆或者静态区)

如图:

                2.3.2static修饰全局变量

        那么当static修饰全局变量时又是怎么样的呢?让我们一起来看一看吧!

         如果static没有修饰全局变量,那么全局变量在工程中的哪个文件中都可以被找到,此时全局变量的作用域是整个工程。那么当全局变量被static修饰时又是怎么样的呢!我们继续往下看:

       这时我们发现会编译报错这时为什么呢?因为当static修饰全局变量时会改变全局变量的链接属性将全局变量的外部链接属性变为内部链接属性因此被static修饰的全局变量只能在本文件中使用。

                 2.3.3static修饰函数

         那么当static修饰函数时又是怎么样的呢!没有static修饰时:

         这时可以正常调用函数,那么如果加入static修饰又是怎么样的呢!我们继续向下看:

        这时我们发现编译器又报错了,这是因为当static修饰函数时改变了函数的链接属性,将函数的外部链接属性改为了内部链接属性,其他源文件就无法使用了。(全局变量和函数都是具有外部链接属性的) 

3.#define定义的宏和常量

        3.1#define定义的常量

        #define定义的常量相当于给将一个符号当成了这个常量的值,但是在程序预编译的时候符号会被替换为常量值。比如:

#define MAX 100//将常量100定义为MAX
int main()
{
	return 0;
}

        上面的代码的意思是将常量100定义为MAX。

        3.2#define定义的宏

        

#define ADD(a,b)  ((a)+(b))//宏,实现两个数相加
int main()
{
	int sum = ADD(2, 45);
	printf("%d ", sum);
	return 0;
}

        上面的ADD就是一个宏,它实现了两个数相加求和的功能,是不是感觉和函数调用是不是有一点相似呢,那么让我们一起看看宏的组成部分吧!

         宏和函数是不一样的,宏是在预编译阶段进行的参数替换,函数则是在有自己的地址调用函数时会创建栈桢,宏的参数是没有类型检查的不是很安全,但是函数的参数是存在类型检查的。

4.指针

        4.1内存

        内存是电脑上面很重要的存储器件,计算机中的程序都是在内存中运行的,为了有效的使用内存,就把内存划分为一个个有效的的单元,为了能够访问每个内存单元就给内存单元进行了编号,这些编号就被称为内存单元的地址。如图:

        变量的创建都是在内存上的(在内存中给变量分配空间),每个内存单元都有地址,所以每个变量也是有地址的,取出变量的地址如下:

        我们可以看到变量a确实是有地址的并且变量a的地址是可以被拿到的,那么我们拿到的是变量a整个的地址吗,不是我们拿到的是a的首地址,为什么拿到a的首地址就可以了呢,因为变量在内存中是连续存放的,而内存在物理上也是连续的,如图: 内存地址是用十六进制表示的。

         4.2指针变量

        内存地址也叫指针如果我们将变量的地址取出来存到一个变量中该如何操作呢?

int main()
{
	int a = 10;//定义变量a,并向内存申请4个字节的空间
	&a;//取出变量a的地址
	int* p = &a;//用指针变量来存放a的地址
	return 0;
}

        我们可以用一个int*型的变量p来存放变量的地址,那么变量p就被我们称为指针变量简称指针。int说明要存放的变量的地址是int类型的变量,*说明是指针变量。

5.结构体

        我们之前描述一个人的年龄可以用int类型的变量,描述一个人的体重可以用float类型的变量,那么如果需要我们来描述一个人该用什么类型的变量呢,我们发现好像之前C语言提供的内置类型都无法满足我们的需求,于是我们就要来看看C语言提供的自定义类型结构体了,那么如果我们需要描述一个人的身高体重,年龄,性别,家庭住址该如何表示呢?

struct peo//定义类型peo
{
	int age;
	float height;
	float weight;
	char sex[10];
	char id[20];
};
int main()
{
	struct peo s1 = { 20,55,180,"male","zhongguoxian" };//用peo类型创建变量s1变初始化
	return  0;
}

        创建类型的时候是不会消耗空间的,那么我们如果我们想要打印变量s1该如何打印呢?如果是结构的变量来的访问结构的成员,我们可以使用 . 这个操作符,如果是结构的指针来访问结构的成员我们可以使用 -> 这个操作符。如下:

#include<stdio.h>
struct peo//定义类型peo
{
	int age;
	float height;
	float weight;
	char sex[10];
	char id[20];
};
int main()
{
	struct peo s1 = { 20,55,180,"male","zhongguoxian" };//用peo类型创建变量s1变初始化
	printf("%d %f %f %s %s", s1.age, s1.height, s1.weight, s1.sex, s1.id);
	//如果是结构的变量通过 . 操作符来访问结构的成员
	struct peo* p1 = &s1;//将变量s1的地址存储到结构指针p1中
	printf("%d %f %f %s %s", p1->age, p1->height, p1->weight, p1->sex, p1->id);
	//如果是结构的指针通过 -> 操作符来访问结构的成员
	return  0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值