赞
踩
VS2019按F10进行代码调试。监视窗口在调试-窗口
里面打开;内存窗口在调试-内存
里面打开
数据类型的作用:创建对应大小的内存空间,以存放数据。
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数
每种数据类型的大小(内存空间)多少?
#include <stdio.h>
int main()
{
//sizeof: 关键字 - 操作符 - 计算类型或者变量所占空间的大小
printf("%d\n", sizeof(char)); //1
printf("%d\n", sizeof(short)); //2
printf("%d\n", sizeof(int)); //4
printf("%d\n", sizeof(long)); //4
printf("%d\n", sizeof(long long)); //8
printf("%d\n", sizeof(float)); //4
printf("%d\n", sizeof(double)); //8
printf("%d\n", sizeof(long double)); //16
return 0;
}
注:C语言标准: sizeof(long) >= sizeof(int)
#include <stdio.h>
int main()
{
int arr[10] = {0};
printf("%d\n", sizeof(arr)); //40 - 数组总大小
printf("%d\n", sizeof(arr[0])); //4 - 单个元素大小
printf("%d\n", (sizeof(arr)/sizeof(arr[0])); //10 - 计算元素个数
//sizeof(arr) 等价于 sizeof arr。所以sizeof不是函数
return 0;
}
为什么出现这么多数据类型?
答:存在这么多的类型,其实是为了更加丰富的表达生活中的各种值。类型丰富的时候,选择性更多,空间利用率更高(选择最适合当前情况的类型)。
变量:能被改变的量。(局部变量 + 全局变量)
常量:不能改变的量。
推荐写法:int age = 20;
即:创建变量的时候赋予初始值
不推荐:int age;
当局部变量和全局变量名字冲突的情况下,局部变量优先。写代码时不建议将全局变量和局部变量写成一样的。
作用域:变量可用的代码范围。
局部变量的作用域是变量所在的局部范围。(所属那一层的{}中间)
全局变量的作用域是整个工程。(1次定义,跨文件用
extern
声明 -> 跨文件全局变量)
例:在 a.c 文件中定义全局变量int flag_global = 0;
。 在 b.c 文件中用到flag_global
时,要先声明:extern int flag_global;
生命周期:变量的创建到变量的销毁之间的一个时间段。
局部变量:进入局部范围为生命周期的开始,出局部范围为生命周期的结束。
全局变量:整个程序(main函数)的生命周期。
字面常量(无意义)
3.14;
10;
'a';
"abcdef";
const
修饰的常变量(本质:变量)
被 const
修饰变量具有常属性:该变量的值无法被更改。
const int sum = 10;
const int n = 10;
int arr[n] = {0}; //n为变量,数组的下标必须为常量,这样会报错
#define
定义的标识符常量
#define Max 1000
枚举常量(用于可以一一列举的常量)
enum Sex
{
//赋初值
MALE, //0
FEMALE, //1
SECRET //2
}; //括号中的MALE,FEMALE,SECRET是枚举常量。默认从0开始,每次增加1。
enum Sex s = MALE; //定义
字符串就是一串字符-双引号引起来的一串字符。结束标志:\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); //bit strlen(arr1) = 3
printf("%s\n", arr2); //bit+乱码 strlen(arr2) = 随机值
printf("%s\n", arr3); //bit strlen(arr3) = 3
return 0;
}
//strlen():求字符串长度的函数(不包括结束标志\0) 头文件:string.h
转义字符:转变了字符原有的意思。
#include <stdio.h>
int main()
{
printf("c:\code\test.c\n"); //输出结果 c:code est.c
return 0;
}
转义字符 | 释义 |
---|---|
\' | 用于表示字符常量’ |
\" | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义符 |
\t | 水平制表符 |
\r | 回车 |
\n | 换行 |
\ddd | ddd 表示1~3个八进制的数字。 如: \130 X(ASCII码值是88=\130) |
\xdd | dd 表示2个十六进制数字。 如: \x30 0 |
ASCII码表:每一个字符(对应printf
的%c)都有一个值。 printf("%c\n", '\130');
//程序输出多少?
#include <stdio.h>
int main()
{
printf("%d\n", strlen("c:\test\628\test.c")); //输出结果:14
return 0;
}
//
:C++注释风格
/* .......... */
:C语言注释风格 缺陷:不能嵌套注释,遇到第一个*/
就结束了。
代码中有不需要的代码可以直接删除,也可以注释掉
代码中有些代码比较难懂,可以加一下注释文字
参数是函数与函数间的交流方式。
函数的特点就是简化代码,代码复用。
函数的括号无法省略。
数组:一组相同类型元素的集合。使用下标来访问,下标从0开始。
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素
char ch[5] = {'a', 'b', 'c'};//不完全初始化,剩余的元素默认为0
9/2 -> 4
9.0/2 -> 4.5
[]:下标引用操作符
arr[5]
的[]
为下标引用操作符。数组定义时的[]
不是下标引用操作符。():函数调用操作符 调用函数的时候,函数后面的
()
就是函数调用操作符。
~ & | ^(按位异或)
符号 | 作用 |
---|---|
! | 逻辑反操作(0为假,非0为真) |
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数的类型长度(以字节为单位) |
~ | 对一个数的二进制按位取反 |
– | 前置、后置– |
++ | 前置、后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
整数在内存中存储的是补码。
#include <stdio.h>
int main()
{
int a = 0;
printf("%d\n", ~a); //输出结果:-1
return 0;
}
前置表达式的值
#include <stdio.h>
int main()
{
int a = 10;
int b = ++a; //b的值取决于表达式++a的结果
printf("%d\n", b); //输出结果:11
printf("%d\n", a); //输出结果:11
return 0;
}
后置表达式的值
#include <stdio.h>
int main()
{
int a = 10;
int b = a++; //b的值取决于表达式a++的结果
printf("%d\n", b); //输出结果:10
printf("%d\n", a); //输出结果:11
return 0;
}
&& 逻辑与
|| 逻辑或
! 逻辑非
exp1 ? exp2 : exp3
exp1成立,整个表达式的结果为exp2的结果;exp1不成立,整个表达式的结果为exp3的结果
exp1, exp2, exp3, … , expN
逗号表达式是从左向右依次计算的,整个表达式的结果是最后一个表达式的结果。
#include <stdio.h>
int main()
{
int a = 0;
int b = 3;
int c = 5;
int d = (a = b + 2, c = a -4, b = c + 2); //a=5, c=1, b=3
printf("%d\n", d); //输出结果:3
return 0;
}
常见关键字:
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
auto
:自动创建,自动销毁。局部变量都是auto
类型,基本都省略掉auto
(现如今意义不大)。
register int num = 100;
建议将num
的值存放在寄存器中。 大量、频繁被使用的数据,放到寄存器中,提高效率(现如今意义不大)。
define
和include
不是关键字,属于预处理指令。
类型重命名 -> 别名
typedef unsigned int uint_32;
static是用来修饰变量和函数的
static修饰局部变量改变了变量的生命周期
静态局部变量出了作用域依然存在,到程序结束,生命周期才结束(本质是改变了变量的存储类型)。
//代码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(); //打印10个1 } 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(); //打印1 2 3 4 5 6 7 8 9 10 } return 0; }
一个全局变量被
static
修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。全局变量,在其他源文件内部可以被使用,是因为全局变量具有外部链接属性。但是被
static
修饰后,就变成了内部链接属性,其他源文件就不能链接到这个静态的全局变量了。
//代码1
//add.c
int g_val = 2018;
//test.c
int main()
{
printf("%d\n", g_val);
return 0;
}
//代码2
//add.c
static int g_val = 2018;
//test.c
int main()
{
printf("%d\n", g_val);
return 0;
}
一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
本质:
static
将函数的外部链接属性变成了内部链接属性!(和static
修饰的全局变量一样)
//代码1
//add.c
int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//代码2
//add.c
static int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
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;
}
指针就是地址。
32位机器 - 32根地址线 - 物理线 - 通电 - 1/0
一个内存单元是一个字节,然后分配地址。&a
只会拿出第一个字节的地址。
int *pa = &a; //pa是存放地址的,存放地址的变量称为指针变量。
*
说明pa是指针变量; int
说明pa指向的对象是 int
类型的。
指针变量的大小:
#include <stdio.h>
//指针变量的大小取决于地址的大小
//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个字节。
结构体的目的:有能力描述复杂对象,创造关于复杂对象的新类型。
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); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。