个人整理C语言笔记

 

C语言笔记

一.初始c语言

该程序的源文件如下: #include<stdio.h>//包含头文件 stdio.h,只有包含了该头文件,才能输出 intmain(void)//主函数,C 程序就是从这里开始运行的 { printf("HelloWorld!\n");//输出语句,双引号里面可以是任意的内容 return0; }

创建 C 程序项目小结: 1>选择 VisualC++,Win32 控制台 2>添加源文件.c,C++源文件.cpp,头文件.h 3>项目文件.sln

一、main 主函数

1.只能有一个主函数,必须要有一个主函数,C 程序从主函数开始运行。 2.intmain(void),int:返回值类型,main:函数名,void:参数

第 10 页 共 130 页

3.return0,返回值是 0。

二.、注释

 1.单行注释// 2.多行注释/**/ 注意:不能在多行注释中嵌套多行注释 注释一个函数时通常用多行注释,注释某个语句用单行注释

三、C 程序执行的过程:

8b7fe6a5334746e8854f3161336c13b0.png

 

 

编辑---写代码的过程,生成.c 文件 编译---检查语法错误的过程,生成.obj 文件 连接---多个.obj 文件合并成一个.exe 文件的过程 执行---运行.exe 文件的过程

四、C 程序的结构

 项目--->文件--->函数--->语句--->单词 项目:后缀是.sln 文件:源文件后缀是.c 函数:可以有多个函数,但一定要有主函数 语句:以分号;结尾 单词:不是单纯的英文单词,而是标识符,标识符又分成:关键字、预定义标识符、自定 义标识符。C 语言的标识符命名规范:由字母、数字、下划线构成且第一个字符不能是数 字,且不能是系统占用的单词。 练习:在程序中分别找出哪些是关键字、预定义标识符、自定义标识符?

第 11 页 共 130 页

------------------------------------PM------------------------------------八、进制的转换 在计算机内存储和运算数据时,通常要涉及到的数据单位有以下 3 种: 位(bit):计算机中的数据都是以二进制来表示的,二进制的代码只有“0” “1”两 个数码,采用多个数码(0 和 1 的组合)来表示一个数,其中的每一个数码称为一位,位 是计算机中最小的数据单位。 字节(Byte):在对二进制数据进行存储时,以 8 位二进制代码为一个单元存放在一 起,称为一个字节,即 1Byte=8bit。字节是计算机中信息组织和存储的基本单位,也是计 算机体系结构的基本单位。在计算机中,通常用 B(字节)、KB(千字节)、MB(兆字节) 或 GB(吉字节)为单位来表示存储器(如内存、硬盘、U 盘等)的存储容量或文件的大小。 字长:人们将计算机一次能够并行处理的二进制代码的位数,称为字长。字长是衡量 计算机性能的一个重要指标,字长越长,数据所包含的位数越多,计算机的数据处理速度 越快。计算机的字长通常是字节的整倍数,如 8 位、16 位、32 位、64 位和 128 位等。

1.内存容量 1TB--->1024GB 1GB--->1024MB 1MB--->1024KB 1KB--->1024Bbyte(字节) 1byte--->8bit(位)

数制是指用一组固定的符号和统一的规则来表示数值的方法。如下图所示为计算机中常用 的几种进位计数制的表示。

2.二进制与十进制的转换

1>将二进制数转换成十进制 10110 转换成十进制数:先将二进制数 10110 按位权展开,再对其乘积相加,转换过程 如下所示。 (10110)2=(1×24+0×23+1×22+1×21+0×20)10 =(16+4+2)10 =(22)10

8421 法(1286432168421) 10111101--->128+0+32+16+8+4+0+1=189

第 12 页 共 130 页

2>将十进制转换成二进制数 除以 2 逆向取余法:

37--->100101 3.二进制与八进制的转换 1>将八进制数转换成二进制:每 1 个八进制位转换成 3 个二进制位,左边不足三个的则补 0。 567--->101110111 234--->010011100

2>将二进制数转换成八进制:从右向左,每 3 个二进制位为一组,每一组转换成 1 个八进 制数。 011010111100110--->32746 011010111101110---32756 011101110101011---35653

4.二进制与十六进制的转换 1>将十六进制数转换成二进制:每 1 个十六进制位转换成 4 个二进制位,左边不足 4 个的则 补 0。 0----0000 1----0001 2----0010 3----0011 4----0100 5----0101 6----0110 7----0111 8----1000 9----1001 A----1010 10 B----1011 11 C----1100 12 D----1101 13 E----1110 14

