初始C语言从HelloWorld到指针

Holle world

#include <stdio.h>

// int 是整形的意思
// main前面的int表示main函数会返回一个整形值
int main()  // 主函数-程序的入口, main函数有且只有一个
{
	printf("Hello world! \n")
	return 0;  // return 0 与开头的int main对应
}

"恭喜你C语言毕业啦"

C语言与Python差别 — 输出
在C中输出函数为 printf(), 该函数没有换行功能需自己加上(哇好麻烦)

输出 printf()

int main() // 主函数-程序的入口, main函数有且只有一个
{
	printf("hello world \n");
	char ch = "AAA";
	printf("%c \n", ch);   // %c  --- 打印字符格式的数据

	char age = 20;
	printf("%d \n", age);  // %d  --- 打印整形十进制数据

	return 0; 
}

输入函数 scanf()

int main()
{
	int num1 = 0;
	int num2 = 0;
	int sum = 0;

	// 输入数据-使用输入函数scanf
	// 这里为输入两个整数
	scanf("%d%d", &num1, &num2);

	//int sum = 0; // C语言语法规定,变量要定义在当前代码块的最前面
	sum = num1 + num2;

	printf("sum = %d \n", sum);

	return 0;
}

数据类型

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

int main()
{
	printf("%d \n", sizeof(char)); // 1    //一个字节8个比特位
	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  

	short int age = 20; //短整型2字节16个比特位-- 2^16-1 = 65535    

	return 0;
}

格式化输出

  • %d 打印整数
  • %s 打印字符串
  • %p 以地址形式打印(地址一般是十六进制)
  • %f 打印浮点数(小数)
  • %c 打印字符(整形数会被转成unsigned char型打印出)

变量

C语言语法规定,变量要先声明变量类型

int num = 2021;

局部变量与全局变量


int num = 100;  // 全局变量- 定义在( '{}' ) 之外的变量

int main()
{
	int num = 10; // 局部变量

	return 0;
}

常量

字面常量

555  //这就是字面常量...

常变量

  • const 使用这个关键字修饰使之具有常属性,本质还是变量所以叫做常变量
int main() 
{
	// const 修饰的常变量
	const int num = 4;

	return 0;
}

标识符常量

  • #define 定义标识符常量
// 定义标识符常量 NUM
#define NUM 10

int main() 
{
	printf("%d \n", NUM)

	return 0;
}

枚举常量

  • 枚举关键字enum
//枚举关键字 - enum
enum Sex
{
	MALE,
	FEMALE,
	SECRET
};

int main()
{
	enum Sex s = FEMALE;
	printf("%d \n", MALE);
	printf("%d \n", FEMALE);
	printf("%d \n", SECRET);

	return 0;
}

转义字符

\转义序列符

  • \\ 用于表示一个反斜杠,防止它被解释为一个转义序列符
  • \a 警告字符,蜂鸣
  • \b 退格符(Tab)
  • \f 进制符
  • \n 换行
  • \r 回车
  • \t 水平制表符
  • \v 垂直制表符
  • \ddd ddd表示1~3ge八进制数字
  • \xdd dd表示2个十进制数字
int main()
{
	//    \ddd     ddd 代表1~3个八进制数字   如: \311  但是 \985 就不行, 因为八进制里没有8   
	//  \32 会被转义--- 3 2就是2个八进制的数字
	// 转义后: 3 2 作为八进制代表的那个十进制数字, 作为ASCII码值对应的字符
	// 3 2 转换为十进制--26  ""
	printf("%c \n", '\32');

	//    \xdd     dd表示2个十六进制数字    
	printf("%c \n", '\x66');  // 66 对应的十进制为102对应的ASCII码值是 f
	return 0;
}

在这里插入图片描述

字符串

  • char 字符类型

"字sdsfsada符sfasdf串"
这种由双引号引起来的一串字符称为字符串字面值, 简称字符串

int main()
{

	char arr1[] = "abc";  // 使用数组表示字符串 // 
	// "abc" -- 'a' 'b' 'c' '\0'  -- "\0"是字符串的结束标识

	char arr2[] = { 'a', 'b', 'c'}; // 这个没有加 \0 就会出现随机
	//char arr2[] = { 'a', 'b', 'c' , '\0'};

	printf("%s \n", arr1);
	printf("%s \n", arr2);

	return 0;
}

注意: 字符串的结束标志是一个 \0 的转义字符. 在计算字符串长度的时候 \0 是结束标志, 不算字符串内容

操作符

单目操作符

  • ! 逻辑反操作
  • - 负值
  • + 正值
  • & 取地址
  • sizeof 操作数的类型长度(以字节为单位)
  • **~**对一个数的二进制按位取反
  • -- 前置\后置--
  • ++ 前置\后置++
  • * 间接访问操作符(解引用操作符)
  • (类型) 强制类型转换

取余/取商%

