1.变量与常量

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

//局部变量:{}内的变量
//全局变量:{}外的变量

//局部变量的作用域是变量所在的局部范围
//全局变量的作用域是整个工程

//局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束
//全局变量的生命周期是:整个程序的生命周期

enum Sex
{
MALE,
FEMALE,
SECRET
};

int main()
{
//{1} 3; 字面常量

//{2}const - 常属性
//const int num=4;
//printf("%d\n",num);
//num=8; 会报错 num的值不会变 num为const修饰的常变量 num本质上还是变量,只是具有了常属性:int a[10] = {0}; (没有问题)
//printf("%d\m",num);
//int n = 10; (n是变量)
//const char* a; //定义一个指向字符常量的指针,这里,a是一个指向 char* 类型的常量, //int a[n] = { 0 };(有问题,[]里面要是常量)
char const* a; //const修饰的是*a,*a的值为const,不能修改。 //const int n = 10;//(n还是变量)
//int a[n] = {0};(有问题)//printf("%d\m",num);
//char*const a; //const修饰的是a,可以直接改变指针指向的值,但不能直接改变指针指向
//const在*后面,才修饰指针,指针指向不可改变; const在*前面,修饰指向的对象,指向对象内容不能改变

//{3} #define 定义的标识符常量
//#include <stdio.h>
//#define MAX 10

//{4} 枚举常量
//枚举 - 列举
//性别:男,女,保密
//三原色:红,黄,蓝
//星期:1,2,3,4,5,6,7
//枚举关键 - enum

//MALE,FEMALE,SECRET - 枚举常量
enum Sex s = FEMALE; //s是可以改变的,常量是指MALE,FEMALE,SECRET是不可改的
s = MALE;
printf("%d\n", MALE); //输出0
printf("%d\n", FEMALE); //输出1
printf("%d\n", SECRET); //输出2
return 0;
}

2.操作符

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int a = 5 / 2;
printf("%d\n", a);//会强制转化为整数类型
int b = 5 % 2;//取模


//移(2进制)位操作符
// << 左移
// >> 右移
int c = 1;
//整形1占4个字节-32bit位
//00000000000000000000000000000001
//左移一个位 左边丢弃一个0在最右边补上一个0 - 00000000000000000000000000000010 - 2
int d = c << 1;
printf("%d\n", d);//输出2
printf("%d\n", c);//c是不变的


//位(2进制)操作符
// & 按位与
// | 按位或
// ^ 按位异或
int x = 3;
int y = 5;
int z = x & y;
int n = x | y;
int m = x ^ y;//不是次方,是异或
//3: 011 二进制序列:1 1 1 1
//5: 101 1*2^3 1*2^2 1*2^1 1*2^0
//z: 001 &:全部为真才为1 n: 111 |:一个为真就为1 m:110 ^:对应的二进制位相同为0 8 4 2 1
printf("%d\n", z); //对应的二进制位相异为1 //3=2+1 : 0 0 1 1
printf("%d\n", n); //5=4+1 : 0 1 0 1
printf("%d\n", m); //13=8+4+1 : 1 1 0 1


int s = 10;
s = 20;//=叫赋值 ==叫判断相等
s = s + 10;
s += 10;//等价与上面的式子
s = s - 20;
s -= 20;
s = s & 2;
s &= 2;


//a+b; +两边各有一个操作数所以叫双目操作符
//c 语言中 0表示假 非0表示真
int w = 10;
printf("%d\n", w);
printf("%d\n", !w);


int k = 10;
int arr[10] = { 0 };//十个整型元素的数据
//sizeof 计算变量/空间所占空间的大小,单位是字节
printf("%d\n", sizeof(k));//大小是4 括号可省略
printf("%d\n", sizeof(int));//大小是4 括号不可省略
printf("%d\n", sizeof(arr));//10*4


int q = 0;
int e = ~q;
//~ -- 按(二进制)位取反
//q:000000000000000000000000000000000
//e:111111111111111111111111111111111
printf("%d\n", e);//输出-1,打印的是这个数的原码
//原码、反码、补码 只要是整数,内存中存储的都是二进制的补码
//负数在内存中存储的时候,存储的是二进制的补码 正数--原码,反码,补码都相同
//11111111111111111111111111111111 补码 原码 -- 反码 -- 补码
//11111111111111111111111111111110 反码 直接按照正负 原码的符号不变 反码+1
//10000000000000000000000000000001 原码 写出的二进制序列 其他位按位取反


