【初识C语言】让你初步认识C语言

1. 认识什么是C语言

在这里插入图片描述

C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方- 式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。

2.第一个C语言输出语句

int main()
{
   int a=10;
   printf("%d\n",a;);
   return 0;
}

3.数据类型

在我们学习C语言中,知道一个数据是什么类型是非常重要的,下面给大家列举我们在写程度最常用的几个数据类型,希望对大家在编程中会有帮助。

在我们学习C语言中数据类型大致分为,整形,浮点型,字符型和指针类型
在这里我们先介绍一下整形,浮点型,字符型,指针的话在后面会给大家讲解。

unsigned表示无符号型
signed表示有符号型数据类型1

#include <stdio.h>
int main()
{
	printf(" char(字符数据类型)的字节大小 : %d 字节\n ", sizeof(char));
	printf("shart(短整型)的字节大小 : %d 字节\n ", sizeof(short));
	printf("int(整形)的字节大小 : %d 字节\n ", sizeof(int));
	printf("long(长整型)的字节大小 : %d 字节\n ", sizeof(long));
	printf("long long(更长整形)的字节大小 : %d 字节\n ", sizeof(long long));
	printf("float(单精度浮点型)的字节大小 : %d 字节\n ", sizeof(float));
	printf("double(双精度浮点数)的字符大小 : %d 字节\n ", sizeof(double));
	printf("long double(多精度浮点类型)的字符大小 : %d 字节\n ", sizeof(long double));
	return 0;
}

在这里插入图片描述

4.变量与常量

在C语言中常量有字面常量,const修饰的常量,#define标识符常量,枚举常量

  • 字面常量:在一串代码中直观的数值就叫做字面常量
    例如
int main()
{
	10;
	20; 
	30;
	return 0;
}
  • const修饰的常量:就是不可以改变的常量
    下面这个就是指明const修饰的值不可改变
int main()
{
	const int a=10;
	a = 9;
	printf("%d\n",a);
	return 0;
}

在这里插入图片描述

  • #define修饰的标识符常量

#define 标识符 常量
例如:
#define MAX 10

#define MAX 10
int main()
{
	
	printf("%d\n",MAX);
	return 0;
}

在这里插入图片描述

  • 枚举常量:就是一枚一枚分别列举出来的就叫做枚举常量
  • enum,这个函数叫做枚举值
enum shuxue
{
	a,
    b,
    c,
    d
};
int main()
{
	printf("%d\n",a);
	printf("%d\n", b);
	printf("%d\n", c);
	printf("%d\n", d);
	return 0;
}

在这里插入图片描述

5.转义字符,字符串,注释

  • 字符串
    这种由双引号引起来的一串字符称为字符串字面值,或者简称字符串
    例如:“abcdef” “C语言” 这些都是字符串
  • 转义字符
    实际上就是转变意思
    在这里插入图片描述
    !](https://img-blog.csdnimg.cn/2c0d7e9979a043f8ad847d02c05e3c3a.png)
include <stdio.h>
int main()
{
    printf("%d\n", strlen("abcdef"));
    // \62被解析成一个转义字符
    printf("%d\n", strlen("c:\test\628\test.c"));
    return 0;
}

在这里插入图片描述

  • 注释
  1. 代码中有不需要的代码可以直接删除,也可以注释掉
  2. 代码中有些代码比较难懂,可以加一下注释文字

常见的注释有 /xxxx/ 和 /xxxxxxxx/

int main()
{
    int a=10;
    a=20;//把a的值变为20

    /*int b=20;
    printf("%d\n",b);*/
    printf("%d\n", );
    return 0;
}

6.选择语句

选择语句就是根据不同的条件,进入不同的语句,从而实现不同的结果
常用的选择语句是if语句

格式为
if(判断条件)
{
}

//这个就是通过if选择语句来输出结果
int main()
{
	int year = 0;
	scanf("%d",&year);
	if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400) != 0)
	
	printf("是闰年\n");
	
	else
	
		printf("不是闰年\n");
	
	return 0;
}

7.循环语句

常用的循环语句有

  • for循环
  • while循环
  • do …while循环(暂时不讲)

首先我们来讲讲for循环语句
格式为 for(表达式1;表达式2;表达式3){循环语句}

  • for循环
int main()
{
	int score = 0;
	int count = 0;
	for (count = 1; count <=5; count++)//这就是循环语句
	{
		scanf("%d",&score);//输入语句
		printf("%d\n",score);//输出语句
	}

}
  • while循环

while循环格式为
while(判断表达式)
{
xxxxxxx
}

int main()
{
	int score = 0;
	int count = 1;
	while(count<=5)
	{
		scanf("%d",&score);
		printf("%d	",score);
		count++;
	}
	return 0;
}

