C语言初阶学习-----01初识C语言

这是初识C语言,对有一定基础的同学帮助很大,看不懂的到以后对应的章节会详细介绍。
1.数据类型

char        //字符数据类型
short       //短整型
int         //整形
long        //长整型
long long   //更长的整形
float       //单精度浮点数
double      //双精度浮点数

每种类型的大小

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

运行结果截图:
在这里插入图片描述

sisizeof() 是一种内存容量度量函数,功能是返回一个变量或者类型的大小,单位为字节
1字节=8位二进制位,返回的类型为unsigned int 无符号整型(也就是说>=0).

2.变量、常量
2.1变量分为局部变量和全局变量
当局部变量和全局变量同名的时候 ,局部变量优先
例:

#include <stdio.h>
int global = 2019;//全局变量
int main()
{
    int local = 2018;//局部变量
    //下面定义的global会不会有问题?
    int global = 2020;//局部变量
    printf("global = %d\n", global);
    return 0; 
}

运行结果:
在这里插入图片描述

当在一个C文件中使用另一个C文件当中的全局变量时,需要使用extern关键字声明一下
例如:
在A03文件当定义的全局变量global在A02中使用时,只是要声明一下即可使用
在这里插入图片描述
在这里插入图片描述
A02运行的结果
在这里插入图片描述
2.2变量的作用域和生命周期
作用域
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用

而限定这个名字的可用性的代码范围就是这个名字的作用域。
1.局部变量的作用域是变量所在的局部范围。(即所在的代码块,也就是花括号{}括住的区域)
2.全局变量的作用域是整个工程。

生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
3. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
4. 全局变量的生命周期是:整个程序的生命周期

2.3常量
C语言中的常量分为以下以下几种:
字面常量
const 修饰的常变量
#define 定义的标识符常量
枚举常量

字面常量:3.14,100…

const 修饰的常变量

const float pai = 3.14f;//这里的pai是const修饰的常变量//是不能直接修改的!

这里 float pai;首先说明pai是个变量,const赋给了它常属性,本质上还是变量
在这里插入图片描述
#define 定义的标识符常量

#define _CRT_SECURE_NO_DEPRECATE 1
#include<stdio.h>
#define MAX 100
enum Color
{
	RED,
	GREEN,
	BLUE
};
int main()
{
	Color color = GREEN;
	printf("MAX=%d\n", MAX);
	printf("color=%d\n", color);
	printf("%d\n", RED);
	printf("%d\n", GREEN);
	printf("%d\n", BLUE);
}

枚举常量:可以一一列举的常量
默认从0开始
程序运行截图:
在这里插入图片描述
#define定义的值无法被修改:
在这里插入图片描述
枚举常量的值也无法修改
在这里插入图片描述
但是可以赋初值:
在这里插入图片描述
在这里插入图片描述

3.字符串+转义字符
3.1字符串
由双引号(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; 
}

运行结果:
在这里插入图片描述

分析:
因为char类型占1个字节所以arr1,arr2,arr3在内存的分布为:
在这里插入图片描述
数组名其实就是首元素地址
按照%s格式打印,就是从当前地址下,按照字节依次往后寻找’\0’,直到找到’\0’(’\0’在内存中为0)为止,才停止打印.
至于arr2打印出来的乱码我们单独拿出一个程序:

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'h','e','l','l','o' };
	printf("%s\n", arr);
	printf("%d\n", strlen(arr));
	return 0;
}

在内存中观看arr地址下的内容:
在这里插入图片描述
在这里插入图片描述
程序运行环境为x86地址线有32根,所以存放数据的地址为32位二进制位,也就是8位16进制位
程序在本次运行中,arr为0x008FF7FC,存放内容为’h’,我们往后依次观察内存中的内容
发现,在地址0x008FF80F存放的内容为0,
0x008FF80F-0x008FF7FC=19(10进制);
程序运行结果:
在这里插入图片描述
至于为什么是烫烫烫什么的,解释一下:
我们看0x008FF801下的内容为cc,
运行以下代码看到

#include<stdio.h>
int main()
{
	char ch = '烫';
	printf("%x\n", ch);
	return 0;
}

在这里插入图片描述
分析;%x为按照16进制打印,将ch提升为整形按照16进制打印,输出ffffffcc,ch只能存一个字节的内容,存的为低地址下的内容即cc.cc对应的字符为’烫’。

3.2转义字符
假如我们要在屏幕上打印一个目录: c:\code\test.c
直接运行以下代码:

#include<stdio.h>
int main()
{
	printf("c:\code\test.c");
	return 0;
}

运行结果:
在这里插入图片描述
转义字符顾名思义就是转变意思.
下面看一些转义字符。

? 在书写连续多个问号时使用,防止他们被解析成三字母词
’ 用于表示字符常量’
\“ 用于表示一个字符串内部的双引号
\ 用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a 警告字符,蜂鸣
\b 退格符
\f 进纸符
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ddd ddd表示1~3个八进制的数字。 如: \130 X
\xdd dd表示2个十六进制数字。 如: \x30 0