int r = 10;
int u = r++;//后置++,先把r的值10赋给u,再把r++
printf("r=%d u=%d\n", r, u);


//int i = 3.14;会报错
int i = (int)3.14;//将double转化为int类型


int o = 10;
int p = 20;
int max = 0;
// (exp1 ? exp2 : exp3)
max=(o > p ? o : p);//若o>p为真,表达式exp2执行,即o的值赋给max,若o>p为假,表达式exp3执行,即p的值赋给max

return 0;

}
//操作符

//算术操作符
//+ - * / %

//位移操作符
// >> <<

//位操作符
// & ^ |

//赋值操作符
// = += -= /= &= ^= |= >>= <<=
//
//单目操作符: ! 逻辑反操作
// - 负值
// + 正值
// & 取地址
// sizeof 操作符的类型长度
// ~ 对一个数的二进制按位取反
// -- 前置,后置--
// ++ 前置,后置++
// * 问接访问操作符(
//双目操作符
//三目操作符

//关系操作符
// > >= < <= == !=

//逻辑操作符
// && ||

//条件操作符
// exp1 ? exp2 : exp3(也是三目操作符)

//逗号操作符
// exp1,exp2,exp3,....expN

//下标引用,函数调用,结构成员
// [] () . ->

3.关键字

static int g_val = 2020;//g_val在加了static后从全局变量变成了静态的全局变量 - 只能在自己所在的源文件内部使用

static int Add(int x, int y)
{
int z = x + y;
return z;
}

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//#define定义的标识符常量
//#define MAX 100
//#define

//static 修饰局部变量
//局部变量的生命周期变长

//static 修饰全局变量
//改变了变量的作用域-让静态的全局变量只能在自己所在的源文件内部使用

//static 修饰函数
//改变了函数的链接属性
//普通的函数具有外部链接属性但被static修饰之后就变成了内部链接属性

void test()
{
static int a = 1;//a变成静态的局部变量 - a+1变成2在函数结束后会销毁,等再次进入函数的时候会再次创建a,但变成静态局部变量后,不会被销毁
a++;
printf("i=%d\n", a);//2 3 4 5 6 a不会再被赋值为1
}


int Max(int x, int y)//函数
{
if (x > y)
return x;
else
return y;
}

#define MAX(X,Y) (X>Y?X:Y)//宏

int main()
{
//int a = 10;//局部变量,也叫自动变量 本来局部变量的前面都有一个auto但一般省略


register int b = 20;//建议把b定义成寄存器变量


int c = 10;
c = -2;
//int定义的变量是有符号的
//signed int和int是等价的
unsigned int num = -1;//此时num是无符号变量,永远是个正数


//struct 结构体关键字


//uniom 联合体/共用体


//typedef 类型定义 - 类型重定义
typedef unsigned int uint;
unsigned int sum = 20;
uint sum2 = 20; //sum的类型和sum2是完全相同的


int i = 0;
while (i < 5)
{
test();
i++;
}

extern int g_val;//extern - 声明外部符号的 - 不申明的话g_val就会显示未定义
printf("%d\n", g_val);//没有static之前可以输出2020


extern int Add(int, int);//声明外部函数
int n = 10;
int m = 20;
int add = Add(n, m);
printf("add = %d\n", add);//没有static之前可以输出30


//define定义的标识符常量
//#define Max 1000
//define定义宏
//#define ADD(x,y)
int l = 10;
int t = 20;
//函数
int max = Max(l, t);
printf("max=%d\n", max);
//宏的定义
max = MAX(l, t); //max=(l>t?l:t)
printf("max=%d\n", max);
return 0;
}
//常见关键字
//auto break case char const contine default do double else enum
//extern float for goto if int long register return short signed
//sizeof static struct switch typedef uniom unsigned void volatile while

4.函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int Add(int x, int y)
{
int z = x + y;
return z;
}

int main()
{
int num1 = 10;
int num2 = 20;
int sum = 0;
int a = 100;
int b = 200;
//sum=sum1+sum2
sum = Add(num1, num2); //num1对应的是x,num2对应的是y,z的返回值对应的是sum
//sum=a+b
sum = Add(a, b); //a对应的是x,b对应的是y,z的返回值对应的是sum
printf("sum = %d\n", sum);
return 0;
}

