初识C语言(Ⅲ)

●🧑个人主页:你帅你先说.

●📃如果文章有帮助,欢迎点赞👍关注💡收藏💖

📖既选择了远方,便只顾风雨兼程。

🤟欢迎大家有问题随时私信我!

●🧐版权:本文由[你帅你先说.]原创,CSDN首发,侵权必究。

目录

1.操作符

1.1算术操作符

1.2移位操作符

1.3位操作符

1.4赋值操作符

1.5单目操作符

1.6关系操作符

1.7逻辑操作符

1.8条件操作符

2.逗号表达式

3.常见关键字

3.1关键字static

4.define定义常量和宏

5.指针

5.1常见的格式符输出

5.2*----解引用操作符

5.3指针变量的大小

6.结构体

6.1结构体的定义和初始化

6.2结构体的声明

6.3结构体成员的访问

6.4结构体传参


1.操作符

1.1算术操作符

+  -  *  / %
%是取模,即取余数,取余的对象只能是整数

1.2移位操作符

>>  <<
移位操作符的对象是二进制位
以4字节整型12为例
eg. 00000000000000000000000000001100  向右移1位
       00000000000000000000000000000110  左边补0

1.3位操作符

&   ^   |
&(按位与)
eg. 
int a=3 b=5;
c=a&b;

a的二进制 00000000000000000000000000000011

b的二进制 00000000000000000000000000000101

结果为       00000000000000000000000000000001

即只要有0即为0

|(按位或)

a的二进制 00000000000000000000000000000011

b的二进制 00000000000000000000000000000101

结果为       00000000000000000000000000000111

即只要有1即为1

^(按位异或)

a的二进制 00000000000000000000000000000011

b的二进制 00000000000000000000000000000101

结果为       00000000000000000000000000000110

相同为0,相异为1

1.4赋值操作符

= += -= *= /= &= ^=  |=    >>=   <<=
以+=为例
a+=5  <=>  a=a+5  其余以此类推
关于float和double需要注意
float a=0;
a=95.5;//直接写出来的浮点数默认是double类型
a=95.5f//指定为float类型

1.5单目操作符

以 3+5 为例

3和5是操作数,3是左操作数,5是右操作数,+是双目操作符。

故单目操作符就是只有一个操作数的操作符

!(逻辑反操作) 

C语言是如何表示真假的?

0位假,非0为真,C语言规定真所对应的值为1。所以 0为假 !0 为真。

这边特别强调大家容易误解的,sizeof是操作符不是函数!

~(按位取反)

00000000000000000000000000001111

11111111111111111111111111111110000  

即0和1互换

整数的二进制表示方法
原码---直接按照数字的正负转换成二进制
反码---原码的符号位不变,其他位按位取反,就是反码
补码---反码+1
特别注意: 正整数的原码、反码、补码相同,整数在内存中存的是二进制补码! 
规定:对于有符号整数,二进制的最高位是符号位,最高位是0,表示正数,最高位是1,表示负数。

1.6关系操作符

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

1.7逻辑操作符

&&(逻辑与)
同时满足两个条件(相当于数学逻辑用语中的且)
||(逻辑或)
两个条件只需满足一个(相当于数学逻辑用语中的或)

1.8条件操作符(三目操作符)

exp1 ? exp2 : exp3   (exp代表表达式)
若exp1的结果为真,则结果为exp2,否则为exp3。

2.逗号表达式

exp1 , exp2 , exp3.....expn
从左向右依次计算,整个表达式的结果是最后一个表达式的结果
eg.
int a=3,b=5,c=6;
int d=(a=a-2,b=a+c,c=a-b);//逗号表达式的结果即为c=a-b的结果
printf("%d",d);//输出结果为-6
下标引用操作符: [ ]
函数调用操作符: ( )

3.常见关键字

在这边先简单介绍几个,后续的文章会详细介绍

 auto-定义局部变量的,一般省略

break-跳出循环

case-在switch语句中会详细介绍

typedef-类型重命名

extern-声明外部变量

在这边提一下大家容易误解的地方,define不是关键字,像#include、#define这种的都属于预处理指令。

3.1关键字static

1.修饰局部变量
使得局部变量出了自己的范围也不销毁,其实是改变了局部变量的生命周期,但是作用域还是局部的。
2.修饰全局变量
全局变量具有外部链接属性,但static修饰全局变量,会使全局变量失去外部链接属性,变成内部链接属性,所以static修饰的全局变量只能在自己所在的.c文件中使用。
3.修饰函数
函数默认是具有外部链接属性,但是被static修饰之后,会使得函数失去外部链接属性,变成内部链接属性,所以static修饰的函数只能在自己所在的.c文件内部使用,不能在其他文件使用。