转义字符以\或者\x开头,以\开头表示后跟八进制形式的编码值,以\x开头表示后跟十六进制形式的编码值。
例题:

//程序输出什么?
#include <stdio.h>
#include<string。h>
int main()
{
    printf("%d\n", strlen("abcdef"));
    // \62被解析成一个转义字符
    printf("%d\n", strlen("c:\test\628\test.c"));
    return 0; 
}

分析:
strlen函数为计算字符串长度,也是从字符串起始地址开始,往后找’\0’,计算结果不包括’\0’
所以strlen(“abcdef”)=6.
而strlen(“c:\test\628\test.c”)为 \628 因为6<8 2<8 8=8 所以 \62为一个八进制数字
c : \t e s t \62 8 \t e s t . c
所以长度为14
运行结果:
在这里插入图片描述

4.操作符

算术操作符:+ - * / %
位移操作符:>> <<
位操作符:& ^ |
赋值操作符:= += -= *= /= &= ^= |= >>== <<==

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

关系操作符:
在这里插入图片描述

逻辑操作符:
在这里插入图片描述

条件操作符:
在这里插入图片描述

下标引用、函数调用和结构成员
在这里插入图片描述

5.常见关键字

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

5.1关键字 typedef
typedef 顾名思义是类型定义,这里应该理解为类型重命名。 就是起别名的意思

在下例中,我们将unsigned int重命名位uint_32,

//将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;
}

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

  1. 修饰局部变量-称为静态局部变量
  2. 修饰全局变量-称为静态全局变量
  3. 修饰函数-称为静态函数

5.2.1修饰局部变量

观察以下两个代码及运行结果:

//代码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运行结果:
在这里插入图片描述

代码2运行结果:
在这里插入图片描述
对比代码1和代码2的效果理解static修饰局部变量的意义。
结论:
static修饰局部变量改变了变量的生命周期
让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。

其实就是被static修饰的局部变量生命周期延长了,main函数结束才销毁。

5.2.2修饰全局变量

//代码1
//add.c
int g_val = 2018;
//test.c
#include <stdio.h>
extern  int g_val;
int main()
{
    printf("%d\n", g_val);
    return 0;
}








//代码2
//add.c
static int g_val = 2018;
//test.c
#include <stdio.h>
extern  int g_val;
int main()
{
    printf("%d\n", g_val);
    return 0;
}

代码1运行结果:
在这里插入图片描述
代码二:
在这里插入图片描述

代码1正常,代码2在编译的时候会出现连接性错误。

结论:
一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使
用。

5.2.3修饰函数

一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用

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

在这里插入图片描述
7.指针!

7.1内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。
所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。
1个字节为8个二进制位。
为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址
在这里插入图片描述
变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。取出变量地址如下:

#include<stdio.h>
int main()
{
	int num = 10;
	printf("%p", &num);
	return 0;
}

%p为按照地址形式打印

在这里插入图片描述
因为int类型占四个字节,所以num在内存的存储为
在这里插入图片描述

那么如何存储变量的地址呢?需要定义指针变量

#include<stdio.h>
int main()
{
	int num = 10;
	int* p = &num;
	*p = 20;
	printf("p=%p\n", p);
	printf("&num=%p\n", &num);
	printf("num=%d\n", num);
	return 0;
}

运行截图:
在这里插入图片描述

*说明p是一个指针变量,也就是存放地址的变量,int说明p存放的地址为一个int类型的地址。

*p=20 表示将p存放的地址(也就是num的地址)下的内容修改为20
这里的星表示 解引用操作。

以整形指针举例,可以推广到其他类型,如:

#include<stdio.h>
int main()
{
	char ch = 'w';
	char* pc = &ch;
	*pc = 'q';
	printf("&ch=%p\n", &ch);
	printf("pc=%p\n", pc);
	printf("ch=%c\n", ch);
	return 0;
}

在这里插入图片描述

7.2指针变量的大小

指针变量的大小取决于地址的大小
32位平台下地址是32个bit位(即4个字节)
64位平台下地址是64个bit位(即8个字节)

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

32位平台下:
在这里插入图片描述
在这里插入图片描述:

64位平台下:
在这里插入图片描述
在这里插入图片描述
结论:指针大小在32位平台是4个字节,64位平台是8个字节

8.结构体

结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。比如描述学生,学生包含:名字+年龄+性别+学号这几项信息。
这里只能使用结构体来描述了。
例如:

#include<stdio.h>
struct Stu
{
	char name[20]; //姓名
	int age;  //年龄
	char sex[5];  //性别
	char id[15];  //学号
};
int main()
{
	//打印结构体信息三种方式
	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);
	printf("name = %s age = %d sex = %s id = %s\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).id);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值