初识C语言
- 什么是C语言
- 第一个C语言程序
- 数据类型
- 变量、常量
- 字符串+转义字符+注释
- 选择语句
- 循环语句
- 函数
- 数组
- 操作符
- 常见关键字
- define 定义常量和宏
- 指针
- 结构体
什么是C语言
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产
生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。
编译器:MSVC(VS2019)、GCC
第一个C语言程序
创建工程步骤:
-
创建新项目 -
创建源文件 test.c–源文件 test.h–头文件 -
写代码
#include <stdio.h>
int main()
{
printf("hello bit\n");
printf("he he\n");
return 0;
}
#include <stdio.h>
int main()
{
return 0;
}
操作快捷键:
运行代码:
Ctrl + F5
[Fn] + Ctrl + F5
调试代码:
F10–逐步执行
int main(void)
{
return 0;
}
int main(int argc, char* argv[])
{
return 0;
}
void main()
{
}
数据类型
char
short
int
long
long long
float
double
#include <stdio.h>
int main()
{
int age = 10;
int price = 50;
double weight = 55.5;
return 0;
}
#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;
}
sizeof(long long) > sizeof(long) > sizeof(int)
不同格式打印的结果:
#include <stdio.h>
int main()
{
char ch = 'e';
printf("%c\n", ch);
printf("%d\n", ch);
return 0;
}
变量、常量
生活中的有些值是不变的(比如:圆周率,性别(?),身份证号码,血型等等)
有些值是可变的(比如:年龄,体重,薪资)。
不变的值,C语言中用常量的概念来表示;变的值,C语言中用变量来表示。
定义变量的方法
#include <stdio.h>
int main()
{
float weight;
char sex = 'm';
short age = 10;
age = 11;
printf("%d\n", age);
return 0;
}
变量的分类
#include <stdio.h>
int g = 100;
void test()
{
int b = 1000;
}
int main()
{
int a = 10;
return 0;
}
#include <stdio.h>
int a = 100;
int main()
{
int a = 10;
printf("%d\n", a);
return 0;
}
局部变量和全局变量可以同名
局部变量和全局变量同名,局部优先,但不建议相同
局部变量和全局变量相互独立,互不影响
#include <stdio.h>
int a = 100;
void test()
{
printf("%d\n", a);
}
int main()
{
int a = 10;
printf("%d\n", a);
a = 20;
test();
printf("%d\n", a);
return 0;
}
变量的使用
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
scanf("%d%d", &num1, &num2);
int sum = num1 + num2;
printf("%d\n", sum);
return 0;
}
’This function or varible may be unsafe’解决方法:
变量的作用域和生命周期
作用域
作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的而限定这个名字的可用性的代码范
围就是这个名字的作用域。
- 局部变量的作用域是变量所在的局部范围。
- 全局变量的作用域是整个工程(跨文件使用也可以)
extern int g_val;
#include <stdio.h>
int main()
{
printf("%d\n", g_val);
return 0;
}
生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
- 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
- 全局变量的生命周期是:整个程序的生命周期。
常量
C语言中的常量分为以下以下几种:
- 字面常量
#include <stdio.h>
int main()
{
3.14;
100;
float a = 3.14;
return 0;
}
const 修饰的常变量
常属性 - 一个变量不能被改变的属性
#include <stdio.h>
int main()
{
int a = 100;
a = 200;
printf("%d\n", a);
const int b = 100;
b = 200;
printf("%d\n", b);
return 0;
}
const修饰的常变量依旧是变量,不是常量,只是具有常属性,不能被修改而已
#include <stdio.h>
int main()
{
const int n = 100;
int arr[n] = {0};
return 0;
}
- #define 定义的标识符常量
#include <stdio.h>
#define MAX 100
int main()
{
int a = MAX;
int arr[MAX] = {0};
printf("a = %d\n", a);
return 0;
}
- 枚举常量
- 枚举 - 一一列举,例:性别、三原色
- 创建完枚举类型后,打印时,默认0、1、2···向下递增。可赋初值
- 枚举常量不可改
#include <stdio.h>
enum Sex
{
MALE=3,
FEMALE=7,
SECRET
};
int main()
{
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
return 0;
}
字符串+转义字符+注释
字符串
char - 字符类型;
"hello world\n"
这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
**注:**字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串 内容。
‘a’ 单引号引起 - 字符
“abcdef” 双引号引起 - 字符串
‘ab’ 胡写!
字符串初始化
#include <stdio.h>
int main()
{
char ch1[10] = "abcdef";
char ch2[] = { 'a', 'b', 'c', 'd', 'e', 'f'};
return 0;
}
\0 作为结束标志的体现
#include <stdio.h>
int main()
{
char ch1[10] = "abcdef";
printf("%s\n", ch1);
char ch2[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%s\n", ch2);
return 0;
}
’\0’在求字符串长度时的作用
\0:打印时作为字符串结束标志;
求长度时不包含\0,不算在长度内
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[10] = "abcdef";
printf("%d\n", strlen(ch1));
char ch2[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0' };
printf("%d\n", strlen(ch2));
return 0;
}
转义字符
假如要在屏幕上打印一个目录: c:\code\test.c
#include <stdio.h>
int main()
{
printf("c:\code\test.c\n");
return 0;
}
实际结果:
转义字符 - 把原来的意思转变
例:n:字符 \n:换行符
转义字符 | 释义 |
---|
? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
三字母词; ??) --> ] ??( --> [
printf("%s\n", "????)");
转义字符 | 释义 |
---|
\’ | 用于表示字符常量’ | \’’ | 用于表示一个字符串内部的双引号 | \\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符。 | \t | 水平制表符 |
printf("%c", 'a');-打印字符a
printf("%c", '\'');-打印'
printf("%s\n", "\"");-字符串打印内容为"
printf("%s\n", "c:\\test\\test.c");
转义字符 | 释义 |
---|
\ddd | ddd表示1~3个八进制的数字。 如: \130 X | \xdd | dd表示2个十六进制数字。 如: \x30 0 |
\ddd - ddd的8进制数字转换成10进制后的值,作为ASCII值对应的字符
\xdd - dd的8进制数字转换成10进制后的值,作为ASCII值对应的字符
#include <stdio.h>
int main()
{
printf("%c\n", '\065');
printf("%c\n", '5');
printf("%c\n", '\x51');
return 0;
}
练习:
#include <stdio.h>
int main()
{
printf("%d\n", strlen("abcdef"));
printf("%d\n", strlen("c:\test\328\test.c"));
return 0;
}
注释
- 代码中有不需要的代码可以直接删除,也可以注释掉
- 代码中有些代码比较难懂,可以加一下注释文字
注释有两种风格:
-
C语言风格的注释 /*xxxxxx*/
-
C++风格的注释 //xxxxxxxx
选择语句
int main()
{
int input = 0;
printf("加入比特\n");
printf("要好好敲代码吗(1/0)?");
scanf("%d", &input);
if (input == 1)
{
printf("好offer\n");
}
else
{
printf("卖红薯\n");
}
return 0;
}
循环语句
有些事必须一直做,比如大家,日复一日的学习。
C语言中如何实现循环呢?
- while语句
- for语句(后期分析)
- do … while语句(后期分析)
#include <stdio.h>
int main()
{
int line = 0;
printf("加入比特\n");
while (line<20000)
{
printf("敲代码:%d\n", line);
line++;
}
if(line >= 20000)
printf("好offer\n");
return 0;
}
函数
#include <stdio.h>
int Add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
scanf("%d %d", &num1, &num2);
sum = Add(num1, num2);
printf("%d\n", sum);
return 0;
}
数组
C语言中给了数组的定义:一组相同类型元素的集合
数组定义
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
char ch[5] = {'a', 'b', 'c'};
下标默认从0开始,更好访问元素
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d ", arr[5]);
数组使用
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
while (i < 10)
{
printf("%d ", arr[i]);
i++;
}
return 0;
}
操作符
简单介绍,后续详解。
算术操作符
+ - * / %
#include <stdio.h>
int main()
{
int a = 5 / 2;
printf("%d\n", a);
float b = 5 / 2.0;
printf("%f\n", b);
return 0;
}
#include <stdio.h>
int main()
{
int a = 7 % 2;
printf("%d\n", a);
return 0;
}
移位操作符 - 作用于二进制位
>> <<
#include <stdio.h>
int main()
{
int a = 6;
int b = a << 1;
printf("%d\n", b);
printf("%d\n", a);
return 0;
}
位操作符
& ^ |
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a & b;
printf("%d\n", c);
return 0;
}
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a | b;
printf("%d\n", c);
return 0;
}
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a ^ b;
printf("%d\n", c);
return 0;
}
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
#include <stdio.h>
int main()
{
int a = 10;
a = 20;
a = a + 10;
a += 10;
a = a - 8;
a -= 8;
a = a >> 1;
a >>= 1;
return 0;
}
单目操作符
a+b:a和b是+的两个操作数 —> +:双目操作符
! 逻辑反操作
#include <stdio.h>
int main()
{
int a = 10;
printf("%d\n", !a);
int a = 0;
printf("%d\n", !a);
int a = 10;
if (a)
{
}
if (!a)
{
}
return 0;
}
- 负值
+ 正值
#include <stdio.h>
int main()
{
int a = 10;
int b = -a;
int c = +a;
return 0;
}
& 取地址
sizeof() 操作数的类型长度(以字节为单位)
#include <stdio.h>
int main()
{
int a = 10;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));
return 0;
}
~ 对一个数的二进制按位取反
#include <stdio.h>
int main()
{
int a = 0;
printf("%d\n", ~a);
return 0;
}
-
整数在内存中存储的时候,存储是二进制 -
一个整数的二进制表示有3种形式:
- 正的整数:原码、反码、补码相同
? 负的整数:原码、反码、补码需要计算
- 有符号的整数,最高位是0,表示正数
? 最高位是1,表示负数
- 内存中存储整数的时候,存储的是二进制的补码,计算的时候采用也是补码
例:
int a = 1;
int a = -1;
++ 前置、后置++
-- 前置、后置--
#include <stdio.h>
int main()
{
int a = 2;
printf("%d\n", a);
return 0;
}
#include <stdio.h>
int main()
{
int a = 2;
int c = ++a;
printf("%d\n", c);
printf("%d\n", a);
int c = a++;
printf("%d\n", c);
printf("%d\n", a);
int c = --a;
printf("%d\n", c);
printf("%d\n", a);
int c = a--;
printf("c = %d\n", c);
printf("a = %d\n", a);
return 0;
}
注:
int main()
{
int a = 1;
int b = (++a) + (++a) + (++a);
printf("b = %d\n", b);
return 0;
}
int main()
{
int a = 10;
printf("%d %d\n", --a, --a);
return 0;
}
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
#include <stdio.h>
int main()
{
int a = (int)3.14;
printf("%d\n", a);
return 0;
}
关系操作符
=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
逻辑操作符
&& 逻辑与 - '并且'
|| 逻辑或 - '或者'
#include <stdio.h>
int main()
{
int a = 3;
int b = 4;
if ((a == 3) && (b == 4))
{
printf("哈哈\n");
}
if ((a == 3) || (b == 4))
{
printf("呵呵\n");
}
return 0;
}
条件操作符(三目操作符)
exp1 ? exp2 : exp3
#include <stdio.h>
int main()
{
int a = 10;
int b = 0;
if (a == 5)
{
b = -6;
}
else
{
b = 6;
}
b = ((a == 5) ? (-6) : (6) );
return 0;
}
逗号表达式
exp1, exp2, exp3, …expN
#include <stdio.h>
int main()
{
int a = 0;
int b = 3;
int c = -1;
int d = (a = b - 5, b = a + c, c = a + b, c -= 5);
printf("%d\n", d);
return 0;
}
下标引用、函数调用和结构成员
[] () . ->
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
arr[9];
return 0;
}
- arr、9分别是两个操作数
- int arr[10]中的[]是定义数组大小的写法
int main()
{
printf("hehe\n");
return 0;
}
int Add(int x, int y)
{
return x + y;
}
void test()
{
}
int main()
{
test();
int ret = Add(3, 5);
return 0;
}
函数调用操作符的操作数不固定:
- Add(3, 5) - 3个操作数:Add、3、5
- printf(“hehe\n”) - 2个操作数:printf、""内的字符串
- 函数不需要传参,函数名本身是操作数
常见关键字
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
int main()
{
int a = 10;
return 0;
}
break - 停止,中断 - 用于循环,switch语句
switch-case
const - 常属性
continue - 继续 - 用于循环
do - 常用于do-while语句
for
while
if else
goto
enum - 枚举关键字
struct - 结构体
extern - 声明外部符号
register - 寄存器
return - 返回 - 函数
char
double
float
int
long
short
signed - 有符号的,应用于正负数
unsigned - 无符号的
sizeof
static - 静态的
struct - 结构体
typedef -类型重定义
union - 联合体(共用体)
void -空,无
volatile - Linux - 易变的
关键字C语言内置,不能拿自己的定义的符号名和关键字冲突!
register
#include <stdio.h>
int main()
{
register int num = 100;
return 0;
}
关键字 typedef
typedef:类型定义,这里理解为类型重命名
typedef unsigned int uint_32;
int main()
{
unsigned int num1 = 0;
uint_32 num2 = 0;
return 0;
}
关键字static
在C语言中:
static是用来修饰变量和函数的
- 修饰局部变量-静态局部变量
- 修饰全局变量-静态全局变量
- 修饰函数-静态函数
void test()
{
int a = 1;
a++;
printf("%d ", a);
}
#include <stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
void test()
{
static int a = 1;
a++;
printf("%d ", a);
}
#include <stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
结论:
static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
全局变量-extern可用-链接
static修饰全局变量
static int g_val = 2018;
int main()
{
printf("%d\n", g_val);
return 0;
}
结论:
- 默认一个全局变量具有【外部】链接属性
- 而全局变量被static修饰,使全局变量的外部链接属性变成内部链接属性
- 此时该全局变量只能在本源文件内部使用,其他源文件无法链接到,也无法使用!
static修饰函数
结论:
#define 定义常量和宏
- #define定义常量
#include <stdio.h>
#define NUM 100
int main()
{
printf("%d\n", NUM);
return 0;
}
- #define定义宏
#include <stdio.h>
#define MAX(X,Y) (X>Y?X:Y)
int main()
{
int a = 10;
int b = 20;
int c = MAX(a, b);
printf("%d\n", c);
return 0;
}
指针
内存
- 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
- 为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
变量都有地址,取出变量地址如下:
#include <stdio.h>
int main()
{
int a = 10;
printf("%p\n", &a);
return 0;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EVxIMT1r-1629038565284)(E:\比特就业课\C_初阶\1.初识C语言\初识C语言.assets\image-20210815204633677.png)]
那地址如何存储,需要定义指针变量
地址可以很好找到内存空间,故也称指针
当指针存到某变量中去,也称该变量为指针变量
int num = 10;
int *p;
p = #
#include <stdio.h>
int main()
{
int a = 10;
int * pa = &a;
return 0;
}
指针变量的解引用操作
两大操作符
pa是指针变量,即变量本身
*pa是指针pa指向的对象,即a
指针变量:
- 把地址放进去
- 通过地址找到所指向的空间
#include <stdio.h>
int main()
{
int a = 10;
int * pa = &a;
* pa = 20;
printf("%d\n", a);
printf("%p\n", *pa);
return 0;
}
以整形指针举例,可以推广到其他类型,如:
#include <stdio.h>
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'q';
printf("%c\n", ch);
return 0;
}
注意:
int a = 10;
char* p = &a;
指针变量的大小
指针变量存放的是地址,地址的大小是4byte,则指针变量也是4byte
- 32位机器(x86) - 32根地址线 - 32bit - 4byte
- 64位机器(x64) - 64根地址线 - 64bit - 8byte
#include <stdio.h>
int main()
{
printf("%zu\n", sizeof(char*));
printf("%zu\n", sizeof(short*));
printf("%zu\n", sizeof(int*));
printf("%zu\n", sizeof(long*));
printf("%zu\n", sizeof(float*));
printf("%zu\n", sizeof(double*));
return 0;
}
int main()
{
char c = 'w';
char* pc = &c;
printf("%d\n", sizeof(pc));
return 0;
}
结论:
地址的大小与是什么类型的地址无关!
结构体
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。
- 声明结构体类型
- 结构体的初始化
- 访问结构体
- . 为结构成员访问操作符:结构体变量.成员名
- 指针操作:-> - 结构体指针->成员名
struct Stu
{
char name[20];
int age;
char sex[5];
char id[15];
};
struct Book
{
char name[20];
int price;
char author[20];
};
int main()
{
struct Student s1 = {"张三", 20, "男", "20200506"};
struct Student s2 = {"lisi", 30, "女", "20200908"};
struct Book b1 = { "C语言程序设计", 55, "谭浩强" };
printf("名字: %s 年龄: %d 性别: %s 学号: %s\n", s1.name, s1.age, s1.sex, s1.id);
printf("%s %d %s\n", b1.name, b1.price, b1.author);
struct Book * pb = &b1;
printf("%s %d %s\n", (*pb).name, (*pb).price, (*pb).author);
printf("%s %d %s\n", pb->name, pb->price, pb->author);
return 0;
}
完结撒花。
|