C语言学习--初始C语言03

语句

C语言的语句结构,从执行流程的角度可以划分出三种基本结构,顺序结构分支(选择)结构循环结构

顺序结构

顺序结构就是从上往下的顺序依次执行语句的结构。

#include <stdio.h>
int main()
{
    int a = 1;
    int b = 2;
    int c = 0;
    c = a;
    a = b;
    b = c;
    printf("a=%d b=%d\n",a,b );
    return 0;
}

在这里插入图片描述

分支(选择)结构

分支(选择)结构, 给定判断条件,根据判断条件的结果是否为真,来选择执行什么语句。

C语言中0代表false,一切的!0 代码true。

分类

  1. if语句
  2. if else 语句
  3. switch 语句
#include <stdio.h>
int main()
{
	int input = 0;
	printf("上学去\n");
	printf("你要好好学习吗?(1/0)>:");
	scanf("%d", &input); 
	if (input == 1) 条件式为 // if(true)---> 好offer
		printf("好offer\n");
	else                    // else --> 卖红薯
		printf("卖红薯\n");
	return 0;
}

循环结构

循环结构,依据判断条件来重复执行循环体内部的语句,为假时退出循环。

分类

  1. while 循环
  2. for 循环
  3. do while 循环
int  main()
{
	int line = 0;
	printf("加入我们");
	while (line < 20000)  
	{
		printf("敲""%d\n""代码\n", line);
		line++;
	}
	if(line >= 20000)
	   printf("好offer!~");
	return 0;
}

函数

函数是C语言的基本模块,一块独立的代码,可以将C程序看作由各种函数组成的。

函数分为两种: 库函数自定义函数

函数的功能要相对独立,即每个函数只完成自己特定的任务。

库函数

C语言提供给开发人员的函数,将常用功能的函数封装入库,供开发人员随时调用,提高了开发效率。

使用库函数需要引头文件。

上面经常用到的printf();和scanf();就是库函数。

printf()格式化打印函数,可以跟两个参数;

sancf()输入函数

#include <stdio.h> // 头文件 standard input and output 标准输入输出
int main()
{
    int a = 0;
    printf("请输入值:>"); // 调用函数,输出内容到标准输出
    scanf("%d",&a);      // 接收用户收入的十进制数,存放在a存放的地址所指向的那块内存区域。
    printf("%d\n",a);
    return 0;
}

自定义函数

为了开发人源自己封装的函数,用于完成不同的任务。

函数使用时需要调用函数。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
// 自定义函数
// 函数的返回类型  函数名 (para1, para2)
int Add(int x, int y) 
{
	int z = x + y; // 函数体
	return z; 
// 返回的z是整型,Add前面要写int
}
int main()
{
	int num1 = 10;
	int num2 = 30;
	int sum = 0;
	sum = Add(num1, num2); // 调用函数
	printf("sum = %d\n", sum);
	return 0;
}

数组

一组相同类型元素的集合

数组声明

int main()
{
    // 语法格式
    // 数据类型 变量名+[] ,[] 内部来设置数组内的元素个数。
    int arr[5];  // 数据中可以存放5个整形元素
    char str[5]; // 数组中可以存放5个字符元素
    // 注意 char数组和int数组 元素个数相同,数组大小不相同
    // 因为char类型占用的空间是1byte,而int占用的空间是4byte。
    printf("arr=%d str=%d",sizeof(arr),sizeof(str));
    // arr = 20 str = 5
    return 0;
}

在这里插入图片描述

数组初始化

  1. 整形数组在初始化时使用大括号{},每个元素用逗号分隔;
#include <stdio.h>
int main()
{
    int arr[10]= { 0,1,2,3,4,5,6,7,8,9 }; // 定义一个存放10个整型的数组
    char str1[] = {'a','b','c','d','e','f','\0'};
    char str2[] = "abcdef";    // 字符串数组在初始化时可以用""不加{};
    printf("str1 = %s, str2 = %s", str1,str2);
    // 结果相同
    return 0;
}

在这里插入图片描述

  1. 数组在初识化时 [] 中不指定元素个数,数组的元素个数由初始化的元素个数决定。