8.函数

  • 什么是函数

main函数就是一种函数,程序中不可缺少的函数【程序入口】
C语言里面的函数和数学中的函数有一定的区别,C语言里面的函数可以没有参数,也可以没有计算的数值,而数学函数需要参数。
为什么要使用其它函数呢?
函数便于人们理解和修改程序,不必重新编写多次使用的代码,使用某个功能直接调用相应函数就可以了。【多次使用多次调用】

#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;
}

9.1一维数组

  • 什么是数组

数组的定义:一组相同类型元素的集合

数组类型一般是 整形数组,字符型数组,指针数组(暂时不讲)

数组的创建 数组类型 数组名【元素个数】
int arr [5];
char arr1[5];

  • 数组的初始化
    在这里插入图片描述

需要注意的是数组的下标是从0开始的,依次增长
一维数组的数组个数可以省略

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//数组的元素就是1-10
char arr1[5]={'a','b','c','d','e'};//数组的元素就是abcde
  • 数组的使用
int main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int  i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ",a[i]);//通过循环输出1-10
	}
	return 0;
}

数组在内存中连续存放的
数组的地址,从低到高变化的

9.2二维数组

  • 二维数组的创建

int main()
{
	int arr[3][3];
	char arr[3][3];
	double arr[3][3];
	return 0;
}
  • 二维数组的初始化
int main()
{
	int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
	//arr就是二维数组,3行3列
	return 0;
}

二维数组中行数可以省略,但是列数不能省略

  • 数组的越界

规定数组的下标从0开始,如果有n个元素,最后一位是n-1
如果下标小于 0或下标大于n-1,则数组越界

  • 冒泡排序

依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。

在第一趟排序结束后,第二趟排序依旧从第一个元素开始排序,排到倒数第二个元素停止。为什么是从第一个元素开始,又为什么到倒数第二个元素停止了呢?因为每一次排序都会往序列的后面放,第一趟排序已经将整个序列最大的数放在了序列的最后,但是除了这个已经排序好的这个元素其他的元素还没有排序完成,所以第二次排序就不需要考虑最后一个元素,且第二次以及后面的几次排序都需要从头开始到前一个排序完成的元素的前一个元素停止。

int  main()
{
	int a[10] = { 25,35,68,79,21,13,98,7,16,62 };//定义一个大小为10的数组
	int sz = sizeof(a) / sizeof(a[0]);
	int i=0, j=0;
	printf("排序过前的数顺序:\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d	", a[i]);
	}
	for (i = 1; i <= 9; i++)//外层循环是比较的轮数,数组内有10个数,那么就应该比较10-1=9轮
	{
		for (j = 0; j < sz-1 - i; j++)//内层循环比较的是当前一轮的比较次数,例如:第一轮比较9-1=8次,第二轮比较9-2=7次
		{
			if (a[j] > a[j + 1])//相邻两个数如果逆序,则交换位置
			{
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
	printf("\n排序过后的数顺序:\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d	", a[i]);
	}
	
	return 0;
}

在这里插入图片描述

  • 数组名是首元素地址
    在这里插入图片描述

10.结构体

结构体是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);

11. 操作符

算术操作符 + - * / %

移位操作符 >> <<

赋值操作符 = ,+= ,-= ,*=, /= ,&=, ^=, |=, >>=, <<=

单目操作符
在这里插入图片描述

关系操作符

=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”

逻辑操作符
&& 逻辑与
|| 逻辑或

条件操作符
exp1 ? exp2 : exp3

12.关键字

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

  • 关键字 typedef

typedef 顾名思义是类型定义,这里应该理解为类型重命名

//将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
typedef unsigned int uint_32;
int main()
{
    //观察num1和num2,这两个变量的类型是一样的
    unsigned int num1 = 0;
    uint_32 num2 = 0;
    return 0;
}
  • 关键字static

在C语言中:
static是用来修饰变量和函数的

  1. 修饰局部变量-称为静态局部变量
    2.== 修饰全局变量-称为静态全局变量==
  2. 修饰函数-称为静态函数
  • 修饰局部变量
/代码1
#include <stdio.h>
void test()
{
    int i = 0;
    i++;
    printf("%d ", i);
}
int main()
{
 int i = 0;
    for(i=0; i<10; i++)
   {
        test();
   }
    return 0;
}
//代码2
#include <stdio.h>
void test()
{
    //static修饰局部变量
    static int i = 0;
    i++;
    printf("%d ", i);
}
int main()
{
 int i = 0;
    for(i=0; i<10; i++)
   {
        test();
   }
    return 0;
}

  • 修饰全局变量
//代码1

int g_val = 2018;
int main()
{
    printf("%d\n", g_val);
    return 0;
}

//代码2