4.define定义常量和宏

//define定义标识符常量
#define MAX 1000
//define定义宏
#define ADD(x, y) ((x)+(y))
#include <stdio.h>
int main()
{
    int sum = ADD(2, 3);
    printf("%d",MAX);//打印结果是1000,在这个程序中所有的MAX都会替换成1000
    printf("sum = %d\n", sum);//打印结果为5
    return 0;
 }

在宏里面是怎么实现这个算法的?

 经过预编译后

int sum = ADD(2, 3)已经被替换成int sum=((a)+(b))

然后就进行计算了。

这边先简单介绍一点皮毛,后续会再进行更深入的介绍。

5.指针

要学习指针,首先要了解内存的概念。

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1 个字节 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地

以32位系统、int类型为4字节即32个比特位为例。

在计算机中:

32位-32根地址线

地址线-1/0 要么是0要么是1

那一共多少种可能?

00000000000000000000000000000000

00000000000000000000000000000001

............

111111111111111111111111111111111111

一共2^{32}种可能

转换成10进制就是4294967296

除1024算出来是4,194,304Kb

除1024算出来是4096Mb

再除1024算出来是4GB,所以32位的电脑能做到4GB算是比较好的了。

以int类型变量为例

进行取地址操作时取出的是4个字节中第一个字节的地址,打印出的是完整地址。

5.1常见的格式符输出

%s-字符串

%c-字符

%d-有符号的整型

%f-单精度浮点数

%lf双精度浮点数

%p-地址的16进制表示形式

int a=10;

int * pa=&a;//变量名是pa,类型是int*

5.2*----解引用操作符(通过地址找到对象 )

int*中的*说明pa是个指针变量,int类型说明pa所指向的对象是int类型。

总而言之,指针变量是一种变量,这个变量是用来存放地址的。

5.3指针变量的大小

指针变量是用来存放地址的,地址的大小是4/8字节。

所以32位系统:指针大小是4个字节

       64位系统:指针大小是8个字节

6.结构体

结构体是 C 语言中特别重要的知识点,结构体使得 C 语言有能力描述复杂类型。
比如描述学生,,学生包含  名字+年龄+性别+学号 这几项信息。
例如

6.1结构体的定义和初始化

struct Point
{
 int x;
 int y; 
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初值。
struct Point p3 = {x, y};

struct Stu        //类型声明
{
 char name[15];//名字
 int age;      //年龄
};
struct Stu s = {"zhangsan", 20};//初始化

struct Node
{
 int data;
 struct Point p;
 struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化

struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

6.2结构体的声明

struct Stu //结构体类型声明,struct是结构体关键字
{
    char name[20];//名字
    int age;      //年龄
    char sex[5];  //性别
    char id[15]; //学号
}​b1,b2;//b1、b2是全局变量
typedef struct Stu
{
     char name[20];//名字
     int age;//年龄
     char sex[5];//性别
     char id[20];//学号
     //这些都是结构体成员,可以是标量、数组、指针,甚至是其他结构体。
}Stu;

这种写法是类型重定义,struct Stu是一个新的类型,可以简写成Stu。

6.3结构体成员的访问

结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。

struct S
{
	int a;
	char c;
	double d;
};
struct T
{
	struct S s;
	char name[20];
	int num;
};
int main()
{
	struct T t = { {100, 'w', 3.14}, "zhangsan", 200 };
	printf("%d %c %f %s %d\n", t.s.a, t.s.c, t.s.d, t.name, t.num);

	struct T* pt = &t;
	
	printf("%d %c %f %s %d\n", pt->s.a, pt->s.c, pt->s.d, pt->name, pt->num);

	return 0;
}

6.4结构体传参

struct S
{
 int data[1000];
 int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s) 
{
 printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps) 
{
 printf("%d\n", ps->num);
}
int main()
{
 print1(s);  //传结构体
 print2(&s); //传地址

 return 0; 
}

在这边传值调用和传址调用哪种更好呢?

答案是传址调用

原因是:

函数传参的时候,参数是需要压栈的。
如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
结论:
结构体传参的时候,要传结构体的地址。

本人水平有限,请大家批评指正!喜欢我就点个关注吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你帅你先说.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值