#include <stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5,6 };
    char str[] = "abcdef";
    // 计算元素个数的方法 sizeof(arr) / sizeof(arr[0]);
    int sz1 = sizeof(arr) / sizeof(arr[0]);
    int sz2 = sizeof(str) / sizeof(str[0]);
     printf("sz1 = %d, sz2 = %d\n", sz1,sz2);
    return 0;
}

在这里插入图片描述
3. 初始化的元素个数不能大于[]中的值。

int main()
{
    int arr[5] = {1,2,3,4,5,6};
    return 0;
}

在这里插入图片描述

数组下标

数组里每个值都有下标,从0开始,依次递增。

最后一个元素的下标 == 数组元素个数 - 1。

#include <stdio.h>
int main()
{
    int arr[10]= { 0,1,2,3,4,5,6,7,8,9 }; 
    printf("%d\n", arr[4]); // 第5个值 为4
    return 0;
}

在这里插入图片描述

打印数组

如果想打印数组只有通过循环的方式打印,字符数组可以通过%s来打印字符串。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    char str[] = "abcdef";
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    // 利用循环遍历数组
	for (i = 0; i < sz; i++)
	{
	    printf("%d ", arr[i]);
	}
    // %s 打印字符串
	printf("\n %s", str);
	return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y5RGTcRD-1623117829008)(C:\Users\joker\AppData\Roaming\Typora\typora-user-images\image-20210607111002796.png)]

操作符

算数操作符

// +  -  *  /  %
// 加 减 乘 除 取模
  1. 两个整形进行除法运算的得到是整数,即使用浮点型变量接收结果依然是整数
int main()
{

    double res = 5 / 2;
    printf("%lf\n", res);  //2.000000 商2余1

    return 0;
}

在这里插入图片描述

  1. 进行运算的两个数其中一个为浮点型,得到的也为浮点型。(前提接收结果的变量为浮点型)
int main()
{

    double res = 5 / 2.0;
    printf("%lf\n", res);

    return 0;
}

在这里插入图片描述

移位操作符

移二进制位,将数的二进制形式整体左移或者右移

移位操作符并不会改变变量本身的值,与算数操作符一致,a+1并不会改变a的值,除非a=a+1。

//  >> 右移  <<  左移   
int main()
{
	
	int a = 3;  
	// int 占 4byte = 32bit  
	// 所以 3  =  00000000000000000000000000000011;
	int b = a << 1; // 向左移1位
	// b = 00000000000000000000000000000110;
	// b = 6;  1*2^2 + 1*2^1 + 0*2^0 = 6
	int c = a << 2;
	// c = 00000000000000000000000000001100;
	// c = 12 
	printf("%d\n", b);  // 6
	printf("%d\n", c);  // 12
	printf("%d\n", a);  // 3 , a不变
    // 当对变量进行移位操作时,变量本身不变,除非将值再赋给原变量
	return 0;
}

位操作符

位操作符操作的是相同二进制位,将两个10进制数转换位2进制的形式,相同的每一位二进制数进行运算。

按位与&

两个二进制位都为1时结果为1,否则为0。
1 = 11 , 0 = 01 / 10 / 00 1=11,0=01/10/00 1=11,0=01/10/00

int main()
{
    int a = 8;
    int b = 10;
    int res = a&b;
    printf("%d\n", res); // 8
    return 0;
}

这里不把32位全部列出,因为是正整数,1的前面全部为0。

在这里插入图片描述

按位或 |

两个二进制位中至少存在一个1则结果为1,全0结果为0;
1 = 11 / 10 / 01 , 0 = 00 1=11/10/01,0=00 1=11/10/01,0=00

int main()
{
    // 按位或
    int a = 8;
    int b = 10;
    int res = a | b;
    printf("%d\n", res);  // 10 
    return 0;
}

在这里插入图片描述

按位异或^

两个二进制位不同时结果位1,相同时结果为0。
1 = 10 / 01 , 0 = 11 / 00 1=10/01,0=11/00 1=10/01,0=11/00

int main()
{

    // 按位异或
    int a = 8;
    int b = 10;
    int res = a ^ b;
    printf("%d\n", res); // 2
    return 0;

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVPGFCM6-1623117829011)(C:\Users\joker\AppData\Roaming\Typora\typora-user-images\image-20210607145017717.png)]

