初始C语言完结篇

目录

函数的初识

 数组的初识

操作符的简单介绍

常见关键字

初始C语言中的指针

结构体

结语



函数的初识

我们在数学中的函数可以表示为f(x)=2*x+5,C语言中的函数其实是很类似的f(x,y)=x+y;为了更加理解代码的意思我们将f换成Add,就变成了Add(x,y)=x+y。比如我们要计算两个数的和,首先我用非函数的方法为大家演示。

//这是用非函数的方法求俩个数的和
#include <stdio.h>
int main()
{
	
	int x = 0;
	int y = 0;
	scanf("%d%d", &x, &y);
	int r = x + y;
	printf("%d\n", r);
	return 0;

}

这个想必大家都能理解,下面讲解一下函数的使用

#include <stdio.h>
int Add(int x, int y)
{
	return x + y;   //返回两个数的和给Add函数
}
int main()
{
	
	int x = 0;
	int y = 0;
	scanf("%d%d", &x, &y);
	//int r = x + y;这里是注释
	int r = Add(x, y); 
	printf("%d\n", r);
	return 0;

}

想必大家看到这个还是一脸懵我将用画图的界面为大家解释。

 为了更加理解函数的概念,我给大家举个生活中的例子说明。我们当代大学生经常会让室友张三带饭,会给张三钱(x,y),张三这时候会问你带什么饭啊?多少钱的?也就是上面用上面类型来接收x和y,最后张三他们收了钱会把饭带回来把,就是用return 返回值,返回值的类型用函数前面的表示。通过这个例子想必大家都能理解函数大概是个什么东西了。这一串代码下来大家心里可能会有一个疑问?唉,用函数的方法计算比用普通的代码要写多上几行啊,为什么还要用函数写呢?这是因为啊函数定义后,接下来如果想让另外两个变量相加时,直接在Add中填写就行,而我们非函数的又得重复写一次加的过程。用函数只是看起来多了几行,其实在用的过程中会省去许多麻烦,现在大家心里的疑惑应该解除了把。接下来为大家介绍另一个概念数组。

 数组的初识

数组的定义:一组相同类型元素的集合

在c语言中要存储1~10的数字,怎么存储。

 另外还要给大家介绍另外一个概念,数组的下标。如果数组的元素是10个元素,那么他的下标范围是0~9

    int arr [ 10 ] 0000000000
         下标 0123456789

这里需要记住的是数组的下标是从0开始的,而不是1。下面简单介绍一下数组的使用,打印1~10的数字。

#include <stdio.h>
int main()
{
	int i = 0;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//完全初始化。
	//char arr [10] = {'a','b'};    //不完全初始化,差的元素用0补齐。
	for (i = 0; i <= 9; i++)
	{
		printf("%d\n", arr[i]);//通过循环从下标0开始找数组中的元素
	}
	printf("\n");//每打印一个数字换行
	return 0;
}

这里就是用数组先将1~10的数字存储起来,然后通过下标去找数组中的元素,并且将找到的元素输出到屏幕上。数组的初始就到这里,下面为大家简单介绍一下C语言中的操作符。

操作符的简单介绍

算术操作符

+  -     *    /     %

 这里前面4个加减乘除我就不多介绍了,大家都懂。后面这个操作符叫做模,模运算符就是取余数,并且使用模运算符时,只能用整数。给大家举个例子,比如:

15 % 7 = 1,这里的1就是模算出来的值,取余数嘛。

移位操作符

       

>>    <<

移位操作符,实际上移动的是二进制位。仍然举例子为大家说明:

 可以看到这里a用移位操作符向左移动一位之后,在把值赋给b,最后变为了4。这是为什么呢?

上面我们说了移位操作符实际上移动的是二进制位,2的2进制 1 ,0,1个整形是4个字节,1个字节是8个比特位,所以我们要将a的二进制补为32位,00000000 00000000 00000000 00000010。

当我们用移位操作符向左移动移位后就变为了            0000000   00000000 00000000 000000100

前面少了一个0,后面会补齐一个0,现在通过移位a的值变为了二进制的1 0 0对应的10进制为4。所以说最后b打印出来的值为4。这么说还是太抽象了我画图来为大家解释。

 通过画图想必大家都能大概明白移位操作符的意思了。接下讲解另一种。

位操作符

&      ^      |

&  按位与

|   按位或

^   按位异或

这里简单了解一下概念之后会为大家讲解。

赋值操作符

=      +=    -=     *=      /=     &=     ^=       |=    >>=       <<=

这里简单介绍几种

#include <stdio.h>
int main()
{
	int a = 2;
	a = a + 5;
	//等价于
	a += 5;
	a = a % 2;
	//等价于
	a %= 2;
	return 0;
}

单目操作符

!           逻辑反操作

-           负值

+           正值

&           取地址

sizeof      操作数的类型长度(以字节为单位)

