1. 第一个C程序
- 头文件
- 主函数
- 注释
#include<stdio.h>//头文件
int main()//主函数
{
return 0;//返回0
}
//stdio标准输入输出
//使用库函数就得包含相应的头文件
//main是程序的入口,有且只有一个
2. 数据类型
#include<stdio.h>
int main()
{
printf("%d\n", sizeof(char)); //字符数据类型
printf("%d\n", sizeof(short)); //短整型
printf("%d\n", sizeof(int)); //整型
printf("%d\n", sizeof(long)); //长整型
printf("%d\n", sizeof(long long)); //更长的整型
printf("%d\n", sizeof(float)); //单精度浮点型
printf("%d\n", sizeof(double)); //双精度浮点型
return 0;
}
//c语言是可以自己定义类型的
运行结果:
注:sizeof是一个操作符,用来计算类型和变量大小。
3. 常量变量
常量:用来表示不变的量
变量:用来表示变化的量
3.1 变量
类型+变量名
float w=55.5f;
char ch='e'; (' ' 字符 " " 字符串)
3.1.1 变量的分类
- 全局变量:在大括号外面定义的(尽量不使用)
- 局部变量:在大括号内定义的
#include<stdio.h>
int a= 100; //全局变量
int main()
{
int a = 10;//局部变量
printf("a=%d", a);
return 0;
}
//运行结果:a=10
总结:
全局变量与局部变量同名时,局部变量优先。
3.1.2变量的使用
输入函数:
scanf(“%d%d”,&a,&b); (键盘输入两个变量时之间要加空格)(& 取地址符)
输出函数:
printf(“a=%d,b=%d”,a,b);
注:
error C4996: ‘scanf’: This function or variable may be unsafe.Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
解决办法1:
在代码的第一行定义 #define _CRT_SECURE_NO_WARNINGS 1
(scanf_s并非C语言库函数,而是VS编译器提供的函数,在其他编译器上编译不通过,代码的可移植性差)
解决办法2:
在VS编译器里有一个newc++file.cpp,将该文件拷贝到桌面,在桌面用记事本修改添加#define _CRT_SECURE_NO_WARNINGS 1后替换原文件,给VS源文件添加一个新建项(.c),即可。(一劳永逸的办法)
3.1.3 变量的作用域和生命周期
- 作用域(scope): 程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
局部变量的作用域是变量所在的局部范围,一个局部变量初始化的话默认是随机值(注意初始化!)。
#include<stdio.h>
int main()
{
{
int a = 10;//局部变量
printf("%d",a);//correct
}
printf("%d",a); //error
return 0;
}
全局变量的作用域是整个工程。
#include<stdio.h>
int a = 10;//全局变量
void test()
{
a = a + 10;
printf("test:%d\n", a);
}
int main()
{
test();
printf("main:%d",a);
return 0;
}
//输出结果:
//test:20
//main:20 局部变量优先于全局变量
注:如果全局变量是来自外部的,需要声明外部变量再使用。
extern int a;
-
生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
全局变量的生命周期是:整个程序的生命周期。
3.2 常量
3.2.1 字面常量
可直观看出.
3.2.2 const修饰的常变量
const修饰的变量具有常属性,不能改变,本质还是变量。
const int n=10; //不符合VS规定,因为数组大小只能用常量。
int arr[n]={0};
3.2.3 define定义的标识符常量
#define MAX 50
#include<stdio.h>
int main()
{
printf("%d", MAX);
return 0;
}
3.2.4 枚举常量
一一列举,C语言提供的一种自定义类型的方法.
性别:男,女,未知
#include<stdio.h>
enum Sex//性别:男 女 未知
{
//枚举常量
MALE,//0
FEMALE,//1
SECRET//2
};
int main()
{
enum Sex s=MALE;
return 0;
}
4. 字符串和转义字符
4.1字符串
这种由双引号引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
#include <stdio.h>
int main()
{
char arr1[] = "bit";
char arr2[] = { 'b', 'i', 't' };
char arr3[4] = { 'b', 'i', 't', '\0' };
printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);
return 0;
}
//运行结果:
//bit
//bit 烫烫烫
//bit
总结:
字符串的结束标志是’\0’,字符串长度(strlen)不统计’\0’,但是 '\0’占一个数组位 。
4.2 转义字符
转变字符本来的意思,如果要恢复转义字符原本的意思,再用一个\转回来,如" " ”,表示路径时都用两个\ 。
转义字符 | 释义 |
---|---|
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\’ | 用于表示字符常量’ |
\" | 用于表示一个字符串内部的双引号 |
\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符。 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3个八进制的数字。如\210 |
\xdd | d表示2个十六进制数字。 如: \x12 |
问题1:在屏幕上打印一个单引号’,怎么做?
问题2:在屏幕上打印一个字符串,字符串的内容是一个双引号“,怎么做?
#include<stdio.h>
int main()
{
printf("%c\n", '\'');
printf("%s\n", "\"");
return 0;
}
//程序输出什么?
#include<stdio.h>
int main()
{
printf("%d\n", strlen("abcdef"));
printf("%d\n", strlen("c:\test\328\test.c"));
return 0;
}//c : \t e s t \32 8 \t e s t . c
//运行结果:6
// 14
注:
‘0’—字符0,ASCII码为48;
‘\0’—转义字符0,ASCII码为0;
0—数字0;
EOF—文件结束标志,值为-1:#define EOF -1 。
5. 选择语句
5.1if语句
if(表达式)语句;
else 语句;
#include <stdio.h>
int main()
{
int input = 0;
printf("学不学?(选择1 or 0):>");
scanf("%d", &input);
if(input == 1)
{
printf("坚持,买旺仔牛奶\n");
}
else
{
printf("放弃,回家喂猪\n");
}
return 0;
}
6. 循环语句
6.1 while语句
#include <stdio.h>
int main()
{
int line = 0;
while(line<=20000)
{
line++;
printf("我要继续学习\n");
}
if(line>20000)
printf("毁灭吧我要摆烂\n");
return 0;
}
6.2 for语句
6.3 do … while语句
7. 函数
函数复用,简化代码。
#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;
}
8.数组
定义:一组相同类型元素的集合
8.1数组定义
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//定义一个整形数组,最多放10个元素
char ch[5]={'a','b','c','d','e'};
注:
数组的下标一定从 0 开始,定义数组时数组的大小在VS中不能是变量。
ERROR:int arr[n];
8.2数组的使用
#include <stdio.h>
int main()
{
int i = 0;
int arr[10];
for (i = 0; i < 10; i++)
{
scanf("%d ", &arr[i]);
}
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
scanf("%d ", &arr);为什么不对
为什么输入是1 2 3 4 5 6 7 8 9 10 11?
9. 操作符
9.1 算数操作符
+ - * / %
9.2 移位操作符
>> <<
9.3 位操作符
& ^ |
9.4 赋值操作符
= += -= *= /= &= ^= |= >>= <<=
a+=2;
a=a+2;
9.5 单目操作符
! 逻辑反操作 //C语言中0是假,非0是真
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换 //a=(int)3.14;(尽量少用)。
注:
前置:先运算再使用结果;
后置:先取用结果再运算(尽量少用)。
int a=1;
b=(++a)+(++a)+(++a);
printf("%d",b);//在不同的编译器里结果不同,代码不优秀
9.6 关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
9.7 逻辑操作符
&& 逻辑与
|| 逻辑或
9.8 条件操作符
exp1 ? exp2 : exp3
exp1结果为真,表达式结果为exp2的结果,否则表达式结果为exp3的结果。
9.9 逗号表达式
exp1, exp2, exp3, …expN
从左向右计算,但是表达式的结果与expN的结果相同。
9.10 下标引用、函数调用和结构成员
[] () . ->
10. 常见关键字
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
注:define不是关键字
10.1 关键字typedef
typedef 顾名思义是类型定义,这里应该理解为类型重命名。
//将unsigned int 重命名为uint1, 所以uint_1也是一个类型名
typedef unsigned int uint1;
int main()
{
unsigned int num1 = 0;//这两个变量的类型是一样的
uint1 num2 = 0;
return 0;
}
10.2 关键字static
static在C语言中用来修饰变量和函数。
10.2.1. 修饰局部变量-静态局部变量
static修饰局部变量改变了变量的存储类型,从而改变了生命周期,但没有让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束,但没改变作用域。
初始化:只在第一次调用该函数时进行初始化;
记忆性:后序调用时,该变量使用前一次函数调用完成之后保存的值;
存储位置:不会存储在栈上,放在数据段(静态区),不会销毁。
#include <stdio.h>
void test()
{
static int i = 0;//static修饰局部变量,调用时只初始化一次
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
//运行结果:1 2 3 4 5 6 7 8 9 10
10.2.2. 修饰全局变量-静态全局变量
一个全局变量被static修饰,改变了全局变量的链接属性,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。
(全局变量具有外部链接属性,原本可以在整个工程中使用,如果全局变量是来自外部的,需要声明外部变量再使用。)
注:extern用来声明外部符号。
//add.c
static int g_val = 2018;//外部链接属性消失
//test.c
#include <stdio.h>
int main()
{
extern int g_val;//声明来自外部的函数
printf("%d\n", g_val);
return 0;
}
10.2.3 .修饰函数-静态函数
函数也具有外部链接属性,一个函数被static修饰,改变了其链接属性,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
ERROR: static int Add(int x, int y);
//add.c
int Add(int x, int y)
{
return x + y;
}
//test.c
#include <stdio.h>
int main()
{
extern int Add(int, int);//声明外部函数
printf("%d\n", Add(2, 3));
return 0;
}
11. define定义标识符常量和宏
11.1define定义标识符常量
#define MAX 100
#define CHA "hehe"
#include <stdio.h>
int main()
{
printf("%d",MAX);//printf("%d",100);
printf("%s",CHA);//printf("%s","hehe");
}
11.2 define定义宏
#define ADD(x,y) ((x)+(y))
#include <stdio.h>
int main()
{
int a=10;
int b=20;
int sum=ADD(a,b);//int sum=(a+b);
}
12. 指针
12.1 内存
内存是电脑上特别重要的存储器,计算机中所有程序的运行都是在内存中进行的 。
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地
址。
12.2 指针变量
指针是地址,指针变量用来存放地址和指针的变量。
内存会被划分为小的内存单元,一个内存单元的大小是1个字节
每个内存单元都有编号,这个编号也被称为:地址/指针
地址/指针就可以存放在一个变量中,这个变量被称谓指针变量
通过指针变量中存储的地址,就能找到指针指向的空间
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a;//&取地址,p为一个整型指针变量
*p = 20;//*解引用操作符,指向a
printf("a=%d", a);//a=20
}
12.3 指针变量的大小
#include<stdio.h>
int main()
{
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(short *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(double *));
return 0;
}
//运行结果:4 4 4 4
总结:指针大小在32位平台是4个字节,64位平台是8个字节。
13. struct结构体
用结构体描述生活中的复杂类型,比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。
#include<stdio.h>
struct Stu
{
char name[20];//名字
int age; //年龄
char sex[5]; //性别
char id[15];//学号
};
int main()
{
struct Stu s = { "陈老六",20,"女","20815" };//形式1
struct Stu* ps = &s;//形式2
printf("name = %s age = %d sex = %s id = %s\n", s.name, s.age, s.sex, s.id);
printf("name = %s age = %d sex = %s id = %s\n", (*ps).name,(*ps).age,(*ps).sex,(*ps).id);
//等价于printf("name = %s age = %d sex = %s id = %s\n", ps->name, ps->age, ps->sex, ps-
>id);
return 0;
}
总结:
. 结构成员访问符
结构体变量.结构体成员
-> 结构成员访问操作符
结构体指针->结构体成员
请多多指教和关注哦!