赋值操作符

赋值操作符作用
=将=右边得值赋给左边,与关系操作符 == 不同
复合赋值符
+=进行加运算,同时在赋值给原来的变量
-=进行减运算,同时在赋值给原来的变量
*=进行乘运算,同时在赋值给原来的变量
/=进行除运算,同时在赋值给原来的变量
&=进行按位与操作,同时在赋值给原来的变量
|=进行按位或操作,同时在赋值给原来的变量
^=进行按位异或操作,同时在赋值给原来的变量
>>=进行右移位操作,同时在赋值给原来的变量
<<=进行左移位操作,同时在赋值给原来的变量
// 例:
int main()
{
   int a = 10; // 创建变量时给变量赋值叫做初始化
   a = 20;     // = 赋值
   // 复合赋值符
   a += 10; // 等价于 a = a + 10;
   a -= 20; // 等价于 a = a - 20;
   a *= 20; // 等价于 a = a * 20;
   a /= 20; // 等价于 a = a / 20;
   a &= 2;  // 等价于 a = a & 2;
   a >>= 1; // 等价于 a = a >> 1;
   return 0;
}

单目操作符

单目操作符只有一个操作数

单目操作符作用
!逻辑反操作
-负值
+正值
&取地址
sizeof计算变量/类型所占空间的大小(以字节为单位)
~对一个数的二进制按位取反
前置、后置–
++前置、后置++
*间接访问操作符(解引用操作符)
(类型)强制类型转换

!逻辑反操作

取真值的相反值,C语言中 0 == False,一切的非0 ==true。

#include <stdio.h>
int main()
{
    int a = 10;
	printf("%d\n", !a); // 0
	// C语言中一切 0 = false 一切的!0 = true
	// a = 10 = true , 所以!a = false = 0;
    
    // !0 的固定返回值为1;
    int b = 0;
	printf("%d\n", !b);  // 1
    // b = 0 = false , !0 = 1 (固定值)
    
    return 0;
}

sizeof

计算变量或类型所占内存的大小,单位为byte

#include <stdio.h>
int main()
{
     printf("%d\n", sizeof(a))// 4  变量a 属于整型占4个字节
    printf("%d\n", sizeof(int))// 4 
    printf("%d\n", sizeof a )// 4 计算”变量“时可以省略括号
    printf("%d\n", sizeof int);    // int的括号不能省略会报错
    
    // sizeof 可以计算数组大小
    int arr[10] = {0};            // 创建了10个整型元素的数组
    printf("%d\n", sizeof arr);   // 40, 每个整型4 * 10
    
    //  计算数组的元素个数
	//  数组总大小 / 每个元素的大小
	int res = sizeof(arr) / sizeof(arr[0]);
	printf("%d\n", res);  // 10
    return 0;
}

~ 按位取反

  1. 对一个数的二进制数的每一位进行按位取反,1变0,0变1;
#include <stdio.h>
int main(){
	int a = 0;
	printf("%d\n", ~a);  // -1 
	return 0;
}
分析计算过程
原码,补码,反码的概念
  1. 计算机中存储的数组都是二进制数,而C语言中数值默认为有符号数值。即数值的二进制最高位为0时为正数,为1时为负数。其余二进制数为10进制数的绝对值。

  2. 有符号数的可以用原码、补码、反码的形式来表示。

    正数的原码=补码=反码

int main()
{
    int a = 10;
    // 原码 00000000000000000000000000001010 
    // 反码 00000000000000000000000000001010 
    // 补码 00000000000000000000000000001010 
    // 最高位的0表示正号
    return 0;
}

​ 负数的原码 = 十进制数的绝对值的二进制数,符号位为1;

​ 负数的反码 = 在原码的基础上符号位不变,其他位按位取反;

​ 负数的补码 = 负数的反码 + 1 ;

int main()
{
    int num = -10;
    // 原码 10000000000000000000000000001010
    // 反码 11111111111111111111111111110101  
    // 补码 11111111111111111111111111110110
    return 0;
}
  1. 内存中以补码的形式存储数值,计算时采用的也是补码,因此在计算时需要将得到得结果从补码转换为原码

    回看最上面的代码