F----1111 15

1289ADF--->0001001010001001101011011111

2>将二进制数转换成十六进制:从右向左,每 4 个 2 进制位为一组,每一组转换成 1 个十六 进制数。 11101101111110011110--->EDF9E 课堂练习: 1. 请问十进制数 89,二进制数 100111,八进制数 234,十六进制数 1A2 中哪个最大?

五、原码、反码、补码

源码、反码、补码数据在计算机里面都是以补码的形式存储。

原码 反码 补码 37:00100101--->00100101--->00100101 -37:10100101--->11011010--->11011011 正数的原码、反码、补码都是一样的! 负数的反码是在原码的基础上“符号位不变,数值位取反” 负数的补码是在反码的基础上“符号位不变,数值位加 1” 3-2=1 3+(-2)= -2:10000010---11111101---11111110 00000011 +11111110 =00000001 -2:1000000000000010 1111111111111101 1111111111111110

 

#include<stdio.h>

main()

{

pintf(“hello,world”);

}

各类数值型数据之间的混合运算

 

变量的数据类型是可以转换的。转换的方法有两种,一种

 

是自动转换,一种是强制转换。自动转换发生在不同数据

 

类型的量混合运算时,由编译系统自动完成。自动转换遵

 

循以下规则:

 

1)若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

 

2)转换按数据长度增加的方向进行,以保证精度不降低。如int型和

 

long型运算时,先把int量转成long型后再进行运算。

 

3)所有的浮点运算都是以双精度进行的,即使仅含float单精度量运

 

算的表达式,也要先转换成double型,再作运算。

 

4) char型和short型参与运算时,必须先转换成int型

符号解释

%d表示按整型数据的实际长度输出数据

 

%c用来输出一个字符。

 

%s用来输出一个字符串

 

%x表示以十六进制数形式输出整数

 

%f表示输出小数

 

 

 

&&:运算对象不为0则为真

 

int a = 5;int b = 10;a&&b为真,1为真,0为假

 

||较之&&基本相反,有一个为真就是真

 

 

 

sizeof(表达式)求表达式的数据类型占据的字节数

 

大括号括起来的都是复合语句(确信)

 

递归函数就是函数调用自己,这种情况:A调的B,然而B调用了A,这也算递归

 

作用域:一个代码空间,变量的使用范围

 

函数作用域:只在函数中使用、函数的参数和函数体属于函数作用域,函数的返回值和函数名属于文件作用域

 

文件作用域:定义在外面的,作用的范围是文件作用域,不过范围貌似是只延伸往下

 

结构体作用域:定义在外面是全局,定义在代码语句块里就在那里面

 

语句块作用域:复合语句里,内部的语句里面的作用域不可作用在外部

 

 作者:青色的霖 https://www.bilibili.com/read/cv21494965?spm_id_from=333.999.0.0&jump_opus=1 出处:bilibili

二:基本的数据类型

 

1,常量与变量

 

A:常量:

 

定义:不可以被改变的量

 

分类:

  1. 整型常量:整数
  2. 实型常量:
        1. 十进制小数形式:由数字和小数点组成
        2. 指数形式:由于没法区分上下标所以用字母e或E代表以十为底的指数e或E之前必须要有数字,后面必须为整数
  3. 字符常量:有两种形式的字符常量
        1. 普通字符常量:单引号括起来的一个字符,字符型在内存中存储的是ASCII码形式
        2. 转义字符:C语言中的特殊字符常量,是以字符\开头的字符序列,参考下图:
        3. 3acdad67ab414a5ba04406c8a1ae0161.png

         

  4. 字符串常数:例如“ABC”,用双引号把若干个字符括起来,字符串不包括双引号
  5. 符号常数:用#define指令代表一个常量。例如:#define PI 3.1415926 (末尾不用加分号),使用符号常量可以做到“一改全改”,注意:符号常量不是变量。
  6. 地址常量:每一个人常量、变量、数组的地址在程序运行期间是不能够改变的,成为地址产量

B:变量

 

定义:可以被改变的量。要存什么类型的数据就要用什么类型的定义。

变量代表一个有名字、具体特定属性的存储单元,可以存储数据,也就是一个盒子

变量必须先定义后使用

 

命名规范:见名知意,符合标识符命名规则(只能由字母、数字、下划线开头,不能是关键字,同一个作用域范围内定义的标识符不允许重名)

 

 

定义变量格式:;类型 变量名(标识符)

 

2,基本数据类型:

 

A:常用的六种基本数据类型:

整型:int

int HP=10//初始化