~           对一个数的二进制按位取反

--          前置、后置--

++          前置、后置++

*           间接访问操作符(解引用操作符)

(类型)       强制类型转换

上面为什么称为单目操作符呢 ?因为每个操作符后面或者前面只有一个操作数,像a+b中的+号两边都有数字称为双目操作符。下面还是简单给大家讲解其中的几个操作符

首先介绍一下!(逻辑反操作符) 在语言中规定0表示假,非0表示真。可以看到这里的逻辑反操作符的作用将原本a = 3的值变为了0。他的作用就是将假的变为真,真的反操作成假。

接下来介绍一下sizeof ,首先我们需要明白sizeof是一个操作符不是函数,概念别弄混淆了,sizeof是用来计算操作数的类型长度的,举例子为大家说明。

#include <stdio.h>
int main()
{
	
	int a = 3;
	int arr[10] = { 0 };
	printf("%zd\n", sizeof(a));//计算a类型的大小
	printf("%zd\n", sizeof(arr));//计算arr数组的大小
	return 0;
}

因为一个整形的大小是4个字节,所以第一个sizeof所计算的值应该是4,arr数组中有10个元素,每个元素的类型为整形,所以他的大小应该应该为40。为了验证我们的猜想,我们运行一下看看,

 可以看到我们的理解是没有问题的,这就是sizeof的使用。接下来将一下~(按位取反)的使用

 我们这里对0取反的意思和!操作符不同,这里的取反是对0二进制位的取反。取反后他的二进制就变成了 11111111 11111111 11111111 11111111,32个1。这里就要引入一个概念了,一个二进制的表现形式有三种,原码,反码,和补码。整数在内存中存储的是补码。正整数的原码,反码,补码都相同。这里取反后,我们得到的最高位是1所以他是负数,由于整数在内存中存储的是补码,我们上面用%d输出要打印的是原码,我们这时候就需要对补码进行转换。

 这里就是转换的过程,这个时候%d输出出来的原码二进制所对应的值就是-1。讲到这里大家应该理解~操作符的意思了把。

接下来介绍一下前置++,与后置++的区别,依然是上图带领大家认识。

 通过前置++与后置++的的类别,想必大家应该能理解前置和后置的区别了。

最后为大家介绍单目操作符的最后一种(类型)       强制类型转换,

#include <stdio.h>
int main()
{
	int a = (int)3.14;//这里是把3.14强制转化为整形
	printf("%d\n",a);
	return 0;
}

&&       逻辑与

||          逻辑或

这里逻辑与(&& )就是并且的意思,比如桌子太重,我让张三李四一起去搬桌子,少一个人搬不动,必须全部满足才为真。逻辑或(||  )就是或者的意思,比如去搬凳子,张三李四去一个就行,满足一个条件就为真。下面用类比来给大家看逻辑与的对比

 通过上面两张图的对比,大家应该可以认识逻辑与(&&)并且的概念。下面给大家上图来认识逻辑或(||  )的区分。

逻辑或就是或者的意思,其中只要有一个满足条件就执行后面的语句,如果都不满足就执行else后面的语句。 

常见关键字

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

下面先给大家介绍几种关键字,其他的在之后的文章中讲解。

关键字register

registe其实就是寄存器,为了让大家理解呢,需要先了解电脑上的存储设备有哪些,我们对内存中熟悉的就是电脑上的硬盘嘛,还有内存,内存之上是高速缓存(cache)高速缓存之上就是我们的寄存器了。越往上去运行的速度越快,空间越小,造价越贵。

 寄存器在代码中是如何使用的呢,

int main()
{
	//寄存器变量
	register int num = 3;//建议把3存放在寄存器中。
	return 0;
}

注意这里只是建议把3放在寄存器中,而不是直接直接放进去。

关键字typedef

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

#include <stdio.h>
//将unsigned int 重命名为uint_11, 所以uint_32也是一个类型名
typedef unsigned int utf_11;
int main()
{
	 unsigned int num1 = 50;
	 utf_11 num2 = 50;
	 printf("%d\n", num1);
	 printf("%d\n", num2);
	return 0;
}
//输出的结果都为50

 可以观察到这里是unsigned int重命名为utf_11,然后分别用来定义num1和num2,最后输出的结果都是一样,在遇到这种复杂的数据类型时我可以用关键字typedef,使我们书写更加方便,快捷。

关键字static

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

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

 这是今天的重头戏,我将花费一定的篇幅来为大家分别从上面三个方面去讲解。先讲解一下当static修饰静态局部变量

 通过上述图片我们发现,static修饰的局部变量的值从原来的全是2变为了2~11的数字,这是为什么呢?这里需要给大家普及一个概念大家才能懂,static修饰局部变量,改变了变量的生命周期(本质上是改变的变量的存储类型)。