int main()
{
	int a = 5 / 2;  // "/" 取商 -- 2
	printf("%d \n", a);

	int b = 5 % 2;  // '%' 取余 -- 1
	printf("%d \n", b);
	return 0;
}

移位操作符>>,<<

int main()
{
	//  >> 右移    << 左移        (移的是2进制位)
	// 左移-- 吧二进制整体去掉最左边一位, 然后在最右边 补0, 这样实现左移
	int c = 1;
	// 整形 占4个字节--32个bit位  
	// 00000000000000000000000000000001
	int d = c << 1;  // 左移1位 -- 00000000000000000000000000000010  得到 d=2
	int e = c << 2;  // 左移2位 -- 00000000000000000000000000000100  得到 e=4
	// 在进行位移操作时 c 本身不会变, 就是被移位的数本身不会发生变化
	printf("c的值: %d \n", c);
	printf("d的值: %d \n", d);
	printf("e的值: %d \n", e);
	printf("c的值: %d \n", c);
	return 0;
}

位操作$ | ^

int mian()
{
	//    &  按 位 与  ----  对位相同则为真(1), 对位不同为假(0)
	//    |  按 位 或  ----  对位之间有一个真(1)则为真(1), 对位都是假(0)则为假(0)
	//    ^  按位异或  ----  对位不同则为真(1), 对位相同为假(0)

	int f = 3;       // 3的二进制: 011
	int h = 5;       // 5的二进制: 101
	int i = f & h; // 按 位 与:  0→1=0, 1→0=0, 1→1=1  所以 i 的二进制: 001  转换为十进制就是 1
	int j = f | h; // 按 位 或:  0→1=1, 1→0=1, 1→1=1  所以 j 的二进制: 111  转换为十进制就是 7
	int k = f ^ h; // 按位异或:  0→1=1, 1→0=1, 1→1=0  所以 k 的二进制: 110  转换为十进制就是 6
	printf("3和5按位与得(i): %d \n", i);
	printf("3和5按位或得(j): %d \n", j);
	printf("3和5按位或得(k): %d \n", k);
	return 0;
}

逻辑操作符&& ||

int main()
{
	//    &&    逻辑与  并且的意思
	//    ||    逻辑或  或者的意思
	int m = 6; // -- 真
	int n = 3; // -- 真
	int o = 0; // -- 假
	int p = m && n;   // m 和 n 有两个值都为真(非0),结果就为真(1), 否则为假(0)   -- 结果 1
	int q = m && o;   // m 和 n 有两个值都为真(非0),结果就为真(1), 否则为假(0)   -- 结果 0
	int r = m || n;   // n 和 o 有一个值为真(非0), 结果就为真(1), 否则为假(0)    -- 结果 1
	int s = m || o;   // n 和 o 有一个值为真(非0), 结果就为真(1), 否则为假(0)    -- 结果 1 
	printf("逻辑与 p 的值 %d \n", p); 
	printf("逻辑与 q 的值 %d \n", q);
	printf("逻辑或 r 的值 %d \n", r);
	printf("逻辑或 s 的值 %d \n", s);
	return 0;
}

条件运算符

int main()
{
	//  exp1 ? exp2 : exp3
	int u = 10;
	int v = 20;
	int max = (u > v ? u : v);  // 如果u > v为真则max的值为u, 否则为v
	int min = (u < v ? u : v);	// 如果u < v为真则max的值为u, 否则为v 
	printf("max的值: %d \n", max);
	printf("mix的值: %d \n", min);
	return 0;
}

"Python里三元运算符"
a=b if b>5 elif 0     // a等于b, 如果b>5结果是a等于b, 否则a等于0
原码反码补码
 只要是整数, 内存中存储的都是二进制的补码, 
 --- 正数的原码,反码,补码相同
 原码== 直接按照正负写出的二进制序列
 反码 == 原码的符号位变, 其他位取反得到
 补码 == 反码+1

      -2  的原码反码补码
 10000000000000000000000000000010  -- 原码
 11111111111111111111111111111101  -- 反码
 11111111111111111111111111111110  -- 补码

if语句

int main()
{
	int num = 0;
	printf("你会点赞收藏吗?(1/0) \n");
	scanf("%d", & num);
	if (num == 1)
		printf("感谢感谢 \n");
	else
		printf("好家伙! \n");
	return 0;
}

while 循环

int main()
{
	int num = 0;

	while (num < 20000)
	{
		printf("num的值: %d \n", num);
		num++;
	}
	if (num >= 20000)
		printf("循环已经退出 %d  \n", num);

	return 0;
}

数组


int main()
{
	// 定义一个存放7个整数数字的数组
	int arr_list[7] = {1, 2, 3, 5, 6, 8, 9};
	int i = 0;
	// 使用数组
	while (i < 7)
	{
		//printf("i的值:%d , 取到的值: %d \n", &i, &arr_list[i]);  // 不知道这样写为啥会错!!!
		printf("i的值:%d ", i);
		printf("取到的值: %d \n", arr_list[i]);
		i++;
	}
	return 0;
}

