初识c语言
1. 什么是c语言
c语言是一门通用的计算机编程语言,广泛应用于底层开发。c语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
二十世纪八十年代,为了避免各开发厂商用的c语言语法产生差异,有美国国家标准局为c语言指定了一套完整的美国国家标准语法,称为ANSI C,作为C语言的最初标准。目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数和汉字标识符,一定程度上实现了汉字编程。**
2.第一个C语言程序
首先先写出一个可以显示出“Hello World”的程序。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
//第一个C语言程序
//打印出“Hello World”
printf("Hello World\n");
printf("Hello jokr\n");
return 0;
}
// main()函数是程序的入口
//并且一个程序只能有一个main函数
3.数据类型
数据名 | 大小 | 类型 |
---|---|---|
char | 1 | 字符数据类型 |
short | 2 | 短整型 |
int | 4 | 整型 |
long | 4 | 长整型 |
long long | 8 | 更长的整型 |
float | 4 | 单精度浮点数 |
double | 8 | 双精度浮点数 |
long double | 8 | 更长的双精度浮点数 |
首先先介绍一下sizeof:
- sizeof是C语言的一种单目操作符,如C语言的其他操作符++、–等。 它并不是函数。
- sizeof操作符以字节形式给出了其操作数的存储大小。
- 操作数可以是一个表达式或括在括号内的类型名。
- 操作数的存储大小由操作数的类型决定。
#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));
printf("%d\n", sizeof(long double));
return 0;
}
类型的使用:
char ch = ‘w’;
int weight = 120;
int salary = 20000;
4.变量、常量
在生活中,存在变化的量,也同时存在着不变的量,比如:
可变值的量:身高,体重,年龄等
不可变值的量:圆周率(pi),一天有24个小时等
所以在C语言中,将不会改变值的量称为常量,会改变值的量称为变量。
4.1定义变量的方法
int age = 150;
float weight = 45.5f;
char ch = ‘w’;
char ch[] = “hahahah”;
float类型的变量要在数字都后面加一个f,字符型的要用单引号(‘’)给修饰起来,字符串应该存储在字符数组里边。
4.2变量的分类
- 局部变量
- 全局变量
#include<stdio.h>
int year = 2022;
int year1 = 2021;
int main()
{
int year = 2023;
printf("year = %d\n", year);
printf("year1 = %d\n", year1);
}
那这段代码的运行结果是什么呢?
在main函数外定义的year变量是全局变量。
而在main函数内部定义的year变量则称之为局部变量。
由运行结果可知,当全局变量和局部变量重名时候,局部变量优先使用。
全局变量则可以在任何位置使用。
4.3变量的使用
#include<stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("请输入两个数字");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("%d", sum);
return 0;
}
4.4变量的作用域和生命周期
作用域
作用域(scope)是程序设计的概念,通常来说,一段代码中所用到的名字并不是一直有效的,而限制这个名字的可用性的代码范围就是这个名字的作用域
1.局部变量的作用域是变量所在的局部范围。
2.全局变量的作用域是整个工程
生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
1.局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
2.全局变量的生命周期是:整个程序的生命周期。
4.5常量
C语言中的常量定义分为以下几种:
- 字面常量
- const修饰的常变量
- #define定义的标识符常变量
- 枚举常量
#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*/;//这里的pai已被const修饰了,不可以被直接修改!!
//#define的标识符
#define MAX 100
printf("MAX = %d\n", MAX);
//枚举常量
printf("Sex = %d\n", MALE);
printf("Sex = %d\n", FEMALE);
printf("Sex = %d\n", SECRET);
//枚举常量的默认是从0开始的,依次向下递增1
return 0;
}
上面的pai被称之为const修饰的常变量,const修饰的常变量是在语法的底层上限制了pai不能直接被改变,但是pai本质上还是一个变量,所以称为常变量。
5.字符串
5.1字符串
"hello bit.\n"
这种有双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。
字符串的简述标注是一个 \0 的转义字符,在计算字符串长度的时候 \0 是结束标准,不算字符串的内容。
#include<stdio.h>
int main()
{
char arr[] = "bit";
char arr2[] = { 'b','i','t' };
char arr3[] = { 'b','i','t','\0' };
printf("%s\n", arr);
printf("%s\n", arr2);
printf("%s\n", arr3);
return 0;
}
因为arr2是一个字符串,但是 \0 的位置未知,所以打印出来的内容会出现其他字符直至读取到 \0 停止打印。
char arr[] = “bit”;
这种方式使用字符串字面值来初始化字符数组。
字符串字面值会自动在末尾添加一个空字符(‘\0’),所以arr数组实际上包含了四个字符:“b”, “i”, “t”, “\0”。
char arr2[] = { ‘b’,‘i’,‘t’ };
这种方式同样使用字符数组的初始化列表来初始化数组,但没有显式地添加末尾的空字符(‘\0’)。
arr2数组只包含了三个字符:“b”, “i”, “t”。
arr2不符合C语言中字符串的要求,因为它没有以空字符结尾。
arr2只是一个普通的字符数组,不能直接用于处理字符串的函数,除非你显式地在后面添加空字符(‘\0’)。
char arr3[] = { ‘b’,‘i’,‘t’,‘\0’ };
这种方式使用字符数组的初始化列表来初始化数组。
我们显式地在数组的初始化列表中添加了末尾的空字符(‘\0’)。
arr3数组也包含了四个字符:“b”, “i”, “t”, “\0”。
strlen 是一个C标准库函数,用于计算字符串的长度(不包括末尾的空字符 ‘\0’)。它的函数原型定义在头文件 <string.h> 中。
5.2转义字符
转义字符 | 释义 |
---|---|
\” | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行符 |
\t | 水平制表符 |
\v | 垂直制表符 |
- 问题1 :如何在屏幕上打印一个单引号 ’,怎么做?
- 问题2:如何在屏幕上打印一个字符串,字符串的内容是一个双引号 ”,怎么做?
#include<stdio.h>
int main()
{
printf("%c\n",'\'');
printf("%s\n", "\"");
return 0;
}
6.注释
1.代码中有不需要的代码可以直接删除,也可以直接注释掉。
2.代码中有些代码比较难懂,可以加一些注释文字。
#include<stdio.h>
int main()
{
//这是一个单行注释
/*
这是一个多行注释
*/
//单行注释//是//可以嵌套//的
//但是多行注释是不可以嵌套的
return 0;
}
注意:单行注释可以嵌套,但是多行注释不可以嵌套!!!
7.循环语句
#include <stdio.h>
int main() {
int number = 10;
if (number > 5) {
printf("数字大于5。\n");
}
else {
printf("数字不大于5。\n");
}
printf("程序结束。\n");
return 0;
}
循环语句里面主要有:
- while语句
- for语句
- do…while语句
#include <stdio.h>
int main() {
int i = 0;
while (i < 5) {
printf("循环迭代:%d\n", i);
i++;
}
printf("循环结束。\n");
return 0;
}
8.函数
函数的特点就是简化代码,代码复用
#include<stdio.h>
int add(int num1,int num2)
{
return num1 + num2;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("请输入你要求和的两个数字\n");
scanf("%d %d", &num1, &num2);
sum = add(num1, num2);
printf("%d + %d = %d", num1, num2, sum);
return 0;
}
9.数组
要存储1-10的数字,怎么存储
c语言中给了数组的定义:一组相同类型元素的集合
9.1数组定义
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整型数组,最多可以存储10个数字
9.2数组的下标
C语言规定:数组的每个元素都有一个下标,下标是从0开始的。
数组可以通过下标来访问
比如:
int arr[10] = {0};
//如果数组有10个元素,则下标的范围就是0~9;
9.3数组的使用
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
for (int i = 0; i <= 9; i++)
{
arr[i] = i;
}
for (int i = 0; i <= 9; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
10.常见关键字
10.1 关键字typedef
typedef顾名思义就是类型定义,这里应该理解为类型重命名
比如:
//将unsigned int 重命名为unit_32,所以unit_32也是一个类项名
typedef unsigned int unit_32;
int main()
{
unsigned int num1 = 0;
unit_32 num2 = 0;
//此时这里的num1和num2是同一个类型!
return 0;
}
10.2 关键字static
在C语言中:
static是用来修饰变量和函数的
- 修饰局部变量-称为静态局部变量
- 修饰全局变量- 称为静态全局变量
- 修饰函数-称为静态函数
10.2.1修饰局部变量
以下这个代码可以解释static修饰局部变量时的作用。
#include<stdio.h>
void test()
{
int i = 0;
i++;
printf("%d ", i);
}
void test2()
{
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
if (i == 9)
printf("\n");
}
for (i = 0; i < 10; i++)
{
test2();
}
return 0;
}
因为staic中的i每次都会被重新创立,所以每次i都是从1开始记起,故打印出10个1。
因为test2函数中的i被static修饰,所以i每次不会被重新创立,故打印出1~10。
static修饰局部变量改变了变量的生命周期
让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。
10.2.2修饰全局变量
//代码1
//add.c
int g_val = 2018;
//test.c
int main ()
{
printf("%d \n",g_val);
return 0;
}
//代码2
//add.c
ststic int g_val = 2018;
//test.c
int main ()
{
printf("%d\ n",g_val);
return 0;
}
代码1可以正常运行,而代码2则在编译时就会出现连接性错误。
结论:
一个全局变量被static修饰时,使得这个全局变量只能在本源文件内使用,不能再其他源文件中使用。
10.2.3修饰函数
//代码1
//add.c
int Add(int x,int y)
{
return x + y;
}
//test.c
int main ()
{
printf("%d /n",Add(2,3));
return 0;
}
//代码2
//add.c
static int Add(int a ,int b)
{
return (a + b);
}
//test.c
int main ()
{
printf("%d",Add(2,3));
return 0;
}
代码1正常,代码2则在编译时就出现了连接性错误。
结论:
一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
11#define定义常量和宏
//define定义常量和宏
#define MAX 1000
//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 * 10 = %d", sum);
return 0;
12.指针
12.1内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的。
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是一个字节
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
变量是创建在内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。
取出变量地址如下:
#include<stdio.h>
int main()
{
int num = 10;
#//取出num的地址
//注:这里的num的4个字符,每个字符都有其地址,而&num取出的则是他第一个地址(较小的地址)
printf("%d", &num);
return 0;
int num = 10;
int *p;//p是一个整型指针变量
p = #
指针的使用实例:
#include<stdio.h>
int main ()
{
int num = 10;
int *p = #
*p = 20;
printf("num = %d",num);
return 0;
}
因为p取了num的第一个地址,所以p的存储的地址就是0x0012ff44
12.2指针变量的大小
#include<stdio.h>
int main()
{
//32位平台指针变量的大小取决于32个bit位(4个字节)
//64位平台指针变量的大小取决于64个bit位(8个字节)
printf("sizeof(char *) = %zd\n", sizeof(char *));
printf("sizeof(short *) = %zd\n", sizeof(short *));
printf("sizeof(int *) = %zd\n", sizeof(int *));
printf("sizeof(double *) = %zd\n", sizeof(double *));
return 0;
}
总结:指针大小在32位的平台下是4个字节,64位的平台下是8个字节。
13.结构体
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂模型。
比如描述学生,学生包含了姓名+年龄+性别+学号这几项信息。
struct stu
{
char name[20];
int age;
char sex[5];
char id[15];
}
结构体的初始化:
//打印结构体的信息
struct stu s = {"张三",20,"男","22408010319"};
//.为结构成员访问操作符
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);