int age;

age=100;//赋值操作

 

字符型:char

占1个字节

单个字符:‘a’

多个字符:”avdg”

字符可以和数字之间转化的;ASCII码表

char ch=’a’;

ch=65;//’A’

int a;

a=ch;//隐示转换

ch=(int)ch;//强制转换

单精度浮点型:float

占四字节,精确到小数点后6—7位

 

 

双精度浮点型:double

占八字节,精确到小数点后16—17位

 

长整型:long

短整型:short

 

3,数据的输入与输出

 

A:输出

 

格式占位符: 将输入的数据转化为指定格式进行输出

printf(“格式占位符”,变量);

 

输出小数时,默认输出小数点后六位,不够则补零,超过则四舍五入。%.2f输出小数点后两位

字符输出:ch=getchar();从键盘上获取一个字符

 

B:输入

 

scanf:可视化输入

scanf(“变量1的类型的格式占位符,变量2的类型的格式占位符”,&变量1,&变量2)

字符输出putvhar(ch);

 

 


 

三:运算符和表达式

A:算术运算符

 

定义:用于算术运算的特殊符号

 

 

 

B,自增自减运算符

 

 

前缀:++a或--a  先自增或自减再运算

后缀:a++或a--  先运算再自增或自减

运算优先级:多个运算符时先计算优先级高的

 

 

 

 

C:关系运算符

 

 

 

D:逻辑运算符

 

 

逻辑与&&

逻辑或||

逻辑非!

 

E:条件运算符

 

 

 

条件运算符: 表达式1?表达式2;表达式3

表达式1的结果为真,执行表达式2,否则执行表达式3

#include<stdio.h>

Int main()

{

       Int a=10;

       Int b=2;

  1. b?a=11:b=11;

printf(“%d\n”,a);

}

 

 

F:赋值运算符

 

 

 

+=  -=  =  *=  /=  %=

 

G:逗号运算符和强制类型转换

 

 

 

H:位运算符

 

位运算符:输入十进制数,以二进制数的运算得到结果后,输出十进数

左移:<< 相当于乘以2的n次方,移几位就乘以2的几次方

右移:>> 相当于除以2的n次方,移几位就除以2的几次方

按位非(取反):~  二进制1变0,0变1  二进制数最高位表示符号位,0整数 1负数

 

按位或:|   对应位置,有1则为1,否则为0

5|3

5————0000 0101

3————0000 0011

0000 0111

7

按位与:& 对应位置,都为1,则为1,否则为0

5&3

5————0000 0101

3————0000 0011

                0000 0001

             1

按位异或:^ 相同位置,相同为0,不同为1 按住shift+6

5……3

5————0000 0101

3————0000 0011

                0000 0110————结果为6

sizeof();求类型大小的运算符

操作数:一个运算符要用到几个变量计算,比如两个变量计算则用双目运算符

 

表达式和C语句

 

 

 

 

 

 

 

 

 

 

 

 

 

四:循环与分支

 

选择分支结构

 

A:if选择分支结构

 

又名if判断语句

if(表达式)如果结果为真就执行语句,否则不执行

{

语句;

}

 

2.else if

 

if(表达式)如果表达式成立则执行语句1,否则执行语句2

{

语句1;

}

else否则

{

语句2;

}

 

if(表达式1)如果表达式1成立则执行语句1,如果表达式1成立且表达式2成立则执行语句2,否则执行语句3

{

语句1;

}

else  if(表达式2)

{

语句2;

}

else

{

语句3

}

 

注意:     如果a=12,一旦满足前面的某一个分支之后,后面所有分支不在判断,也不再执行,直接跳到分支语句的最后。

 

双目运算符

C=a>b?a:b;

如果a大于b执行a如果小于执行b

代码:

#include <stdio.h>

main()

