c#title: C语言基础
6.创建并运行第一个C程序
集成开发环境(IDE)
编译器/C语言中的指令-机器指令
VC6版本
安装虚拟机+VC6建议学习
同学帮助安装
编写C程序
1.创建项目,选择win32控制台项目(Win32 console Application)
文件-新建-Win32 console Application(项目名字为时间的顺序2020_06_16)
2.添加文件
文件-新建-C++ Source File-Main.cpp
3.生成项目(编译):*.exe
#include <stdio.h>
int main()
{
printf("Hello,World!\n");
getchar();
return 0;
}
F7(出现00error为程序已经创建成功)
2020_06_15.exe - 0 error(s), 0 warning(s)
4.运行项目
F5
cpp为C++文件
shift+F 程序结束
debug版本(调试版本)
release版本(发布版本) 编译器会优化掉一部分无用代码
7.内存与变量
内存的使用
内存的单位是字节(Byte) 每个字节占8个位(bit)
每个运行中的程序(进程)都有4G内存
内存的编号就是地址
内存不是内存条,是空头支票
变量类型
变量就是内存
变量类型就是告诉系统(编译器)我需要的内存有多大
变量名告诉系统(编译器)我需要的内存在哪里,变量名是地址的别名
值是写到内存里的数据
变量类型 变量名称 = 值;
十六进制为"%x"
十进制为"%d"
数据到底存在哪里?
取地址符号==&==
//变量类型 变量名(就是内存编号) 变量值
char x = 10;
short y = 100;
int z = 1000;
//打印内存中的数值
printf("值为:%d-%d-%d\n",x,y,z);
printf("值为:%x-%x-%x\n",x,y,z);
&符号可以帮助我们获取指定的变量的地址:
printf("变量内容为:%d-%d-%d\n",x,y,z);
printf("变量地址为:%p-%p-%p\n",&x,&y,&z)
溢出范围
溢出的右移,舍弃
char //0 - 0xFF
short //0 - 0xFFFF
int //0 - 0xFFFFFFFF
浮点型变量的使用
每种类型的变量,存储的数据都是有范围,超过这个范围的数据,将会被计算机丢弃,如:
float x = 100.12f; //4字节,float后面跟f
double y = 100.1234;//8字节(范围很大)
printf("%f %lf\n",x,y);//%f与%lf分别是存储float与double的形式
printf("%.2f %.4lf\n",x,y);//显示小数点后几位,.2位或者.4位定义输出的小数点位数
总结
变量类型 | 变量宽度(字节byte)16进制 | 存储范围 |
---|---|---|
char | 1 | -128~127 |
short | 2 | -32768~32767 |
int | 4 | -2147483648~2147483747 |
float | 4(精度:整数+小数6-7) | -3.4·1038~3.4·1038 |
double | 8(15-16) | -1.7·10308~1.7·10308 |
课后练习
1.如何理解内存
一个内存为一个字节
2.如何理解内存编号
内存编号就是内存地址,别名就是变量名
3.分别使用char、short、int、float、double申请内存,并用 printf 正确输出对应内容和地址
#include<stdio.h>
char a = 10;
short b = 100;
int c = 100;
float e = 50.12f;
double f = 3432.3423;
int main()
{
printf("%d %d %d %f %lf\n", a,b,c,e,f);
printf("%d %d %d %.2f %.4f\n",a,b,c,e,f);
printf("%x %x %x %x %x\n",a,b,c,e,f);
printf("%p %p %p %p %p\n",a,b,c,e,f);
getchar();
return 0;
}
3.为什么要使用变量
回顾
char 一个字节、
short 四个内存
int 八个字节
使用&地址符号,获得当前地址的内存
编译器替我们是申请
内存太多,使用编号代替,一个内存的编号就是地址,一个地址里面代表一个字节,一个字节就是八个0或者1
#include<stdio.h>
//变量类型 变量名字 值
int main()
{
char x = 10;//可以放进程序里面可以放到程序外面,但是如果放进程序里面,仅仅是当前程序使用,其他程序无法使用
printf("%d",x);
getchar();
return 0;
}
放到函数里面必须有一个明确的初始值
放到函数外面称为全局变量
为什么要使用变量
变量本身是一个内存
变量的本质是容器,里面可以存储任意类型的数据
实例
可以根据用户输入圆的半径,计算出圆的面积。
#include <stdio.h>
#define PI 3.14//定义常量
int main()
{
double r;
double s;
scanf("%lf",&r);//变量的地址在哪里,控制台就会读入一个数,放入r的地址。
s = PI*r*r;
printf("%lf \n",r);
printf("%.4lf\n",s);
getchar();
getchar();
}
常量是一个数,不会变化
用变量是为了临时储存数据
内存就是变量
变量命名规则
- 只能由字符,数字,下划线
- 第一个符号不能是数字
- 变量名不能是关键字
小端存储模式
#include <stdio.h>
char a = 0x12;//一个字节
short b = 0x1234;.//两个字节
int c = 0x12345678;//四个字节
printf("%p,%p,%p \n",&x,&y,&z)
大端小端针对的是数据超过1个字节的存储
小端模式:数据低位在内存地址编号低位,数据高位在高位
大端模式:数据高位在内存地址编号低位,数据高位在低位
程序在断点才可以看memory
float使用二进制规范存储,将小数点变为二进制IEEE规则
#include <stdio.h>
int main()
{
char x = 0x12;
short y = 0x1234;
int z = 0x12345678;//12 34 56 78
//0019FF28-0019FF24
//78 56 34 12
printf("%p,%p,%p\n,"&x,&y,&z);
getchar();//断点在getchar不能看memory
return 0;
}
使用小手选择断点调试
getchar()因为程序一直在运行,所以无法进行调试,需要删除掉
选择断点-把要看的变量名输入到address输入框中-查看存储的内存地址
原码反码补码
回顾
如何让程序运行到某阶段的存储下来
浮点型有自己的存储规范,课堂上不涉及
当存储的12时是12,负数的时候存储的是EE
原码反码补码
原码:最高位为符号位,其余各位为数据本身的绝对值
0X12 = 0001 0010;//正数,最高位0正,最高位1为负
反码:
正数:反码与原码相同
负数:符号位为1,其余位取反
补码:
正数:补码与原码相同
负数:符号位为1,其余位对原码取反加1
0x12 0001 0010
原码:0001 0010
反码:0001 0010
补码:0001 0010
-0x12 EE
原码:1001 0010//符号位为1,负数
反码:1110 1101//符号位为1,取反
补码:1110 1110 //末位+1
E E
计算机存储整数的时候存储补码
有符号数与无符号数
谁能告诉我下面的1代码表示什么?
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
#include <stdio.h>
int main()
{
int x = 0xFFFFFFFF;
prinf("%u,%d\n",x,x);
return 0;
}
%u:无符号数的输出标记
%d:有符号数的输出标记
有符号数与无符号数在存入内存的时候是相同的,比如
int a = -1;
unsigned a = -1;
//此两者在存储时是相同的,存入内存的数值都是
//FFFF FFFF
#include <stdio.h>
int main()
{
unsigned char x = 0xFF;//1111 1111
unsigned int y = x;//0000 0000 1111 1111
int y = x;//1111 1111 1111 1111
printf("%p,%p\n",x,y);
return 0;
}
%x:十六进制输出标记
%p:类似于地址,全部位输出标记
有符号数与无符号数区别
- 拓展的时候有差异
#include <stdio.h>
int main()
{
char x = 0xFF;
printf("%x\n",x);
int y = x;
printf("%x\n",y);
unsigned char a = 0xFF;
printf("%x\n",a);
unsigned int b = a;
printf("%x\n",b);
getchar();
return 0;
}
计算结果如下:
ffffff ff//拓展成四个字节打印
fffff ff//有符号数,使用符号位进行补位
ff//无符号数
ff//无符号数
- 比较的时候有差异
#include <stdio.h>
int main()
{
unsigned int a = -1;
if (a>1)
{
printf("%p",a);
}
return 0;
}
总结
- 无论有符号数与无符号数,内存存储的方式是一样的,补码
- 有符号数与无符号数在使用的时候,主要的区别是:
<1>拓展的时候
<2>运算的时候
只有整数才有有符号与无符号之分
浮点数另算
字符与字符串
单引号==’ '==只是单个字符
ACSII表
A-65
a-97
putchar()
只能打印一个字符,给他任何数字都会进行查表,然后输出表的对应值
转义字符 \a = 7, \n = 10
#include <stdio.h>
void main()
{
char buffer[6] = {
'H','e','l','l','o','!'};
printf("%s",buffer);
}
结果:因为没有0结束,会出现一些别的打印结果
所谓字符串是以数组的形式来表示的
输出打印字符串需要见到0才能停止,当数组扩大,会自动补0
一般情况下不用指明长度,编译器会计算长度,自动补0。
字符串的来由
- 字符串其实是一对字符组成的
- 字符就是ASCII码对应得到的
- ASCII码对照的是十进制数
- 存入的是十进制数的二进制数
中文字符
英文字符查表,中文如何操作的呢?
中文也有值,每个中文字有两个字节的占格
计算机发明之后及后面的很长一段时间,只用应用于美国及一些西方国家
我们专家把那些127之后的奇异符号们(EASCII)取消掉
规定两个大于127的数定义为汉字,字符等,全角
GB2312
Win32-unicode本质就是查表
8.数组
为什么要使用数组
数组是连续申请一些内存供应使用
数组的地址是第一个数组的地址
如果我们要存储多人的年龄
能否让编译器分配多一点的int
void main()
{
int age[20];//向编译器申请了40个字节的空间
}
数组的初始化
整数是小端存储
int age[20] = {
0};//初始化全部为0
- 定义时是不初始化,如:
int age[20];
- 定义时直接初始化,如:
int age[10] = {
1,2,3,4,5,6,7,8,9,10}
- 定义时部分初始化,如:
int age[10] = {
1,2,3,4,5};
数组的使用
越界/当你取数组中的数值时,假设数组中有10个值,age[10],值已经越界。
通过下标访问数组
其他类型的数组
char arr[10];
short arr[20];
int arr[20];
使用watch来查看你申请得到的数组内的值
查看-调试-watch-右边输入名称
训练
- 创建一个长度为10的整型数组,并为这个数组赋值(值是下标的2倍);
- 将上题中数组的第一个元素与最后一个元素的值交换。
#include <stdio.h>
void main()
{
int arr[10]={
0,3,4,6,8,10,12,14,16,18};
int a;
printf("交换前:%d %d\n",arr[0],arr[9]);
a = arr[0];
arr[0] = arr[9];
arr[9] = a;
printf("交换后:%d %d\n",arr[0],arr[9]);
}
二维数组
解决问题
name | math | chinese | english |
---|---|---|---|
小明 | 89 | 67 | 67 |
小黄 | 73 | 42 | 65 |
小红 | 56 | 56 | 47 |
47 | 78 |
int score[12] = {
...}
//寻找
第x个同学,第y门课
score[x*3+y]
直接告诉编译器几人几科
int score[3][2] = {
...};//二维数组
int score[0][0];//第一人第一科
int score[1][1];//第二人第二科
int score[2][2];//第三人第三科
二维数组与数组在存储方式上是相同的,不同工作主要是由编译器运作,二维数组就是一维数组
修改的情况下直接修改可以
二维数组的初始化形式
int arr[3][4]={
1,2,3,4,
5,6,7,8,
9,7,6,5
}
int arr[3][4]={
{
1,2,3,4},
{
5,6,7,8},
{
9,7,6,5}
}
int arr[3][4]={
{
1,2},
{
5},
{
9}
}
int arr[][4]={
1,2,3,4,
5,6,7,8,
9,10,11,12
}//自动分配少数补0
第二个维度必须指定
初始化写{0}即可
多维数组
多维数组
int arr[3][4][5] ={
{
{
1,2,3},{
4,5,6},{
7,8,9},{
10,11,12,14}},
{
<