【零基础玩转C语言】初识C语言(3)

一.操作符

初识C语言中简单介绍为主,后面会重点讲。

Ⅰ.算术操作符

+   -   *   /   %

其中+(加)-(减)*(乘)比较简单,和我们平时的使用习惯一样
/(除)

#include <stdio.h>
int main()
{
    //除号两端都是整数的时候,执行的是整数除法,结果也是一个整数,会自动向下取整
    int a = 7 / 2;
    printf("%d\n", a);

    //如果两端只要有一个浮点数就执行浮点数的除法,结果也是一个浮点数
    float b = 7 / 2.0;
    printf("%f\n", b);

    return 0;
}

运行结果:
在这里插入图片描述

%(取模)返回两个整数相除后的余数

#include <stdio.h>
int main()
{
    //取模操作符的两个操作符只能是整数
    int a = 7 % 2;
    printf("%d\n", a);

    return 0;
}

运行结果:
在这里插入图片描述

Ⅱ.移位操作符

>>(右移)      <<(左移)

Ⅲ.位操作符

&(按位与)       ^(按位异或)       |(按位或)

Ⅳ.赋值操作符

=   +=   -=   *=   /=   &=   ^=    |=    >>=   <<=
#include <stdio.h>
int main()
{
    int a = 0;//初始化
    a = 3;//赋值
    a += 3;//等价于a=a+3
    a -= 3;//等价于a=a-3
    a *= 2;//等价于a=a*2
    a /= 2;//等价于a=a/2
    //其它赋值操作符的运算也与上述的赋值操作符一样

    return 0;
}

Ⅴ.单目操作符

!           逻辑反操作
-           负值
+           正值
&           取地址
sizeof      操作数的类型长度(以字节为单位)
~           对一个数的二进制按位取反
--          前置、后置--
++          前置、后置++
*           间接访问操作符(解引用操作符)
(类型)       强制类型转换

C语言中,0表示假,非0表示真
sizeof

#include <stdio.h>
int main()
{
    int a = 10;

    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof(int));
    //对象是一个变量时,可以去掉括号
    printf("%d\n", sizeof a);
    //对象是一个类型时,不能去掉括号,否则会报错
    //printf("%d\n", sizeof int);

    int arr[10] = { 0 };
    printf("%d\n", sizeof(arr));//计算整个数组的大小
    printf("%d\n", sizeof(arr[0]));//计算数组一个元素的大小
    printf("%d\n", sizeof(arr) / sizeof(arr[0]));//计算数组元素个数
   
    return 0;
}

运行结果为:
在这里插入图片描述

-- & ++

#include <stdio.h>
int main()
{
    int a = 10;

    //后置++
    int b = ++a;//前置++,先++后使用
    //相当于
    //a=a+1; int b=a;

    a = 10;
    //后置++
    int c = a++;//后置++,先使用后++
    //相当于
    //int c=a; a=a+1;

    printf("b = %d\n", b);
    printf("c = %d\n", c);
   
    return 0;
}

运行结果:
在这里插入图片描述

--++的用法一致

(类型)

#include <stdio.h>
int main()
{
    //3.14 字面浮点数,编译器默认理解为double类型
    //将3.14强制转换为一个整型
    int a = (int)3.14;
    printf("%d\n", a);//3

    return 0;
}

Ⅵ.关系操作符

>
>=
<
<=
!=   用于测试“不相等”
==   用于测试“相等”

如果满足条件,就为真,否则为假

Ⅶ.逻辑操作符

&&     逻辑与
||     逻辑或

&&需要操作符左右两边同时为真,整体才为真
||只要操作符左右两边有一个为真,整体就为真

Ⅷ.条件操作符(或者三目操作符)

如果exp1为真,执行exp2;反之,执行exp3

exp1 ? exp2 : exp3
#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;

    int r = (a > b ? a : b);
    printf("%d\n", r);//20

    return 0;
}

Ⅸ.逗号表达式

逗号表达式会从左向右依次计算,整个表达式的结果是最后一个表达式的结果

exp1, exp2, exp3, …expN
#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    int c = 0;
    //       c=8     a=28   5
    int d = (c=a-2, a=b+c, c-3);
    printf("%d\n", d);//5

    return 0;
}

Ⅹ.下标引用、函数调用和结构成员

[]   ()   .   ->

[]

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int n = 3;
    //访问元素的时候[]里面可以是变量,定义数组的时候不行
    arr[n] = 20;//[]就是下标引用操作符  arr和3就是[]的操作数

    return 0;
}

()

#include <stdio.h>
//函数调用操作符()
int add(int x, int y)
{
	return x+y;
}

int main()
{
    int sum = add(2, 3);//()就是函数调用操作符,add,2,3都是()的操作数

    return 0;
}

二.常见关键字

C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。

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

当我们定义一个变量的时候,变量的名字不能和操作符的名字一样
下面我们重点介绍几个关键字

Ⅰ.关键字 typedef

typedef 顾名思义是类型定义,这里应该理解为类型重命名

//将unsigned int 重命名为uint, 所以uint也是一个类型名
typedef unsigned int uint;
int main()
{
    //观察num1和num2,这两个变量的类型是一样的
    unsigned int num1 = 0;
    uint num2 = 0;
    return 0;
}

Ⅱ.关键字static

在C语言中:
static是用来修饰变量函数

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