{

         int a=20,b=10,c;

//      if(a>b)

//      {

//               c=a;

//      }

//      else

//      {

//               c=b;

//      }

//      printf("%d",c);

         c=a>b?a:b; //相当于上面的语句,简化成一句,这就是三目运算符的作用

         printf("%d",c);

 

B:switch多分支结构

 

 

 

Swinth(表达式)

{

         case 常量表达式:

      case 常量表达式:

         case 常量表达式:

         …….

         default:

         break;

}

  1. 直接进入case判断,判断哪个表达式的值和常量表达式相等
  2. 如果没有break,一但遇到满足条件的case之后,就会执行后面所有的语句

 

五.循环结构

 

1:for循环

 

 

for(表达式1;表达式2;表达式3;)

{

语句;

}

表达式1:条件的初始值

表达式2:判断条件

表达式3:判断的条件的值

 

第一步 执行表达式1,初始化语句,旨在循环开始的时候执行一次

第二步 执行表达式2,判断条件是否成立,执行循环体语句,否则退出循环

第三步 执行表达式3,在进行判断表达式2,执行循环体语句,否则执行表达式,执行表达式3

第四步 重复执行第二步和第三步

for 例题:

求1的乘积家2的乘积+3的乘积···+k的乘积(1+1*2+1*2*3+···*k)

代码:

#include <stdio.h>

main()

{

int i,k,sum=0,ret=1;

scanf(“%d”,&k);

for(i;i<=k;i++)

{

ret=ret+i;

sum+=ret;

}

      Printf(”%d”,sum);

return 0;

}

2:for语句的嵌套

#include<stdio.h>

main()

{

int i,j;

 

  

第一步:外面for循环满足,

第二步:执行循环里面的for循环且循环结束,然后接着往下输出

第三步:再次判断是否满足外面的for循环

第四步:重复上面的步骤

 

3:while循环

 

while(表达式)

{

语句;

}

表达式成立则执行语句,然后在判断表达式是否成立然后再执行

 

这个会无限输出无法停止是死循环是错误的

 

可以这样编写代码结束死循环

while(条件表达式)

{

      代码块:

}

  1. 首先判条件表达式是否成立,如果成立则执行代码块,否则退出循环。

 

注意!while(只能放条件表达式,不能加; )

例题:

用while求0~100之间所有数的和:

1.先分析:

  首先找到每一个数

Int a=0;

 while(a<=100)

{

 

}

2.将每一个数相加

Int a=0,b=0;

while(a<=100)

{

  b+=a; //就等于:0+1+2+3+4……

a++;

}

printf( “1~100相加的和为:%d”,b);

3.带入到c++为

 

 

 

4:do while循环

do//【强制执行一次,随后判断表达式,正确接着执行错误停止】

{

      代码块;

}while(条件表达式);

注意
这里的whule(条件表达式)后面加分号(;)

注意!这里的do while 是先执行后判断条件是否满足,如果满足则继续执行循环,如果不满足则推出循环

例题:

用do…while求0~100的和

代码:

int a=0,b=0;

do

{

         b+=a;

         a++;

}while(a<=100);//注意这里有分号!!!

         printf("1~100相加的和为:%d",b) ;

 

 

6.死循环

       这串代码会无限循环下面这几行代码导致死循环,所以慎用goto

a:

       printf(“###\n”);//标记

       goto b;

b:

       printf(“\n”);

              goto a

           //循环中的变量的使用:局部变量只能再当前for循环中进行使用

          

           for循环的变量只能在for循环中使用

           可以在for循环里使用上面的a(a=10)不能在for循环体外面使用a

5.跳转语句

 

 

for(int i=0;i<100;i++)

{

       if(i%2==0)//i是偶数

       {

 

continue;//跳过本次循环,从这里开始下面循环体不在执行,开始新一次的循环

}

printf(“%d\t”,i);

}

 

//goto

for(int i=0;i<10;i++)

{

       goto a;

       printf(“*\n”);

}

a:

       printf(“###\n”);//标记

       goto b;

b:

       printf(“\n”);

              goto a;

跳转例题:判断一个数是否为素数

代码:

#include <stdio.h>

main()

{

      int a,k,n;

      printf("输入一位自然数");

      scanf("%d",&k);

      for(a=2;a<k;a++)

      {

           if(k%a==0)

           {

                 n=1;

                 break;

           }

      }

      if(n==1)

      {

           printf("是素数");

      }

      else

      {

           printf("不是素数");

      }

      return 0;

}

 

 

六.一维数组

数组:是相同数据类型的集合。

从0开始

1为什么要有数组

如:现在要统计版里同学的年龄,如果用变量去储存,那么我们需要定义n个变量,定义和管理都很麻烦,这时候就可以用数组来做,就很方便

//普通变量

int a1,a2,a3….

//用数组,简单,快捷,方便。

int[45]

2数组的定义:

1.数据类型 数组名【数组大小】

2.数据类型:任意类型

3.数组名:合法标识符即可

4.数组大小:只能是常量

5.数组中的每个元素都由【】里面的数值决定

6.定义数组时[]里面的数不能为变量只能为常量

7.使用时[]里面的值可以是常量也可以是变量

8.数组数值不能整体操作

9.数组的每一个元素都是变量,可以被改变赋值

3数组的初始化

 

初始化类型

1.

int i;

int num[10]={1,2,3,4,5,6,7,8,9,10}’

for(i=0;i<10;i++)

{

Printf(“%d”,num[i]);

}

printf(“/n”);

 

2.

int i;

int num[10]={1,2}’

for(i=0;i<10;i++)

{

Printf(“%d”,num[i]);

printf(“/n”);

 

如果数组只初始部分值,则其他元素被初始化为0。

3.int i;

 i[10]={0};

将数组所有元素初始化为0.

4.

让地五个元素为5其他为0

代码

#include <stdio.h>

main()

{

       int i;

       int num[10]={[5]=5};

       for(i=0;i<10;i++)

              {

                     printf("%d ",num[i]);

              }

              printf("/n");

              return 0;

}

 

 

 

 

 

 

5.定义时没有告知是几个元素,这个是错误的

int num[];

6.如果定义时,[]中没有值,这个数组的值由{}里面的元素个数决定

int num[]={1,2,3};

 

 

4数组的大小

数组的大小=元素个数*每个元素大小

求数组大小

代码:

#include <stdio.h>

main()

{

         int i;

         int num[10]={1,2,3,4,5,6,7,8,9,10};

                   printf("%d ",sizeof(num));

                   printf("/n");

                   return 0;

}

 

 

求数组元素个数:

代码:

#include <stdio.h>

main()

{

         int num[10]={1,2,3,4,5,6,7,8,9,10};

         int i=sizeof(num)/sizeof(num[0]);//num[0]代表一个元素//int也代表一个元素

         printf("%d",i);

}

 

一共有十个元素

5数组在内存中的地址

数组在内存如和储存

启动一个程序,系统会给这个程序分配一块内存空间。

内存的最小单位是1个字节,每个字节都有每个编号,这个编号我们把它叫内存的地址

数据在内存中的地址,就是它在内存中的起始地址

6一维数组数组名

int a[5]

 

        

2.数组的地址和数组名

int a[10]

数组名a,等价于第0个元素的地址(首元素地址)

数组名是常量,不能被赋值

证明

#include <stdio.h>

main()

{

    int a[5];

         printf("%u\n",&a[0]);

         printf("%u\n",a);

         printf("%u\n",&a);//这三个相等

        

                

         printf("%u\n",&a[0]+1);//元素地址+1跨过一个元素

         printf("%u\n",a+1);//元素地址+1跨过一个元素

         printf("%u\n",&a+1);//整个数组的地址+1跨过整个数组

}

 

&a[0] 第0个元素的地址

&a    整个数组地址

7强化训练

求一个数组的最大值

#include <stdio.h>

main()

{

    //求数组最大值

    int a[10] = { 1,15,68,95,68,456,85,12,3,89};//最大值是456

    int max = a[0];//定义

    int i = 0;//初始化i

    for (i; i < 10; i++)//循环

    {

        if (max < a[i])//判断条件

            max = a[i];//判断结果

    }

    printf("%d", max);

    return 0;

}

 

 

8数组冒泡排序原理

将数组元素从小到大排列

冒泡:相邻两个元素比较,前面的比后面的大,两元素交换

 

一共有n个元素,一共比较n-1论=轮,没比较一轮,下一轮少比较一次

 

9数组冒泡代码的实现

代码:

#include <stdio.h>

main()

{

    int a[5] = { 1,5,6,3,-1 };

    int n = sizeof(a) / sizeof(a[0]);//求元素的多少

    int i = 0;

    for (i; i < n - 1; i++)

    {

        //因为每次比较的次数都要减1,刚好i每次加1,所以每一轮比较的次数是n-1-i

        for (int j = 0; j < n - 1; j++)//每一轮需要比较的次数

        {

            if (a[j] > a[j + 1])//如果前面的元素比后面的元素大,则交换位置

            {

                int t = a[j + 1];

                    a[j + 1] = a[j];

                    a[j] = t;

            }

        }

    }

    for (int i = 0; i < n; i++)

    {

        printf("%d ", a[i]);

    }

    printf("\n");

    return 0;

}

 

七.二维数组

1二维数组的定义与使用

二维数组定义的一般形式是:

 

类型说明符 数组名[常量表达式1][常量表达式2]

 

类型说明符 数组名[常量表达式1][常量表达式2]

其中常量表达式1表示第一维下标的长度,常量表达式2表示第二维下标的长度

 

  1. 二维数组在概念上是二维的,其下标在两个方向上变化,对其访问一般需要两个下标。
  2. 在内存中并不存在二维数组,二维数组实际的硬件存储器是连续编址的,也即是说内存中只有一维数组,即放完一行之后顺次放入第二行,和一维数组的存放方式是一样的。

 

C++ 代码:

#include <stdio.h>

main()

{

         int a[3][4]={0};

         int i;

         int j;

         for(i=0;i<3;i++)

         {

                   for(j=0;j<4;j++)

                   {

                            printf("%d ",a[i][j]);

                   }

                   printf("\n");

         }

}

 

二维数组每一个元素也是一种变量

//我想让第1行第三个成为‘3’让第2行第4个成为4.

从0开始。

2二维数组的初始化

和一维数组一样,给二维数组部分元素初始化,其余为0

a[3][4]一共有12个数三行四列

如果想让他们全部打印,需要用到循环实现

 

一维数组可以省略[]里面的数

二维只能省略行,列必须写:a[][3]这样可以

二维数组定义时,不能省略列的下标,可以省略行的下标

 

注意:更改行或者列的时候循环里面的数也要更改

9.scanf输入读取字符串

缺点:遇到空格就会提前结束读取,如果存放读取字符的空间不足,但他也会继续存放,会造成内存污染

\s 从键盘获取一个字符串遇到\n结束,或者遇到空格结束

 

 

3求二维数组的行和列

更改行和列的时候,循环里面也更改这样会显的很麻烦所以要查询行和列

 如何查询元素个数和行和列呢?

代码:

#include <stdio.h>

main()//求数组的行和列

{

    int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };

    int n = sizeof(a) / sizeof(a[0][0]);//求数组的个数

    int hang = sizeof(a) / sizeof(a[0]);//行的个数

    int lie = sizeof(a[0]) / sizeof(a[0][0]);//列的个数

    printf("数组个数为%d\n 行:%d\n 列:%d\n",n, hang, lie);

}

 

4.二维数组数组名

 

不懂看视频:https://www.bilibili.com/video/BV1ud4y1n7EF?t=450.8&p=68

5维数组地址验证

#include <stdio.h>

main()

{

    int a[2][3] = { 1,2,3,4,5,6, };

    printf("%u\n", &a[0][0]);

    printf("%u\n", a[0]);

    printf("%u\n", &a);

    printf("%u\n", a);

    printf("%u\n", &a);

    //前4个起始地址是一样的

    printf(" %u \n", &a[0][0]+1);

    printf(" %u \n", a[0]+1);

    printf(" %u \n", &a+1);

    printf(" %u \n", a+1);

    printf(" %u \n", &a+1);

    return 0;

}

 

6.了解多维数组

多维数组的意思是:2维以上就是多维

比如a[][][]就是多维数组

那如何来表示这个多维数组呢?

先来看看三维数组的初始化

以a[2][3][4]为例

Int a[2][3][4]={

{

{1,2,3}{1,2,3}{1,2,3}

}

{

{2,3,4}{4,5,6}{7,8,9}

}

}

如何打印三维数组

代码:

#include <stdio.h>

main()

{

    int num[2][3][4];//定义了一个三维数组意思是有两个二维数组,每个二维数组有三个一维数组,每个二维数组有4个元素

    for (int i = 0; i < 2; i++)

    {

        for (int k = 0; k < 3; k++)

        {

            for (int j = 0; j < 4; j++)

                printf("%d ", num[i][k][j]);

        }

    }

    return 0;

}

 

不管是几维数组都是相同的写法

7.字符数组

int a[10]这样的是int类型,是数组数组

char b[10]这样的是char类型是字符数组

#include <stdio.h>

main()

{

    //int a[10]这样的是int类型,是数组数组

    //char b[10]这样的是char类型是字符数组

    //字符数组的打印:

    char a[5] = { 'a','b','c','d','e' };

    for (int i = 0; i < 5; i++)

    {

        printf("%c", a[i]);

    }

    return 0;

}

 

如果打印部分char

 

后面是显示不出来的

 

字符数组显示不出来(显示不出来的是\0)但数值数组可以显示

#include <stdio.h>

main()

{

    //int a[10]这样的是int类型,是数组数组

    //char b[10]这样的是char类型是字符数组

    // 字符串就是字符数组中有\0字符的数组

    // 因为有\0字符的字符数组,操作起来更方便

    //字符数组的打印:

    char a[5] = "abcd";//定义了一个字符数组,存的是abcd\0

    char[]="worle"//一共有6个元素,多加个\0

    //char a[5] = { 'a','b','c' };

    char a[5] = { 'a','b','c','d','\0'};//字符数组中含有\0的,它也是字符串

    for (int i = 0; i < 5; i++)

    {

 

        printf("%c", a[i]);

    }  

    printf("\n");

    for (int i = 0; i < 5; i++)

    {

        printf("%d ", a[i]);

    }

 

    return 0;

}

 

 

 

8.字符数组初始化

0,\0,{}区别

 

#include <stdio.h>

main()

{

    char a[5] = { 'a','b','c','d','e' };//写法复杂,但简单

    char b[7] = "abcde\0";//这个写法更简便,遇到\0就不会在执行

    for (int i = 0; i < 5; i++)

    {

        printf("%c", a[i]);。

    }

    printf("\n");

    for (int j = 0; j < 5; j++)

    {

        printf("%c", b[j]);

    }

}

 

 

在内存里面0和\0是等价的

 

划横线的地方有乱码,原因是因为没有\0或0

 

\0最好不要跟一些数字,有可能几个数字连起来刚好是转义字符

//\012相当于\n

 

10.gets输入读取字符串

库函数,从键盘读取字符串

gets遇到\n结束,遇到空格继续读取空格

#include <stdio.h>

main()

{

    //gets遇到\n结束,遇到空格继续读取空格

    //gets也会造成内存污染

    char a[5] = "";

    gets(a);//里面的参数要的是存放读取字符串的地址

    printf("[%s]", a);

    return 0;

11.fgets读取字符串

库函数,从键盘读取字符串

#include <stdio.h>

main()

{

    char num[128]="";

    fgets(num, sizeof(num), stdin);//fgets从stdin(标准输入-键盘)读取字符串到"num"数组中,最大可以读sizeof(num)-1取决于你定义了多少数组

    printf("%s\n", num);

    return 0;

}

fgets标准写法:(定义的数组名,地址(sizeof(数组名)),固定写法:stdin);

 

遇到空格也会继续执行

sizeof(num)-1取决于你定义了多少数组

 

fgets会把回车键\n读取

如何将回车键\n去掉呢

11.strlen测有效字符数量

首先我们要知道回车键\n是在最后,但是我们不能删除\n,所以需要将\n替换成0或‘\0’

下面的代码是测有效的字符数量,我们要用他来将\n替换

#include <stdio.h>

main()

{

    char num[128] = "hhhh";

    int i;

    i = strlen(num);

    printf("%s\n%d", num, i);

}

 

如何替换

代码:

#include <stdio.h>

main()

{

    char num[128] = "";

    fgets(num, sizeof(num), stdin);

    num[strlen(num) - 1] = 0;//让最后面的\n=0

    printf("%s", num);

    return 0;

}

 

      12.字符数组的输出

#include <stdio.h>

main()

{

    char num[1024] = "llllll";

    printf("%s\n", num);//不光可以这样打印打印

    puts(num);//首元素地址,有换行,打印更简便

    fputs(num, stdout);//第一个参数,数组首元素地址,用stdout标准输出(屏幕)

}

 

13.字符串的追加(练习)

将 2中的追加到1中

#include <stdio.h>

main()

{

    char num1[128] = "hello";//hello123456

    char num2[128] = "123456";

    //将num2追加到num1中

    int i=0;

    while (num1[i] != 0)

    {

        i++;

    }

    int j = 0;

    while (num2[j] != 0)

    {

        num1[i] = num2[j];

        i++;

        j++;

    }

    puts(num1);

}

 

八.函数

1.概述:

         C语言要求,在程序中用到的所有函数,必须先定义在使用,例如用max函数去求两个数中的大者,必须事先按规范对他进行定义,指定他的名字,函数返回值类型、函数实现的功能以及参数的个数与类型,将这些信息通知编译系统。这样,在程序执行max时,编译系统就会按照定义所指定的功能执行。如果事先不定义,编译系统怎么知道max是什么,要实现什么功能呢!

定义函数应包括以下几个内容:

  1. 指定函数的名字,以便以后按名调用。
  2. 指定函数的类型,及函数返回值的类型。
  3. 指定函数的参数的名字和类型,以便在调用函数时向他们传递数据。对无参函数不需要这项。
  4. 指定函数应当完成什么操作,也就是函数是做什么的,及函数的功能。这是最重要的,在函数体中解决的。

C程序是由函数组成的,我们写的代码都是由主函数main()开始执行的。函数  函数是C程序的基本模块,是用于完成特定任务的程序代码单元。

 

2.分类

从函数定义角度来看,函数可分为系统函数和用户定义函数两种:

  1. 系统函数,及库函数这是由编译系统提供的,用户不必自己定义函数可以直接使用它们,比如我们长写的printf()。
  2. 用户自定义函数:用以解决用户的专门需要。
  1. 函数的作用
  1. 函数的使用可以省去重复代码的编写,降低代码重复率。
  2. 函数可以让程序更加模块化,从而有利于程序的阅读,修改和完善

 

4.函数的调用:产生随机数

当调用函数时,需要关系5要素:

  1. 头文件:包含指定文件。
  2. 函数名字:函数名字必须和头文件生命的名字一样。
  3. 功能:需要知道此函数能干吗之后才调用
  4. 参数:参数类型要匹配
  5. 返回值:根据需要接收返回值

 

5函数的名字、形参、函数体、返回值

a.函数名:

理论上是可以随便起的名字,最好的名字见名如意,应该让用户看到这个函数就知道函数的的作用和功能。但要注意,函数名后面带括号的(),代表这个函数表示普通变量

b.形参列表:

真实传给函数的参数,叫实参。

实参可以是:常量、变量、表达式、函数等。

无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形 参。 3.2 形式参数(形参):

形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内 存单

元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

 

在定义函数时指定的形参,在未出现函数调用时,他们并不占内存中的储存单元,因此称他们是形式参数说虚拟参数,简称形参,表示它们并不是实际存在的数据,所以,形参里的变量不能赋值。

 

在定义函数时指定的形参,必须是,类型加变量的形式:

 

第一个是对的

第二个只有类型,没有变量

第三个只有变量,没有类型

在定义函数时指定的形参,可有可无,根据函数的需要来设计,如果没有形参,圆括号内容为空,或写一个void关键字:

 

c.函数体

花括号{}里的内容即为函数体的内容,这里为函数功能  实现的过程,这和原来写代码没有什么区别,以前我们吧代码写在main()函数里,现在只是吧这些写在其他函数里

D.返回值

1.无参无返回值的调用

#include <stdio.h>

//函数的定义不能定义在函数的代码块里,必须在函数的外面定义函数

//符号加()代表这是一个函数

//如果定义的函数没有形参,可以不填,也可以写void,但是如果返回值没有,需要学void

// 函数{}里面的是函数体,所有代码必须放在{}里面

// 函数结束之前需要返回值

// 注意:返回值的类型看函数定义时,所需要的类型

//无参无返回值:

void fun()

{

    printf("hello,fun\n");

    printf("hello,main\n");

    return;

}

main()

{

    fun();

    return 0;

}

 

2.有参无返回值的定义和调用

#include <stdio.h>

//定义一个有参五返回值的函数

//函数定义时()小括号里面叫形参,(因为这个形参只是形式上的参数,定义函数时没有给形参开辟空间)

//形参只有被调用时才会分配空间

//形参的定义  类型名+变量名

void fun2(int a,int b)

{

    int c;

    c = a + b;

    printf("a+b=%d\n", c);

    return;

}

 

main()

{

    //函数调用有参函数时,不可以不传参

    //调用函数时,()里面的参数叫实参

    //实参的类型和形参的类型必须一致

    //函数调用时,实参的个数应和参数个数相同

    //实参为常量,可以为变量,可以为表达式

    int x = 3;

    int y = 4;

    fun2(2,3);//这个是int型的所以要填整数

    fun2(x,y);

    fun2(x+y,x*y);

}

 

3.有参数有返回值的调用

#include <stdio.h>

int fun3(int a,int b)//有形参

{

   return a + b;

}

int main()

{

   //调用有返回值函数时,可以不接返回值,也可以接返回值

   //注意!返回的类型是所接收返回值的变量类型也需要是相同

    //参数的传递,只能是单向传递(实参传给形参)

   int c = fun3(2,3);

   printf("a+b=%d", c);

   return 0;

实参传给形参,形参的值改变不会改变实参的值

以后如果实参是传变量本身,只会是值传递,不会吧变量本身的空间给传进去

 

   //参数的传递,只能是单向传递(实参传给形参)

  1. 函数的声明

如果使用用户自己定义的函数,而该函数与它是函数(即主函数)不在同一文件中,或者函数定义的位置在主函数之后,则必须在调用此函数之前对被调用的函数作声明。

所谓函数声明,就是在函数尚未在未定义的请况下,

 

return和 exit的区别

return 结束当前函数

如果return在子函数中调用指挥结束子函数,如果return在main()中,会结束整个程序

exit 是一个库函数,用来结束整个程序

不管exit在哪里调用,都会结束整个程序

exit(0)

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值