#include <stdio.h>
int main(){
	int a = 0;
    // a 的值存储在内存中的补码:
    // 00000000000000000000000000000000
    // ~a 按位取反 得到补码,符号位为1是负数
    // 11111111111111111111111111111111
    // 转换为反码 
    // 11111111111111111111111111111110
    // 转换为原码
    // 10000000000000000000000000000001 = -1
	printf("%d\n", ~a);  // -1 
	return 0;
}

自增++自减–

前置++、前置–

先自运算,再使用

#include <stdio.h>
int main()
{
    int a = 2;
    int b = ++a; // 先自用算再使用
    printf("a=%d,b=%d\n",a, b);  // a = 3 b = 3 
     int c = --b;
    printf("b = %d, c = %d\n", b,c);  // b =2 c = 2
    return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hSYLcxsH-1623117829012)(C:\Users\joker\AppData\Roaming\Typora\typora-user-images\image-20210608082018493.png)]

在这里插入图片描述

后置++、后置–

先使用,再自运算

#include <stdio.h>
int main()
{

	int a = 2;
	int b = a++;
	printf("a=%d,b=%d\n", a, b);
	int c = b--;
	printf("b = %d, c = %d\n", b, c);
	return 0;
}

在这里插入图片描述

强制类型转换

#include <stdio.h>

int main()
{
    int dd = 3.14 // 给整型赋值浮点数会发出警告
    return 0;
}

在这里插入图片描述

使用强制类型转换 (类型),可以对操作数的类型进行强制转换。

int main()
{
	int dd = (int)3.14;
	printf("%d\n", dd);  // 3
	// 此时输出控制台不会报警告
     return 0;
}

关系操作符

比较操作符两边操作数的大小关系

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

逻辑符操作符

逻辑与 &&

逻辑与为真,当且仅当,被操作数全为真,否者为假

int main()
{
    int a = 3;
    int b = 5;
    if(3 == a && 5== b)  // 当 a == 3 b == 5 都为真时, 进入条件表达式
    {
       printf("逻辑与"); 
    }
    return 0;
}

逻辑或 ||

逻辑或为真,当且仅当被操作数至少有一个为真,被操作数全为假式,逻辑或结果为假

int main()
{
    int a = 4;
    int b = 5;
    int c = 1;
    if (3 == a || 5 == b)  // 当 a == 3 b == 5 至少有一个为真, 进入条件表达式
    {
        printf("逻辑或");
    }

    if (3 == a || 4 == b || 2 == c) // 全为假时逻辑或结果为假
    {

        printf("123");
    }  
    return 0;
}

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

条件操作符有三个操作数

exp1 ? exp2 : exp3 
// 表示 如果exp1 为真 返回exp2 否者返回 epx3
// Is exp1 true?  if exp1 is true then return exp2 else return exp3. 

逗号表达符

exp1, exp2, exp3, …expN // 逗号可以隔开一串表达式
    int main()
{
	int a = 0;
	int b = 3;
	int c = -1;
	int d = (a = b - 5, b = a + c, c = a + b, c -= 5);
	// 逗号表达式会从左向右依次计算
	// 整个逗号表达式的结果是最后一个表达式的结果
    printf("%d\n", a); // -10
	printf("%d\n", d); // -10
	return 0;
}

在这里插入图片描述

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

下标引用操作符[]

int main() 
{ 
    // [] 的操作数是变量名和[]里面的整型常量
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    //  下标从0开始:0,1,2,3,4,5,6,7,8,9  (元素对应的下标)
    arr[4];  //  5 访问下标为4的数组元素

    return 0;
}

函数调用操作符()

// ()  函数名和里面的参数为操作数
// 把实参的数据传给形参
int Add(int x,int y) // 声明函数 (para1,para2,...)  形式参数
{
    int z = 0;
    z = x + y;
    return z; // return的值 调用函数接收
}
int main() 
{
    int a = 10;
    int b = 20;
    int sum =  Add(a, b); // 调用函数,(para1,para2,...) 实际参数
}

常见关键字

在这里插入图片描述
下面介绍一些常见关键字的使用

auto

自动,在C语言用于自动变量

int main()