1. 修饰局部变量-称为静态局部变量

//代码1
#include <stdio.h>
void test()
{
    int i = 0;
    i++;
    printf("%d ", i);
}

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

//代码2
#include <stdio.h>
void test()
{
    //static修饰局部变量
    static int i = 0;
    i++;
    printf("%d ", i);
}

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

代码一的运行结果:
在这里插入图片描述
代码二的运行结果:
在这里插入图片描述

对比代码1和代码2的效果理解static修饰局部变量的意义。
结论: static修饰局部变量改变了变量的生命周期
让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。

2 .修饰全局变量

//代码1
//add.c
int g_val = 2018;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0;
}

//代码2
//add.c
static int g_val = 2018;
//test.c
int main()
{
    printf("%d\n", g_val);
    return 0;
}

代码1正常,代码2在编译的时候会出现连接性错误。
结论
一个全局变量被static修饰,使得这个全局变量外部链接属性就变成内部链接属性,只能在本源文件内使用,不能在其他源文件内使用。
我们在使用的时候,就感觉作用域是变小了

3.修饰函数

//代码1
//add.c
int Add(int x, int y)
{
    return c+y;
}
//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0;
}

//代码2
//add.c
static int Add(int x, int y)
{
    return c+y;
}
//test.c
int main()
{
    printf("%d\n", Add(2, 3));
    return 0;
}

代码1正常,代码2在编译的时候会出现连接性错误.
结论
一个函数本来是具有外部链接属性的,但是被static修饰的时候,使得这个函数只能在本源文件内使用,不能在其他源文件内使用

剩余关键字后续文章中陆续会讲解

三.#define 定义常量和宏

//define定义标识符常量
#define MAX 1000

//define定义宏
#define ADD(x, y) ((x)+(y))//宏的参数是无类型的

#include <stdio.h>
int main()
{
    int sum = ADD(2, 3);
    printf("sum = %d\n", sum);//sum=5
    
    sum = 10*ADD(2, 3);
    printf("sum = %d\n", sum);//sum=50
    
    return 0;
}

四.一些小知识

Ⅰ.文件的类型:

.h 头文件(函数的声明,类型的声明,头文件的包含)
.c 源文件(函数的具体实现)

Ⅱ.浮点数

浮点数的四舍五入,不能用肉眼看到的值来计算!因为浮点数在内存中有可能不能精确地保存
例如:
当你想要存储12.455时
内存中实际存储的数可能是12.494988882525,是一个近似值

五.指针

Ⅰ.内存

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址
在这里插入图片描述
变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。
取出变量地址如下:

#include <stdio.h>
int main()
{
    int num = 10;//向内存申请4个字节,存储num
    //&是取地址符号
    &num;//取出num的地址,0x0012ff47
    //注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
    printf("%p\n", &num);//打印地址,%p是以地址的形式打印
    return 0;
}

示意图:
在这里插入图片描述
那地址如何存储,需要定义指针变量。

int num = 10;
int *p;//p为一个整形指针变量
p = &num;

int 说明p指向的对象是int类型的
*说明p是指针变量
&num代表num在内存中的存储地址

指针的使用实例:

#include <stdio.h>
int main()
{
    int num = 10;
    int* p = &num;
    *p = 20;//可以通过指针变量修改原来变量的值

    printf("%d\n", num);//num的值也被改变为20了

    return 0;
}

示意图:
在这里插入图片描述
以整形指针举例,可以推广到其他类型,如:

#include <stdio.h>
int main()
{
    char ch = 'w';
    char* pc = &ch;
    *pc = 'q';
    printf("%c\n", ch);//q

    return 0;
}

Ⅱ.指针变量的大小

#include <stdio.h>
//不管是什么类型的指针,都是在创建指针变量
//指针变量是用来存放地址的
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
	//我的电脑是64位的
    printf("%d\n", sizeof(char *));//8
    printf("%d\n", sizeof(short *));//8
    printf("%d\n", sizeof(int *));//8
    printf("%d\n", sizeof(double *));//8
    
    return 0;
}

结论:指针大小在32位平台是4个字节,64位平台是8个字节。

六.结构体

结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。结构体就是把一些单一类型组合在一起的做法。
比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。
这里只能使用结构体来描述了。
例如:

struct Stu
{
    char name[20];//名字
    int age;      //年龄
    char sex[5];  //性别
    char id[15]//学号
};

结构体的使用:

#include <stdio.h>

//学生
struct Stu
{
	//成员
	char name[20];//名字
    int age;      //年龄
    char sex[5];  //性别
    char id[15]//学号
};

//打印结构体信息
void print(struct Stu* ps)
{
	//结构体对象.成员名
	printf("%s %d %s %s\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).tele);

	//结构体指针变量->成员名
	printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->tele);
}

int main()
{
	struct Stu s = {"zhangsan", 20, "nan", "15596668862"};
	
	//结构体对象.成员名
	printf("%s %d %s %s\n", s.name, s.age, s.sex, s.tele);

	print(&s);

	return 0;
}

运行结果:
在这里插入图片描述
后续也会详细介绍结构体

七.总结

💓感谢观看,本文到这里就结束了,如果觉得有帮助,请给文章点个赞,让更多人看到👍👍👍;有不足的地方也请在评论区指出,作者会不断完善每一篇文章!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值