C语言学习笔记(一)

一、基础知识

第一个C语言程序,打印helloworld

#include <stdio.h>
#include <stdlib.h>
int main()
{
	printf("Helllo world!\n");
	system("pause");
	return 0;
}

制作程序的流程:

  1. 编写源代码
  2. 编译前,进行预处理
  3. 编译,生成.obj文件
  4. 链接,生成可执行文件(如.exe)
  5. 生成目标程序,可以运行

一段代码基本构成:

  1. main函数
  2. 预处理
  3. 库函数
  4. 关键字
  5. 注释

预处理:以#号开头的命令
库函数:如printf/system等已经实现具体功能的函数,要使用库函数,必须包含头文件

  • printf函数–<stdio.h>
  • system函数–<stdlib.h>
  • 百度 函数名 头文件 查看函数所属头文件

关键字:

变量定义类型定义分支选择循环控制转移控制修饰关键字
charenumifforcontinueunsigned
wchar_tunionelse ifwhilebreakconst
intstructswitch-casedo-whilegotostatic

注释:

  • 单行注释://
  • 多行注释:/**/

注意事项:

  1. 运行程序:找到控制台所在文件夹,按住shift,选择打开Powershell,输入文件名 “.\001.exe”回车运行
  2. VS编译程序:
    2.1 文件必须在项目里运行
    2.2 #include “pch.h” /*VS2017强制要求在每个.c文件加这一句,也叫编译预处理*/

二、数据类型

基本数据类型:整型、浮点型、字符型
数据:常量与变量
C语言中:字符常量'A' 用单引号,字符串常量"abc" 用双引号

  • 变量定义
  1. 变量类型选择:一般char、int、double
  2. 变量名定义:命名规范:小写字母开头(小写字母通常是这个变量的类型简写),然后以一个单词作为变量的名字(多个单词之间首字母应大写)
  int nNum;char cCh;double dNum;
  • 变量初始化
    1. int nNum = 0;//定义并初始化
    2. int nNum; nNum = 0; //此处不是初始化,只能叫赋值
  • 变量赋值
    1. 变量数值交换 temp=a; a=b; b=c
    2. 不使用中间变量:
// 方式一: 
		x=x+y          //x =3 + 6 ;x =9
  		y=x-y         //y=9 - 6; y = 3
        x= x-y         //x=9 - 3; x = 6
        // 两个数相加时,有可能超出int表示范围,不推荐
//方式二:  
	    x = x^y         // x= 3^6
		y = x^y         // y=(3^6)^6; y = 3
        x = x^y         // x=(3^6)^3; x = 6    

标识符:编程时,有许多要命名的对象,比如函数名、变量名等,这些名称都叫做标识符。标识符的命名规则:
4. 只能由数字(0-9)、字母(a-z,A-Z)和下划线组成
5. 数字不能开头
6. 不能使用关键字
7. C语言标识符区分大小写

为了使我们定义的变量名清晰规范有含义,建议使用匈牙利命名法匈牙利命名法

三、输入输出函数

函数名功能
printf格式化输出数据到屏幕
scanf格式化输入数据
puchar输出一个字符到屏幕
getchar从键盘获取一个字符
_getch无回显的从键盘获取一个字符
puts输入一行字符串到屏幕
gets从键盘获取一行字符串

当然,这是一些基本的功能描述,有些细节的地方建议阅读《C Primer Plus》,比如输入字符串计算机怎么判断输入结束,getchar只获取一个字符,那么回车怎么处理等等问题

  • scanf遇到空格会结束输入
  • scanf_s("",参数列表)
    安全版函数针对%c和%s做了一定改进
    在接收字符或字符串时,需要在参数列表额外提供一个数值类表示缓冲区的最大字节数
  • printf("",参数列表)
    功能:格式化输出数据到屏幕
char arr[10]={0};
char *p = arr;

printf("%s",p); //等价 printf("%s",arr)
printf("%s", *p);  //等价printf("%s",arr[0])

int *p = 0;
char *pp = 0;
printf("%d",*p);
printf("%s", pp);
  • getchar()
    功能:从键盘输入一个字符
    返回值:返回输入字符的ASCⅡ码
    说明:在屏幕输入一串字符,直到遇到回车结束输入,但函数只接收第一个字符
  • putchar()
    功能:从终端输出一个函数,且转换成ASCⅡ码返回
    函数原型:int putchar(int c)
    函数参数:c为要输出的字符,可以是字符型常量、字符型变量、整型常量、整型变量表达式、转义序列等
  • _getch()
    功能:无回显字符输入函数
    函数原型:int _getchar(void)
    说明:不需要每次输入完成后输入回车表示结束,只要有键按下就会直接返回,并且不会在屏幕上显示
    包含头文件:#include <conio.h>
  • gets_s(szBuff, sizeof(szBuff))
    功能:从控制台接收带空格的字符串

格式字符:

控制符说明
%d十进制
%o八进制
%x,X十六进制(大小写输出)
%uint类型,无符号十进制
%c字符型输出
%s字符串输出
%ffloat输出
%lfdouble输出
%p打印内存地址
%%打印%