{// 进作用域
    auto int a = 10 // 局部变量a
    // 局部变量,进入作用域自动创建,出作用域自动销毁,所以也叫自动变量。
    // auto 被默认省略掉了,因为局部变量都是自动变量
    return 0;
}// 出作用域

register 寄存器关键字

计算机存储数据的位置,速度由快到慢,容量由大到小

寄存器–>高速缓存–> 内存 --> 硬盘

数据存储在硬盘中,cpu在调用数据时要依次从

硬盘–> 内存 --> 高速缓存 --> 寄存器 --> cpu

CPU先从寄存器提取数据,当寄存器拿不到数据再依次往下提取数据

int main ()
{
    // 给a定义为寄存器变量(建议),结果取决于编译器;
    register int a = 10; 
    return 0;
}

signed 与 unsigned

C语言中数值分为有符号位数(signed)和无符号位数(unsigned)

signed 二进制最高位表示正负 0 正 1负

unsigned 没有符号位,不存在正负之分

int main () 
{
     signed int a = -2; 
    // int 定义的变量是有符号的, + - 
    // signed 通常被省略掉
    
    unsigned int num = -10; // 无符号数,没有符号位,不存在正负之分
}

typedef 类型重命名

自定义类型名,方便下次调用

// 例如将无符号位类型重命名
typedef unsigned int u_int;
int main()
{
    u_int num = 20;
    printf("%d\n", 20);
    return 0;
}

static

static 用来修饰 局部变量全局变量函数
static在修饰未初始化的变量时,会给变量赋值为0。

static 修饰局部变量

局部变量得生命周期变长,但不会改变局部变量得作用域。

// 不使用static 修饰时
void test()
{// 进作用域 局部变量a创建 
    int a = 1; // 局部变量a 初始化为1
    a++;
    printf("%d ", a); 
    // 每次都是进入函数都是重新创建变量并初始化 
    // 因此打印结果为 2 2 2 2 2 
}// 出作用域 局部变量a销毁
int main()
{
    int i = 0;
    while(i<5)
    {
        test();
        i++;
    }
}
// 使用static 修饰局部变量时
void test()
{// 进作用域 局部变量a创建  
    static int a = 1; // 局部变量a 初始化为1,下次进来不会再重新初始化
    a++;  // 再上一次计算的结果上继续自增
    printf("%d ", a);  
    // 打印结果为 2 3 4 5 6
   
}// 出作用域时static改变了a的生命周期,不会被销毁,值会被保存,下次继续使用。
int main()
{
    int i = 0;
    while(i<5)
    {
        test();
        i++;
    }
}
static 修饰全局变量

全局变量默认存在外部链接属性,使用static修饰全局变量时,将全局变量的外部链接属性改编为内部链接属性,此时static修饰的全局变量只能再本源文件中使用。

// test01.c 源文件
static int global = 2021;
// test.c 源文件
extern int global; 
int main()
{
    printf("%d\n", global);
    return 0;
}

在这里插入图片描述

static 修饰函数

static 修饰函数与修饰全局变量相同,都是将其的外部链接属性改为内部链接属性,使得其只能在本源文件中使用。

// test01.c 源文件
static int Add(int x, int y)
{
	return x + y;
}
// test02.c 源文件
extern int Add(int, int);
int main()
{
    int a = 10;
    int b = 20;
    int c = Add(a, b);
    printf("%d\n", c);
    return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ywz8m9jx-1623117829016)(C:\Users\joker\AppData\Roaming\Typora\typora-user-images\image-20210608100008332.png)]

#define 定义常量和宏

定义标识符常量
// 语法格式, 不用加 = 
#define MAX 100; 
int main ()
{
    int a = MAX;
    printf("%d\n", a);
    return 0;
}
定义宏
// 函数的实现
int Max(int x, int y)
{
    int z = (x > y) ? x : y;
    return z;
}

// 宏的定义
#define MAX(X,Y) (X>Y?X:Y)

int main()
{
	int a = 10;
	int b = 20;
    // 函数方式
	int max = Max(a, b);
	printf("max = %d\n", max);
    
    // 宏的方式
    max = MAX(a,b);
    // 通过main函数上面宏的定义,这个表达式会变成
    // max = (a>b?a:b);
    printf("max = %d\n", max);
	return 0;
}
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值