目录
一.前言
大家好,我是一名刚刚入门的编程小白,从今天起我会不定时分享更新一些我在学习C语言过程的知识见解等,如果内容有问题,请大家多多指正。感谢大家的支持。
二.第一个C语言程序
#include <stdio.h> //这是编译预处理指令 也称为头文件的创立
int main() //定义主函数 main函数有且只能有一个(同时存在的两个及以上的源文件也只能有一个主函数)
{ //函数开始的标志
printf("hello world"); //打印 hello world(输出所指定的一行信息)
return 0; //函数执行完毕时返回函数值0
}//函数结束的标志
一个程序主要包括以下两方面的信息 (程序=算法+数据结构)
(一)对数据的描述。在程序中要指定用到哪些数据,以及这些数据的类型和数据的组织形式。这就是数据结构
(二)对操作的描述。要求计算机进行操作的步骤,也就是算法
数据是操作的对象,操作的目的是对数据进行加工处理,以得到期望的结果。打个比方,厨师制作菜肴,需要有菜谱,菜谱上一般应说明:(1)所用配料,指出为了做出顾客所指定的菜肴,应该使用哪些材料;(2)操作步骤,指出有了这些原料,应按什么样的步骤进行加工,才能做出所需的菜肴。
没有原料是无法加工成所需的菜肴的,而同一些原料可以加工出不同风味的菜肴。
三.变量和常量
在计算机高级语言中,数据有两种表现形式:常量和变量
(1)常量:在程序运行过程中,其值不能被改变的量被称为常量
C语言的常量分为以下几种:
- 字面常量
- const修饰的常变量
- #define定义的标识符常量
- 枚举常量
const 修饰的常变量在C语言中只是在语法层面限制了,变量 pai 不能直接被改变,但是 pai 本质上还是一个变量的,所以叫常变量。#include <stdio.h> //举例 enum Sex { MALE, FEMALE, SECRET }; //括号中的MALE,FEMALE,SECRET是枚举常量 int main() { //字面常量演示 3.14;//字面常量 1000;//字面常量 //const 修饰的常变量 const float pai = 3.14f; //这里的pai是const修饰的常变量 pai = 5.14;//是不能直接修改的! //#define的标识符常量 演示 #define MAX 100 printf("max = %d\n", MAX); //枚举常量演示 printf("%d\n", MALE); printf("%d\n", FEMALE); printf("%d\n", SECRET); //注:枚举常量的默认是从0开始,依次向下递增1的 return 0; }
(2)变量
2.1变量的分类
- 局部变量:在代码块内部定义的变量叫局部变量
- 全局变量:在代码块外部定义的变量叫全局变量
#include <stdio.h> int a=100; //全局变量 int main() { int a=10; //局部变量 printf("%d\n",a) return 0; }
当局部变量和全局变量同时对a进行赋值时,局部优先。
2.2 定义变量的方法: 数据类型加变量名 (注意:变量在创建的时候不初始化是一种不好的代码风格且当一个局部变量不初始化的时候值是随机的!!!)
2.3变量的作用域和使用周期
- 作用域作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用 的 而限定这个名字的可用性的代码范围就是这个名字的作用域。 1. 局部变量的作用域是变量所在的局部范围。 2. 全局变量的作用域是整个工程。
- 生命周期 变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段 1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。 2. 全局变量的生命周期是:整个程序的生命周期。
四.数据类型
在定义变量时需要指定变量的类型,变量的类型多种多样,C语言允许使用的类型如图
图4.1 C语言的数据类型(带*的为c99所增加的)
表1.整型数据常见的存储空间和值的范围
表2.实型数据的有关情况
我们同样可以借用关键字sizeof来计算数据类型存储单元的长度(占多少字节)
#include <stdio.h>
int main()
{
printf("%d\n", sizeof(char)); //1
printf("%d\n", sizeof(short));//2
printf("%d\n", sizeof(int)); //4
printf("%d\n", sizeof(long)); //4
printf("%d\n", sizeof(long long));//8
printf("%d\n", sizeof(float));//4
printf("%d\n", sizeof(double));//8
printf("%d\n", sizeof(long double));//8
return 0;
}//关键字sizeof是用来计算变量或者使用类型创建的变量的大小单位是字节
五. 字符串+转义字符+注释
- 字符串:" hello world\n"这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。( 注:字符串的结束标志是一个 '\0' 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容)
#include <stdio.h> //通过打印的结果验证\0的重要性 int main() { char arr1[] = "bit"; char arr2[] = {'b', 'i', 't'}; char arr3[] = {'b', 'i', 't', '\0'}; printf("%s\n", arr1); printf("%s\n", arr2); printf("%s\n", arr3); return 0; }
第一行在打印过程中隐藏了'\0',因此在屏幕上打印完bit后会自动结束进程,与第三行的结果相同。而第二行在内存开辟了空间,储存了bit三个字符后没有遇到'\0'无法停止,而以%s打印字符串的时候的结束标志,就是'\0',因此打印完't'以后会胡乱进行随机打印,直到在内存空间的某个位置遇到'0'才会停止。这就是'\0'转义字符的作用
-
转义字符:
当我们想屏幕上打印 c:\code\test.c
#include <stdio.h>
int main()
{
printf("c:\code\test.c\n");
return 0;
}
可是运行后的结果却是
这就是转义字符的作用,转变了原字符的意思。
表3:转义字符表
3. 注释
1. 代码中有不需要的代码可以直接删除,也可以注释掉
2. 代码中有些代码比较难懂,可以加一下注释文字,既方便调试后的复查又能起到提醒的作用
注释有两种风格:
C语言风格的注释 /*xxxxxx*/
缺陷:不能嵌套注释
C++风格的注释 //xxxxxxxx
可以注释一行也可以注释多行
六.选择语句(简单提及之后会细讲)
if语句 switch语句
举例如下:
#include <stdio.h>
int main()
{
int coding = 0;
printf("你会去敲代码吗?(选择1 or 0):>");
scanf("%d", &coding);
if(coding == 1)
{
prinf("坚持,终有所得\n");
}
else
{
printf("放弃,一无所有\n");
}
return 0;
}
七.循环语句(简单提及之后会细讲)
while语句 for语句 do...while语句
//while循环的实例
#include <stdio.h>
int main()
{
printf("进入大学\n");
int line = 0;
while(line<=20000)
{
line++;
printf("我要继续努力敲代码\n");
}
if(line>20000)
printf("好offer\n");
return 0;
}
八.函数
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0;
}
//上述代码,写成函数如下:
#include <stdio.h>
int Add(int x, int y)
{
int z = x+y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = Add(num1, num2);
printf("sum = %d\n", sum);
return 0;
}
函数的特点就是简化代码,代码复用
C语言要求,在程序中用到的所有函数,必须“先定义,后使用”。
九.数组
数组的定义:一组相同类型元素的集合
数组的下标:C语言规定数组的每个元素都有一个下标,下标是从0开始的。而数组可以通过下标来访问。
数组的使用:
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(i=0; i<10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
十.操作符
十一.常见的关键字
ANSI 标准C语言共有32个关键字,具体用法如下:
auto :声明自动变量
break:跳出当前循环
case:开关语句分支
char :声明字符型变量或函数返回值类型
const :声明只读变量
continue:结束当前循环,开始下一轮循环
default:开关语句中的“默认”分支
do 循环语句的循环体
double :声明双精度浮点数变量或函数返回值类型
else :条件语句否定分支(与 if 连用)
enum :声明枚举类型
extern:声明变量或函数是在其它文件或本文件的其他位置定义
float:声明浮点型变量或函数返回值类型
for:一种循环语句
goto:无条件跳转语句
if:条件语句
int: 声明或函数
long :声明整型变量长整型变量或函数返回值类型
register:声明寄存器变量
return :子程序返回语句(可以带参数,也可不带参数)
short :声明短整型变量或函数
signed:声明有符号类型变量或函数
sizeof:计算数据类型或变量长度(即所占字节数)
static :声明静态变量
struct:声明结构体类型
switch :用于开关语句
typedef:用以给数据类型取别名
unsigned:声明无符号类型变量或函数
union:声明共用体类型
void :声明函数无返回值或无参数,声明无类型指针
volatile:说明变量在程序执行中可被隐含地改变
while :循环语句的循环条件
下面我们来认识一下其中的两个关键字
- 关键字typedef:typedef 顾名思义是类型定义,这里应该理解为类型重命名。
#include <stdio.h> typedef unsigned int u_int int main() { // unsigned int 是无符号整形 unsigned int num1=100; u_int num2=100; // 通过使用关键字typedef,将类型重命名可以简便代码 return 0; }
- 关键字static:在C语言中: static是用来修饰变量和函数的 (1). 修饰局部变量-称为静态局部变量 (2). 修饰全局变量-称为静态全局变量 (3). 修饰函数-称为静态函数
#include <stdio.h>
//void在这里表示不需要函数返回任何值
//测验1.
void test()
{
int a = 1;
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0; //该程序的输出结果是十个2
}
//测验2.
void test()
{
//这里的a是局部变量 用static修试局部变量 测验关键字static的作用
static int a = 1;
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;//该程序的输出结果是2~11
}
结论:static修饰局部变量的时候,其实改变了变量的存储类型(栈区存储变为静态区),从而使得静态的局部变量出了自己的作用域也不会销毁,相当于改变了这个局部变量的生命周期。(或者说static修饰局部变量改变了变量的生命周期 让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。)
//在源文件1里面创建一个变量
int grade=100;//源文件1里
//在源文件2里面引用这个变量grade
//如果想使用来自其他外部文件的全局变量,需要先声明一下
//关键字extern是专门用来声明外部符号的
extern int grade;
int main()
{
printf("%d\n",grade);
return 0;//程序正常输出
}
//但当我们在源文件1里用static修饰后
static int grade=100;
//发现编译器报错“无法解析的外部符号”
结论:使用static修饰全局变量,使这个全局变量只能在自己所在的源文件内部使用。(全局变量在其他源文件内部可以被使用,是因为全局变量具有外部链接属性)
用static修饰函数与修饰全局变量的结果大致相同,即:
结论:一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
十二.#define定义的常量和宏
#include <stdio.h>
//#define 定义的标识符常量
#define M 100
#define STR "hehe"
int main()
{
printf("%d\n", M);
printf("%s\n", STR);
return 0;
}
//define定义宏 类似于函数但与函数的适用范围不同
#define ADD(x, y) ((x)+(y))
#include <stdio.h>
int main()
{
int sum = ADD(2, 3);
printf("sum = %d\n", sum);
sum = 10 * ADD(2, 3);
printf("sum = %d\n", sum);
return 0;
}
十三.指针
13.1内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。而变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。
取出变量地址如下:
#include <stdio.h>
int main()
{
int num = 10;
#//取出num的地址
//注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
printf("%p\n", &num);//打印地址,%p是以地址的形式打印
return 0;
}
那地址如何存储,这就需要定义指针变量。
//定义一个整型指针变量
int num = 10;
int *p;//p为一个整型指针变量
p = #
//指针的使用实例:
#include <stdio.h>
int main()
{
int num = 10;
int *p = #
*p = 20;
return 0;
}
以整形指针举例,可以推广到其他类型,如:
#include <stdio.h>
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'q';
printf("%c\n", ch);
return 0;
}
13.2 指针变量的大小
#include <stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(short *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(double *));
return 0;
}
由此我们可以得出:指针变量在32位平台下是四个字节,在64位平台下是八个字节
十四.结构体
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。 比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。 这里只能使用结构体来描述了。
struct Stu
{
char name[20];//名字
int age; //年龄
char sex[5]; //性别
char id[15]; //学号
};
//打印结构体信息
struct Stu s = {"张三", 20, "男", "20180101"};
//.为结构成员访问操作符
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);
//->操作符
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps-
>id);
结构体用于描述一个具有复杂属性的物品
. 和 -> 是结构体成员访问的操作符
用法:结构体变量 . 结构体成员
结构体指针 -> 结构体成员
十五. 关于编译器的“方言”
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d ", &age);
if (age >= 18)
{
printf("你已经成年啦");
}
else
printf("你还未成年哟");
return 0;
}
在vs编译器中,调用scanf函数时(举例如上图所示)会出现“地方性报错”。
让我们看一下编译器给的报错原因:
这段话的大概意思是:scanf函数要想在该编译器环境调用需要使用scanf_s代替,如果不想使用scanf_s代替,要引用#define _CRT_SECURE_NO_WARNINGS 1,让它允许我使用scanf函数而不报错(注意:一定要放在第一行的位置)但是如果我们使用scanf_s这个具有“地方特色”的函数后会导致我们无法在其他的编译环境使用,没有办法达到“国际通用”的标准,但显然每次输入这个是很麻烦的,那么有没有办法一劳永逸办法呢?
首先,我们可以在“我的电脑”上搜索文件newc++file.cpp。如图所示
这里我推荐使用文件搜索工具Everything,因为他真的要比上面的方式快太多太多了!!!!
当我们打开进行编辑保存后会发现这种方式可能行不通
那么此时我们把newc++file.cpp拖到桌面上,进行编辑保存后,再将它拖回去替代原来的文件即可 。
End:今天的内容就是这些,谢谢大家。