转义字符:

转义字符含义ASCII码 16/10进制
\0空字符(NULL)0/0
\n换行符(LF)0x0A/10
\r回车符 (CR)0x0D/13
\t水平制表符(HT)0x09/9
\v垂直制表符(VT)0x0B/11
\a响铃(BEL)0x07/7
\b退格符(BS)0x08/8
\f换页符(FF)0x0C/12
\ ‘单引号0x27/39
\ "双引号0x22/34
\ \反斜杠0x5C/92

四、运算符

单目运算符是指运算所需变量为一个的运算符,即在运算当中只有一个操作数,又叫一元运算符,其中有逻辑非运算符:!、按位取反运算符:~、自增自减运算符:++, --等。
双目运算符是指运算所需变量为两个的运算符,例如+,-,*,/,%,<,>,>=,<=,==,!=,<<,>>,&,^,|,&&,||,=
三目运算符是指运算所需变量为三个的运算符,只有条件表达式【?:】
一般不会见到,说一个不常见的:
,逗号运算符一般没有太大的效果,通常起到一个分割符的作用。特点:

  1. 优先级最低
  2. 逗号表达式的值是最右边的值
int nNum=0;
nNum = 12,13,14,15;		//nNum=12
nNum = (12,13,14,15);	//nNum=15

更多详细信息可以参考:C语言运算符运算符示例程序

表达式:C语言中的表达式是若干个运算符和数据合在一起的算式。
语句:语句是C语言程序的基本组成,语句的结尾用;分号标识,一个表达式加上一个分号就是一个语句。多个语句使用{}括起来就是符合语句(程序块)

类型转换

  1. 自动类型转换
int nNum;
char cCh1;
//小字节赋值到大字节变量
nNum = 'A';
/*将char类型数据赋值给int类型变量,将1字节填充到4字节空间,c语言编译器会将1字节数据扩充为4字节,然后存储,这种转换为隐式转换*/
nNum = 0x12345678;
cCh1 = nNum;
/*将int类型数据赋值给char类型变量,将4字节填充到1字节空间,c语言编译器会将4字节截断为1字节,然后再存储到1字节变量cCh1中,这个过程实际就是将int类型隐式转换为char型,int类型在转换过程中丢失了部分数据,cCh1 = 0x78*/
  1. 强制类型转换
    格式:(变量类型)变量
float a=13.44;
int nNum=(int)a;	//将float类型强制转为int型

五、一维数组

数组的定义

  1. 数据类型 数组名[数组长度]
  2. 数组长度只能是常量和常量表达式(大于0),不能是变量

数组的初始化

// 1.整体赋值
int arr1[5] = {1,2,3,4,5};
// 2.部分赋值
int arr2[5] = {1,2,3};       	//还有最后两个元素为0
// 3.不给定数组长度,根据数组实际元素个数分配
int arr3[] = {1,2,3456};   //6个元素,分配24字节空间

// 常见错误情况
int arr4[];	//没有初始化时,数组长度不能省略
int arr5[nNum];	//数组长度必须是常量,不能是变量
arr1=arr2;	//数组不能整体赋值
arr6[] = {1,2,3456};//数组不能整体赋值

数组的访问

数组可以通过下标来访问某一元素,下标是具有整数值的表达式,也就是说下标可以是:

  1. 常量
  2. 变量
  3. 整数值的表达式

数组的存储

  1. 数组在内存中的存储是连续的
  2. 数组名就是数组的起始地址,它是一个常量。
  3. 数组下标从0开始,最大下标(元素个数-1)

数组的输入输出

  1. 在C语言中,数组是无法直接打印出来的
  2. 在C语言只有基本数据类型的值才能打印
  3. 数组是由基本数据类型组成,化整为零依次打印
//和变量的使用方式基本一致
printf("%d %d %d",arr[1],arr[2],arr[3]);
scanf_s("%d %d %d",&arr[1],&arr[2],&arr[3]);

数组的越界问题

刚开始学C语言的时候,编译不报错,但是程序经常崩溃,一般是数组越界导致的。

int nArr[10]={0};	//定义一个有10个元素的数组
nArr[11]=10;	//可以赋值吗?答案是可以的,这样会破坏内存原来的数组,导致程序间歇性不稳定

字符数组的初始化方式