函数

// 定义了一个名叫 Add的函数, 注意语法
int Add(int a, int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int x = 66;
	int y = 77;
	int num1 = 98498;
	int num2 = 46451;
	int num = 0;

	num = Add(num1, num2);

	printf("num的值:  %d  \n", num);

	return Add(x, y);
}

static修饰符

  • 修饰局部变量-----> 静态局部变量
  • 修饰全局变量-----> 静态全局变量
  • 修饰函数----> 静态函数

修饰局部变量

void testfunc()
{
	// a = 1;
	// 如果没有加上 static 进行修饰打印结果为 1 1 1 1 1
	// 修饰后打印结果为 2 3 4 5 6
	static int a = 1;
	a++;
	printf("a = %d \n", a);
}

int main()
{
	int i = 0;
	// 创建循环, 执行五次testfunc函数
	while (i < 5)
	{
		testfunc();
		i++;
	}
	return 0;
}

static 修饰局部变量,会使局部变量的生命周期变长

修饰全局变量

  • 在另一个.c文件定义全局变量
  • static int g_num = 2021;  // 定义全局变量
    

int main()
{
	// extern -- 声明外部符号(引入外部变量)
	// 此时因为 外部变量 g_num 已经被static修饰,无法使用
	extern int g_num;
	printf("g_num = %d \n", g_num);
	return 0;
}

static修饰全局变量, 改变变量的作用域–使静态的全局变量只能在其自己所在的源文件内部使用, 出啦原文件就无法使用啦

修饰函数

  • 在另一个.c文件定义一个函数并修饰
  •    // 修饰后在外部就无法使用啦                     
    static int Add(int a, int b)
    {
      int c = a + b;
      return c;
    }
    
声明外部函数--就是引入外部函数
// 外部函数被修饰就引不进来啦
extern int Add(int, int);

int main()
{
	int num = Add(5, 6);
	printf("num= %d \n", num);
	return 0;
}

宏定义

// #define 定义标识符常量
//#define NUM 100

// 宏 
#define MAX(X,Y) (X>Y?X:Y)
// 可以吧 MAX 看成一个比较大小的函数....
// 宏定义真的有点方便...不用指定数据类型,函数的参数要指定参数类型

int main()
{
	// 使用宏
	int num = MAX(5, 6);
	printf("num= %d \n", num);
	return 0;
}

指针

  • 先说我的理解
  • 指针就是存放一个数据对象的地址, 不管那个数据对象所占用多少个字节,指针所占用的空间为4或者8个字节, 通过解引用操作符可以反向取指针所存的那片地址内存放的东西,
  • 例: 你有很多钱存放在窝窝村2栋101号别墅内, 这个窝窝村2栋101别墅就是地址, 然后创建指针,指针的内容记录这个地址, 然后一个好心人拿到你的地址, 就可以找到你的钱
/*****  指针  ****/
//指针变量在32位计算机中占4个字节(32个比特位)
//指针变量在64位计算机中占8个字节(64个比特位)

int main()
{
	int a = 10; // 4个字节
	//printf("%p \n", &a); // & 取地址
	//printf("%d \n ", a); 

	int* p = &a; // 指针变量 --- 用来存放地址的变量
	//printf("%p \n", p); // p 在这里就是一个int类型的指针变量
	//printf("%d \n", *p); // 解引用操作符/间接访问操作符
	*p = 2020; //  *  解引用操作符, 获取指针变量所存地址对应的内容并修改
	printf("%d \n", a);
	return 0;
}

结构体

存储负值的数据对象使用,比如存放一个人的信息或是一本书的信息

// 创建结构体 
struct Book
{
	char name[20];
	short price;
};

int main()
{
	// 利用结构体类型创建一个该类型的结构体变量 b1
	struct Book b1 = { "数据结构", 19 };
	printf("结构书名: %s \n", b1.name);
	printf("结构价钱: %d \n", b1.price);
	b1.price = 29;
	printf("修改后结构价钱: %d \n", b1.price);

	return 0;
}

这个结构体跟python中的类好相似啊

结构体指针与字符串拷贝strcpy

#include <string.h>


int main()
{
	// 利用结构体类型创建一个该类型的结构体变量
	struct Book b1 = { "数据结构", 19 };

	//创建一个结构体指针
	struct Book* sb = &b1;
	// 利用指针打印书名与价钱
	//  .   :先使用*语法解析为结构体变量, 然后结构体变量.name
	//  ->  :直接使用指针->name
	printf("指针书名: %s \n", (*sb).name); // 第一种方式
	printf("指针书名: %s \n", sb->name); // 第二种方式

	//??    strcpy     ??//
	// strcpy == string copy -- 字符串拷贝 库函数<string.h>
	strcpy(b1.name, "算法导论");

	printf("修改书名: %s \n", b1.name);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值