内存实际上分为三个区域栈区,堆区,静态区。栈区一般存储的是局部变量和函数的参数,堆区里其实存放的是动态内存的分配,静态区里存放的是全局变量和static修饰的静态变量。可以看到全局变量是存放在静态区的,说明静态区里的生命周期是很长的。当我们用static局部变量后他就到了静态区,他的生命周期也就随之延长。局部变量的特点是进入这个函数内创建,出范围后销毁。所以这里每次a++打印之后,出去函数范围时都会销毁。而当我们用static修饰修饰的局部变量,他出了局部范围后是不会销毁的,所以的他的值会保留下来每次都+1,直接下面的循环结束不在调用test函数为止。

static修饰静态全局变量

 可以观察到这里通过另外add.c源文件定义的变量sz_dw输出了2022的值,全部变量使用前需要用extern声明全局变量的类型和变量的名称。而我们一旦使用static去修饰全局变量会发生什么变化呢?

 可以看到这里使用static修饰全局变量后,我们找不到sz_dw变量。这是因为全局变量具有外部链接属性,所以才能在其他源文件内部使用。static修饰全局变量后,就变成了内部链接属性其他源文件就不能链接到这个静态的全局变量了。所以static修饰的静态全局变量只能在自己的源文件内部使用。static修饰函数时,使得函数只能在自己所在源文件内部使用,不能在其他源文件内部使用,本质上和全局变量类似,将函数的外部链接属性变成了内部链接属性。

初始C语言中的指针

想要理解指针就必须先了解内存的概念,内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。这里就是内存的概念,变量是创建在内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。

这里向内存中分配4个地址,来存储10.这里第一个字节的地址其实就是a的地址。每个内存单元都是有编号的,这个编号其实就是他的地址,地址也就是指针。

 这里可以怎么理解呢,先取出a的地址然后用p存起来,p前面给的*代表他是一个指针变量,int代表的是p指向的a的类型,这里a是整形所以是int。下面还是画图加深理解

 看到这张图后,想必大家更能理解什么是指针了,我们生活中也会记录下朋友啊,亲戚啊,甚至是上课的地址,而我们记下这些地址是为了什么呢?是为了将来我们能通过这个地址找到相应的地方,去串门或者上课。这里也一样,当我们把a的地址存放到p时,我们可以用*p解引用操作去找到我们想去的地方,也就是a嘛。

int main()
{
	int a = 10;
	//&a;//取地址a就是取地址操作符
	//printf("%p\n", &a);//000000A2B66FF784
	int* p = &a;
	//p就是指针变量
	*p = 20;//解引用操作符,意思就是通过p存放的地址,找到p所指向的对象,也就是a嘛
	printf("%d\n", a);

	return 0;
}

当我们通过解引用操作符找到a后把20的值赋值给他,然后打印来验证我们通过*p找到a没有,如果值a的值为20那么找到了,如果还是原来的10说明没找到。下面放调试结果

通过调试结果我们发现,通过解引用操作*p找到了他所指向的a。当我们有了指针的概念后呢,带领大家来认识一下指针变量的大小

  1. 指针变量的大小取决于地址的大小
  2. 32位平台下地址是32个比特位(即4个字节)
  3. 64位平台下地址是64个比特位(即8个字节)

 结论,指针变量在32位系统上的大小是4个字节,在64位系统上的大小是8个字节。讲到这里指针的概念大家应该有个基本了解,这只是初始C语言我们就不深入下去了。

结构体

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

在C语言中自带的char double int long 这些类型没办法去描述人:名字+年龄+性别+电话+地址,书:书名+作者+出版社+定价+书号,这些复杂的类型类型。这时候C语言就给了自定义类型的能力

自定义类型中有一种叫:结构体,结构体的关键字就叫做struct。结构体其实是把一些单一类型组合在一起。下面用代码演示

/这里描述一个学生的结构体
struct Stu
{
	//成员
	char name[20];
	int age;
	char sex[10];
	char tele[12];
};
int main()
{
	struct Stu s = { "lisi","20","nan","1558666674" };
	printf("%s %d %s %s", s.name, s.age, s.sex, s.tele);//这里是在 变量s中找成员
	return 0;
}

这里的struct Stu其实等价与int,他们后面跟的都是变量,struct Stu s其实是创建了一个变量,将数据放入成员中。另外,在输出我们用到了 . 操作符,意思是在创建的变量s中找name的值,其他的依此类推。

结语

本次关于初始C语言的内容就结束了,今后会持续和大家分享关于C语言方面的学习心得,以及一些小知识点的讲解,另外由于编者水平有限,难免在码字时有所纰漏,希望广大网友指正。另外码字不易,如果写的内容对你有所帮助的话,可以一键三连哦!这对我的帮助很大!很大!很大!重要的事情说三遍,哈哈哈。本次的介绍就到这里,下次再见。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值