static int g_val = 2018;
int main()
{
    printf("%d\n", g_val);
    return 0;
}
  • 修饰函数
代码1
int Add(int x, int y)
{
    return c+y;
}
int main()
{
    printf("%d\n", Add(2, 3));
    return 0;
}

//代码2

static int Add(int x, int y)
{
    return c+y;
}
int main()
{
    printf("%d\n", Add(2, 3));
    return 0;
}

13.#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 = %d\n", sum);
    
    return 0;
}

14.指针

  • 什么是指针

指针是内存单元中最小单元的编号,也就是地址
指针一般是指针变量,是用来存放地址的变量
总结:指针就是地址,口语中说的指针通常指的是指针变量。

  • 内存

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地
址。

在这里插入图片描述

#include <stdio.h>
int main()
{
 int num = 10;
 &num;//取出num的地址
    //注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
 printf("%p\n", &num);//打印地址,%p是以地址的形式打印
 return 0;
}

int num = 10;
int *p;//p为一个整形指针变量
p =& num;

指针变量
我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个
变量就是指针变量

#include <stdio.h>
int main()
{
 int a = 10;//在内存中开辟一块空间
 int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
    //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
中,p就是一个之指针变量。
 return 0;
}

这里就有2的32次方个地址。
每个地址标识一个字节,那我们就可以给 (2^32Byte == 2^32/1024KB ==
232/1024/1024MB==232/1024/1024/1024GB == 4GB) 4G的空间进行编址。

  • 指针类型

char *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long pl = NULL;
float pf = NULL;
double pd = NULL;
char
类型的指针是为了存放 char 类型变量的地址。
short
类型的指针是为了存放 short 类型变量的地址。
int
类型的指针是为了存放 int 类型变量的地址。

  • 指针±整数
#include <stdio.h>
int main()
{
 int n = 10;
 char *pc = (char*)&n;
 int *pi = &n;
 
 printf("%p\n", &n);
 printf("%p\n", pc);
 printf("%p\n", pc+1);
 printf("%p\n", pi);
 printf("%p\n", pi+1);
 return  0;
}
  • 指针的解引用
#include <stdio.h>
int main()
{
 int n = 0x11223344;
 char *pc = (char *)&n;
 int *pi = &n;
 *pc = 0;   //重点在调试的过程中观察内存的变化。
 *pi = 0;   //重点在调试的过程中观察内存的变化。
 return 0;
}

char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

  • 野指针成因
  1. 指针未初始化
#include <stdio.h>
int main()
{ 
 int *p;//局部变量指针未初始化,默认为随机值
    *p = 20;
 return 0;
}
  1. 指针越界访问
#include <stdio.h>
int main()
{
    int arr[10] = {0};
    int *p = arr;
    int i = 0;
    for(i=0; i<=11; i++)
   {
        //当指针指向的范围超出数组arr的范围时,p就是野指针
        *(p++) = i;
   }
    return 0;
}
  1. 指针指向的空间释放

如何规避野指针

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放,及时置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性

指针±指针

int my_strlen(char *s)
{
       char *p = s;
       while(*p != '\0' )
              p++;
       return p-s;
}
  • 指针和数组
#include <stdio.h>
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,0};
    printf("%p\n", arr);
    printf("%p\n", &arr[0]);
    return 0;
}

在这里插入图片描述

可见数组名和数组首元素的地址是一样的。
结论:数组名表示的是数组首元素的地址。

int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,0};
    int *p = arr; //指针存放数组首元素的地址
    int sz = sizeof(arr)/sizeof(arr[0]);
    for(i=0; i<sz; i++)
   {
        printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p+i);
   }
    return 0;
}

在这里插入图片描述

所以 p+i 其实计算的是数组 arr 下标为i的地址。

int main()
{
 int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
 int *p = arr; //指针存放数组首元素的地址
 int sz = sizeof(arr) / sizeof(arr[0]);
 int i = 0;
 for (i = 0; i<sz; i++)
 {
 printf("%d ", *(p + i));
 }
 return 0;
}
  • 指针变量大小
//指针变量的大小取决于地址的大小
//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位平台是4个字节,64位平台是8个字节

15.二级指针

在这里插入图片描述

  • *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 20;
*ppa = &b;//等价于 pa = &b;
  • **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

指针数组

指针数组:是数组。是存放指针的数组。
例如:
int arr[5];
char arr[5];

在这里插入图片描述

  • 指针数组

arr1是一个数组,有五个元素,每个元素是一个整形指针。

  • 在这里插入图片描述

🍠🍠🍠本篇文章只是带大家走进C语言,让大家简单的了解C语言,很多细节没有详解,在接下来的文章中,我会对C语言的各个模块进行详解。感谢各位老铁支持。🍣🍣🍣

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值