5.结构体

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include <stdio.h>

struct Book
{
char name[20];
short price;
};

int main()
{
//利用结构体类型--创建一个该类型的结构体变量
struct Book b1 = { "c语言程序设计",20 };
printf("书名是%s\n", b1.name);
printf("价格是%d元\n", b1.price);
b1.price = 30;
printf("更改后的价格是%的%d\n", b1.price);
struct Book* p = &b1;
//改变b1.name对应的字符要用到strcpy
strcpy(b1.name, "C++");//strcpy--string copy--字符串拷贝--库函数--string.h
//printf("书名是%s\n", (*p).name);
//printf("价格是%d\n", (*p).price); //. 结构体变量.成员
printf("书名是%s\n", p -> name); //-> 结构体指针->成员
printf("价格是%d\n", p -> price);
return 0;
}

6.数组

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

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

int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//定义一个存放10个整数数字的数组
//arr: 1 2 3 4 5 6 7 8 9 10
//下标:0 1 2 3 4 5 6 7 8 9 下标默认从0开始
//char ch[20];
//float arr2[5]
//printf("%d\n", arr[4]); 下标的方式访问元素
int i = 0;
while (i < 10)
{
printf("%d", arr[i]);
i++;
}

return 0;
}

7.指针

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//指针大小在32位平台上是4个字节,64位平台上是8个字节

int main()
{
int a = 10;//4个字节
//&a:取地址
//printf("%p\n", &a);
int* p = &a;//用来存放地址的--指针地址
printf("%p\n",p);//输出地址 //%p--以地址的形式打印
*p = 20;// *:解引用符 // *p--p地址对应的值
printf("a = %d\n", *p);

char ch = 'w';
char *pc = &ch;
*pc = 'a';
printf("ch = %c\n", *pc);


return 0;
}

8.转义字符

#define _CRT_SECURE_NO_WARNINGS 1

#include <string.h>
#include <stdio.h>

/*int main()
{
printf("abcn"); 输出abcn
printf("abc\n"); 输出abc然后换行
return 0;
}*/

int main()
{
printf("c:\test\32\test.c\n"); //\t - 水平制表符 - tab
printf("%d\n", strlen("c:\test\32\test.c")); //c : \t e s t \32 \t e s t . c 有13个字节
//\32 -- 32是2个8进制数 (8进制数字只有0-7的组成)
//32作为8进制数代表的那个十进制数字,作为ASCII码值,对应的字符
//32这个8进制数字 -> 10进制数字 26 -> 以26为代表的ASCII码值对应的字符
printf("%c\n", '\x61');
return 0;
}
// 转义字符 释义
// \? -- 在书写连续多个问号时使用,防止它们被解析成三字母词 (古老的编译器可用)
// \' -- 用于表示字符常量'
// \" -- 用于表示一个字符串内部的双引号
// \\ -- 用于表示一个反斜杠,防止它被解释为一个转义字符
// \a -- 警告字符,蜂鸣
// \b -- 退格符
// \f -- 进纸符
// \n -- 换行
// \r -- 回车
// \t -- 水平制表符
// \v -- 垂直制表符
// \ddd -- ddd表示1-3个八进制的数字。如:\130 X
// \xdd -- dd表示2个十六进制的数字。如:\x30 0

9.字符串

#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include <stdio.h>

int main()
{
//"adada"; "hello adsd"; "";(空字符串)
//这种由双引号引起的一串字符称为字符串字面值,或者简称字符串。
char arr1[] = "abc";//数组 有四个元素 'a' 'b' 'c' '\0'--'\0'是字符串的结束标志,不是字符串的内容 '\0'是转义字符
char arr2[] = { 'a','b','c'};// 有三个元素 'a' 'b' 'c'
//printf("%s\n", arr1); //输出abc
//printf("%s\n", arr2); //输出abc+乱码,当在'c',后面加个0或'\0'才会输出abc

printf("%d\n", strlen(arr1)); //长度为3,\0不算做内容 //strlen - string length - 计算字符串的长度
printf("%d\n", strlen(arr2)); //随机值,随机找到\0后停止

return 0;
}