char arr1[] = {'H','e','l','l','o'};    //正常用法
char arr2[] = "Hello"       //字符数组的特殊用法
/* c语言中每一个常量字符串都额外带有一个特殊字符串结束符“\0”
printf("%d %d\n", sizeof(arr1), sizeof(arr2));  // arr1 长度5   arr2  长度6
//sizeof()计算的是整个数组占用的内存空间字节数
//stelen()计算的是字符串的长度,不包括`\0`
//_countof()计算数组元素个数

字符数组的存储

  1. 数组的最大下标缺省后,其最大元素个数由初始值个数决定
  2. 数组的元素个数一旦定义,其最大元素个数不会有变化

字符数组的输入输出

char arr1[] = {'H','e','l','l','o'};    //正常用法
char arr2[] = "Hello"       			//字符数组的特殊用法
//字符串打印是以`\0`结尾的
printf("%s\n", arr1);       //字符数组可以用%s直接输出,不会正确打印,会多打印一部分内存中的随机值,直到遇到`\0`结束
printf("%s\n", arr2);		// 正确打印
scanf_s("%s\n", arr1, sizeof(arr1)); //安全版函数

注意:\0的ASCII码值是0,而字符0的ASCII码值是0x30

字符串操作函数
这一系列字符串函数,都是库函数,头文件<string.h>,都有相同的前缀str

函数名作用
strlen求字符串长度
strcpy/strcpy_s字符串拷贝函数
strcmp字符串比较函数
strcat/strrcat_s字符串拼接函数
strstr字符串查找函数
sprintf格式化数字转字符串
sscanf_s格式化字符串转数字

示例程序:

//strlen求字符串的长度,只检测0,即'\0'
	   char cChar1[11] = "Hello";
       char cChar2[20] = "Hello";
       char cChar3[20] = "World";
       //字符数组
       printf("%d %d\n", sizeof(arr1), sizeof(arr2));
       printf("%s\n", arr1);
       printf("%s\n", arr2);
       //字符串操作函数
       cChar3[5] = 0;    //'\0'
       //sizeof()和strlen()的区别
       printf("%d %d\n", sizeof(cChar1), sizeof(cChar2));
       printf("%d\n", strlen(cChar1));
       //cChar2[3] = 0;
       printf("%d\n", strlen(cChar2));   //strlrn只检测0
       //strcpy函数
       //strcpy(cChar2, cChar3);
       strcpy_s(cChar2,   //目标字符串
            sizeof(cChar2), 
            cChar3);    //源字符串
       printf("%s\n", cChar2);

六、三大结构

一个程序包含对数据的描述和对数据处理的描述,即数据结构和算法。
算法是为解决一个问题而采取的方法和步骤,无论简单还是复杂的算法,都由以下三大结构构成:

  1. 顺序结构
  2. 选择结构
  3. 循环结构

顺序结构
最为简单,就是从上至下,一条一条语句执行
选择结构
选择结构,就是当满足一定条件时执行某一段语句。

  1. if-else
    二义性:在多重嵌套中,else总是和在它之前出现的、尚未匹配的且离它最近的if相匹配

    1. 使用if结构可以实现复杂的逻辑判断
    2. 用switch结构能够实现的结构,使用if结构都可以实现
    3. 分支较少的情况使用if结构更简单
    4. 分支较多的情况下使用if结构会使程序结构变得更复杂
    5. 如果if嵌套层次过深,也容易使程序结构变得复杂
  2. switch-case
    使用case进行语句时,case的条件只能是常量或者常量表达式

    1. 没有复杂的逻辑判断,程序结构简单
    2. 对于分支很多的情况,特别适合
    3. switch结构只能基于一个整数值进行分支选择
    4. switch只能判断是否相等,不能判断在某一区间的值
    5. 虽然使用switch语句编写的程序有规律,可读性强,但是由于switch语句不能根据表达式的取值范围做出选择,所以使用时也有很大的局限性。

循环结构
判断条件满足,重复执行某一段语句。

  1. for循环
  2. while循环
  3. do-while循环
  • continue语句只能用于循环语句中, 作用是跳出本次循环, 执行下一次循环.而
  • break语句用在循环语句中, 作用是跳出循环, 执行后面的语句. 用在switch语句中, 作用是跳出switch语句, 执行后面的语句. 如果将switch语句中每个case中的break注释掉, 则switch中的所有语句都被执行

七、二维数组

二维数组的定义
格式:类型说明符 数组名[常量表达式1][常量表达式2];
二维数组的初始化

// 1.整体初始化
int arr[2][3]={1,5,6};
// 2.分行初始化
int arr[2][3]={{1},{5,6}};
// 3.全部初始化
int arr[][3]={ 1,2,3,4,5,6}; //数组第一维可以不指定,第二维长度不能缺省

二维数组的输入输出
原则:

  1. 在C语言中,只有基本数据类型(char,int,double)能通过printf输出,scanf输入,数组不能直接输入输出
  2. 数组的输入输出是数组元素的输入输出

二维字符数组的使用

  1. 初始化(如果使用常量字符串来初始化,数组大小要比字符个数多一位,常量字符串包含"\0")
  2. 输入输出:可以使用“\s”格式符直接输入输出字符数组
  3. 二维数组不能直接赋值,但字符数组可以使用strcpy进行拷贝
//遍历二维数组
int main(int argc, char const *argv[])
{
       /* code */
       char szName[3][10] = { "小明","大明" };
       //szName[2] = "小花";               //错误使用赋值
       strcpy_s(szName[2], sizeof(szName[2]), "小花");
       for (int i = 0; i < 3; i++)
       {
              printf("%s\n",szName[i]);
       }
       system("pause");
       return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值