C语言笔记(2)-数据类型

本文围绕C语言数据类型展开,介绍了常量与变量的概念、声明和定义区别,阐述了整数、字符型、实型等数据类型的特点及使用,还讲解了进制转换、计算机内存数值存储方式(原码、反码、补码),以及字符串格式化输出和输入等内容。

2. 数据类型

2.1 常量与变量

2.1.1 关键字

在这里插入图片描述

2.1.2 数据类型

数据类型的作用:编译器预算对象(变量)分配的内存空间大小

在这里插入图片描述

2.1.3 常量

常量:

  • 在程序运行过程中,其值不能被改变的量
  • 常量一般出现在表达式或赋值语句中
整型常量100,200,-100,0
实型常量3.14 , 0.125,-3.123
字符型常量‘a’,‘b’,‘1’,‘\n’
字符串常量“a”,“ab”,“12356”
2.1.4 变量
1. 变量
  • 在程序运行过程中,其值可以改变
  • 变量在使用前必须先定义,定义变量前必须有相应的数据类型

标识符命名规则:

  • 标识符不能是关键字
  • 标识符只能由字母、数字、下划线组成
  • 第一个字符必须为字母或下划线
  • 标识符中字母区分大小写

变量特点:

  • 变量在编译时为其分配相应的内存空间
  • 可以通过其名字地址>访问相应内存

在这里插入图片描述

2. 声明和定义区别
  • 声明变量不需要建立存储空间,如:extern int a;
  • 定义变量需要建立存储空间,如:int b;
#include <stdio.h>

int main()
{
	//extern 关键字只做声明,不能做任何定义,后面还会学习,这里先了解
	//声明一个变量a,a在这里没有建立存储空间
	extern int a;
	a = 10;	//err, 没有空间,就不可以赋值

	int b = 10;	//定义一个变量b,b的类型为int,b赋值为10

	return 0;
}

从广义的角度来讲声明中包含着定义,即定义是声明的一个特例,所以并非所有的声明都是定义:

  • int b 它既是声明,同时又是定义

  • 对于 extern b来讲它只是声明不是定义

一般的情况下,把建立存储空间的声明称之为“定义”,而把不需要建立存储空间的声明称之为“声明”

2.1.5 使用示例
#include <stdio.h>
#define MAX 10 //声明了一个常量,名字叫MAX,值是10,常量的值一旦初始化不可改

int main()
{
	int a;	//定义了一个变量,其类型为int,名字叫a

	const int b = 10; //定义一个const常量,名为叫b,值为10
	//b = 11; //err,常量的值不能改变

	//MAX = 100;	//err,常量的值不能改变

	a = MAX;//将abc的值设置为MAX的值
	a = 123;

	printf("%d\n", a); //打印变量a的值

	return 0;
}

2.2 整数:int

2.2.1 整型变量的定义和输出
打印格式含义
%d输出一个有符号的10进制int类型
%o(字母o)输出8进制的int类型
%x输出16进制的int类型,字母以小写输出
%X输出16进制的int类型,字母以大写输出
%u输出一个10进制的无符号
#include <stdio.h>

int main()
{
	int a = 123;	//定义变量a,以10进制方式赋值为123
	int b = 0567;	//定义变量b,以8进制方式赋值为0567
	int c = 0xabc;	//定义变量c,以16进制方式赋值为0xabc

	printf("a = %d\n", a);
	printf("8进制:b = %o\n", b);
	printf("10进制:b = %d\n", b);
	printf("16进制:c = %x\n", c);
	printf("16进制:c = %X\n", c);
	printf("10进制:c = %d\n", c);
	
	unsigned int d = 0xffffffff; //定义无符号int变量d,以16进制方式赋值
	printf("有符号方式打印:d = %d\n", d);
	printf("无符号方式打印:d = %u\n", d);
	return 0;
}

在这里插入图片描述

2.2.2 整型变量的输入
#include <stdio.h>

int main()
{
	int a;
	printf("请输入a的值:");

	//不要加"\n"
	scanf("%d", &a);
	printf("a = %d\n", a); //打印a的值
    
	return 0;
}

2.2.3 short、int、long、long long
数据类型占用空间
short(短整型)2字节
int(整型)4字节
long(长整形)Windows为4字节,Linux为4字节(32位),8字节(64位)
long long(长长整形)8字节

注意:

  • 整型数据在内存中占的字节数与所选择的操作系统有关。虽然 C 语言标准中没有明确规定整型数据的长度,但 long 类型整数的长度不能短于 int 类型, short 类型整数的长度不能长于 int 类型
  • 当一个小的数据类型赋值给一个大的数据类型,不会出错,因为编译器会自动转化。但当一个大的类型赋值给一个小的数据类型,那么就可能丢失高位
整型常量所需类型
10代表int类型
10l, 10L代表long类型
10ll, 10LL代表long long类型
10u, 10U代表unsigned int类型
10ul, 10UL代表unsigned long类型
10ull, 10ULL代表unsigned long long类型
打印格式含义
%hd输出short类型
%d 输出int类型
%ld输出long类型
%lld输出long long类型
%hu输出unsigned short类型
%u输出unsigned int类型
%lu 输出unsigned long类</型
%llu输出unsigned long long类型
#include <stdio.h>

int main()
{
	short a = 10;
	int b = 10;
	long c = 10l; //或者10L
	long long d = 10ll; //或者10LL

	printf("sizeof(a) = %u\n", sizeof(a));
	printf("sizeof(b) = %u\n", sizeof(b));
	printf("sizeof(c) = %u\n", sizeof(c));
	printf("sizeof(c) = %u\n", sizeof(d));

	printf("short a = %hd\n", a);
	printf("int b = %d\n", b);
	printf("long c = %ld\n", c);
	printf("long long d = %lld\n", d);

	unsigned short a2 = 20u;
	unsigned int b2 = 20u;
	unsigned long c2= 20ul; 
	unsigned long long d2 = 20ull; 

	printf("unsigned short a = %hu\n", a2);
	printf("unsigned int b = %u\n", b2);
	printf("unsigned long c = %lu\n", c2);
	printf("unsigned long long d = %llu\n", d2);

	return 0;
}

输出:

sizeof(a) = 2
sizeof(b) = 4
sizeof(c) = 8
sizeof(c) = 8
short a = 10
int b = 10
long c = 10
long long d = 10
unsigned short a = 20
unsigned int b = 20
unsigned long c = 20
unsigned long long d = 20
2.2.4 有符号数和无符号数区别
1. 有符号数

有符号数是最高位为符号位,0代表正数,1代表负数

#include <stdio.h>

int main()
{
	signed int a = -1089474374; //定义有符号整型变量a
	printf("%X\n", a); //结果为 BF0FF0BA

	//B    F    0    F    F    0    B	 A
	//1011 1111 0000 1111 1111 0000 1011 1010

	return 0;
}

输出: BF0FF0BA

2. 无符号数

无符号数最高位不是符号位, 而就是数的一部分,无符号数不可能是负数

在这里插入图片描述

#include <stdio.h>

int main()
{
	unsigned int a = 3236958022; //定义无符号整型变量a
	printf("%X\n", a); //结果为 C0F00F46

	return 0;
}

当我们写程序要处理一个不可能出现负值的时候,一般用无符号数,这样可以增大数的表达最大值

3. 有符号和无符号整型取值范围
数据类型占用空间取值范围
short2字节-32768 到 32767 ( − 2 15 -2^{15} 215 ~ 2 15 ^{15} 15-1)
int4字节-2147483648 到 2147483647 ( − 2 31 -2^{31} 231 ~ 2 31 2^{31} 231-1)
long4字节-2147483648 到 2147483647( − 2 31 -2^{31} 231 ~ 2 31 2^{31} 231-1)
unsigned short2字节0 到 65535 (0 ~ 2 16 ^{16} 16-1)
unsigned int4字节0 到 4294967295 (0 ~ 2 32 ^{32} 32-1)
unsigned long4字节0 到 4294967295 (0 ~ 2 32 ^{32} 32-1)

2.3 sizeof 关键字

  • sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节
  • sizeof的返回值为size_t
  • size_t类型在32位操作系统下是unsigned int,是一个无符号的整数
#include <stdio.h>

int main()
{
	int a;
	int b = sizeof(a);//sizeof得到指定值占用内存的大小,单位:字节
	printf("b = %d\n", b);

	size_t c = sizeof(a);
	printf("c = %u\n", c);//用无符号数的方式输出c的值

	return 0;
}

输出:

b = 4
c = 4

2.4 字符型:char

2.4.1 字符变量的定义和输出

字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,其中每个字符变量都会占用 1 个字节。在给字符型变量赋值时,需要用一对英文半角格式的单引号(' ')把字符括起来

字符变量实际上并不是把该字符本身放到变量的内存单元中去,而是将该字符对应的 ASCII 编码放到变量的存储单元中。char的本质就是一个1字节大小的整型

#include <stdio.h>

int main()
{
	char ch = 'a';
	printf("sizeof(ch) = %u\n", sizeof(ch));

	printf("ch[%%c] = %c\n", ch); //打印字符
	printf("ch[%%d] = %d\n", ch); //打印‘a’ ASCII的值

	char A = 'A';
	char a = 'a';
	printf("a = %d\n", a);		//97
	printf("A = %d\n", A);	//65

	printf("A = %c\n", 'a' - 32); //小写a转大写A
	printf("a = %c\n", 'A' + 32); //大写A转小写a

	ch = ' ';
	printf("空字符:%d\n", ch); //空字符ASCII的值为32
	printf("A = %c\n", 'a' - ' '); //小写a转大写A
	printf("a = %c\n", 'A' + ' '); //大写A转小写a

	return 0;
}

输出结果:

sizeof(ch) = 1
ch[%c] = a
ch[%d] = 97
a = 97
A = 65
A = A
a = a
空字符:32
A = A
a = a
2.4.2 字符变量的输入
#include <stdio.h>

int main()
{
	char ch;
	printf("请输入ch的值:");

	//不要加“\n”
	scanf("%c", &ch);
	printf("ch = %c\n", ch); //打印ch的字符

	return 0;
}

输出:

请输入ch的值:a
ch = a
2.4.3 ASCII 对照表
ASCII值 控制字符 ASCII值 字符 ASCII值 字符 ASCII值 字符
0NUT32(space)64@96
1SOH33!65A97a
2STX34"66B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92/124|
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL

ASCII 码大致由以下两部分组成:

  • ASCII 非打印控制字符: ASCII 表上的数字 0-31 分配给了控制字符,用于控制像打印机等一些外围设备
  • ASCII 打印字符:数字 32-126 分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。数字 127 代表 Del 命令
2.4.4 转义字符
转义字符含义ASCII****码值(十进制)
\a警报007
\b 退格(BS) ,将当前位置移到前一列008
\f 换页(FF),将当前位置移到下页开头012
\n 换行(LF) ,将当前位置移到下一行开头010
\r 回车(CR) ,将当前位置移到本行开头013
\t 水平制表(HT) (跳到下一个TAB位置)009
\v 垂直制表(VT)011
\\ 代表一个反斜线字符""092
\' 代表一个单引号(撇号)字符039
\" 代表一个双引号字符034
\? 代表一个问号063
\0 数字0000
\ddd 8进制转义字符,d范围0~73位8进制
\xhh16进制转义字符,h范围09,af,A~F3位16进制

注意:红色字体标注的为不可打印字符

#include <stdio.h>

int main()
{
	printf("abc");
	printf("\refg\n"); //\r切换到句首, \n为换行键

	printf("abc");
	printf("\befg\n");//\b为退格键, \n为换行键

	printf("%d\n", '\123');// '\123'为8进制转义字符,0123对应10进制数为83
	printf("%d\n", '\x23');// '\x23'为16进制转义字符,0x23对应10进制数为35

	return 0;
}

输出结果:

efg
abefg
83
35

2.5 实型(浮点型):float、double

实型变量也可以称为浮点型变量,浮点型变量是用来存储小数数值的。在C语言中, 浮点型变量分为两种: 单精度浮点数(float)、 双精度浮点数(double), 但是double型变量所表示的浮点数比 float 型变量更精确。

由于浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字。在有效位以外的数字将被舍去,这样可能会产生一些误差。

不以f结尾的常量是double类型,以f结尾的常量(如3.14f)是float类型

#include <stdio.h>

int main()
{
	//传统方式赋值
	float a = 3.14f; //或3.14F
	double b = 3.14;

	printf("a = %f\n", a);
	printf("b = %lf\n", b);

	//科学法赋值
	a = 3.2e3f; //3.2*1000 = 3200,e可以写E
	printf("a1 = %f\n", a);

	a = 100e-3f; //100*0.001 = 0.1
	printf("a2 = %f\n", a);

	a = 3.1415926f;
	printf("a3 = %f\n", a); //结果为3.141593

	return 0;
}

输出结果:

a = 3.140000
b = 3.140000
a1 = 3200.000000
a2 = 0.100000
a3 = 3.141593

2.6 进制

进制也就是进位制,是人们规定的一种进位方法。 对于任何一种进制—X进制,就表示某一位置上的数运算时是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位

十进制二进制八进制十六进制
0000
1111
21022
31133
410044
510155
611066
711177
81000108
91001119
10101012A
11101113B
12110014C
13110115D
14111016E
15111117F
16100002010
2.6.1 二进制

二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”

当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的

术语含义
bit(比特)一个二进制代表一位,一个位只能表示0或1两种状态。数据传输是习惯以“位”(bit)为单位。
Byte(字节)一个字节为8个二进制,称为8位,计算机中存储的最小单位是字节。数据存储是习惯以“字节”(Byte)为单位。
WORD(双字节)2个字节,16位
DWORD两个WORD,4个字节,32位
1b1bit,1位
1B1Byte,1字节,8位
1k,1K1024
1M(1兆)1024k, 1024*1024
1G1024M
1T1024G
1Kb(千位)1024bit,1024位
1KB(千字节)1024Byte,1024字节
1Mb(兆位)1024Kb = 1024 * 1024bit
1MB(兆字节)1024KB = 1024 * 1024Byte

十进制转化二进制的方法:用十进制数除以2,分别取余数和商数,商数为0的时候,将余数倒着数就是转化后的结果

在这里插入图片描述

十进制的小数转换成二进制:小数部分和2相乘,取整数,不足1取0,每次相乘都是小数部分,顺序看取整后的数就是转化后的结果

在这里插入图片描述

2.6.2 八进制

八进制,Octal,缩写OCT或O,一种以8为基数的计数法,采用0,1,2,3,4,5,6,7八个数字,逢八进1。一些编程语言中常常以数字0开始表明该数字是八进制

八进制的数和二进制数可以按位对应(八进制一位对应二进制三位),因此常应用在计算机语言中

在这里插入图片描述

十进制转化八进制的方法:

用十进制数除以8,分别取余数和商数,商数为0的时候,将余数倒着数就是转化后的结果

在这里插入图片描述

2.6.3 十六进制

十六进制(英文名称:Hexadecimal),同我们日常生活中的表示法不一样,它由0-9,A-F组成,字母不区分大小写。与10进制的对应关系是:0-9对应0-9,A-F对应10-15

十六进制的数和二进制数可以按位对应(十六进制一位对应二进制四位),因此常应用在计算机语言中

在这里插入图片描述

十进制转化十六进制的方法:

用十进制数除以16,分别取余数和商数,商数为0的时候,将余数倒着数就是转化后的结果

在这里插入图片描述

2.6.4 C语言如何表示相应进制数
十进制以正常数字1-9开头,如123
八进制以数字0开头,如0123
十六进制以0x开头,如0x123
二进制C语言不能直接书写二进制数
#include <stdio.h>

int main()
{
	int a = 123;		//十进制方式赋值
	int b = 0123;		//八进制方式赋值, 以数字0开头
	int c = 0xABC;	//十六进制方式赋值

	//如果在printf中输出一个十进制数那么用%d,八进制用%o,十六进制是%x
	printf("十进制:%d\n",a );
	printf("八进制:%o\n", b);	//%o,为字母o,不是数字
	printf("十六进制:%x\n", c);

	return 0;
}

输出:

十进制:123
八进制:123
十六进制:abc

2.7 计算机内存数值存储方式

原码, 反码, 补码 详解

2.7.1 原码

一个数的原码(原始的二进制码)有如下特点:

  • 最高位做为符号位,0表示正,为1表示负
  • 其它数值部分就是数值本身绝对值的二进制数
  • 负数的原码是在其绝对值的基础上,最高位变为1

下面数值以1字节的大小描述:

十进制数原码
+150000 1111
-151000 1111
+00000 0000
-01000 0000

原码表示法简单易懂,与带符号数本身转换方便,只要符号还原即可,但当两个正数相减或不同符号数相加时,必须比较两个数哪个绝对值大,才能决定谁减谁,才能确定结果是正还是负,所以原码不便于加减运算

2.7.2 反码
  • 对于正数,反码与原码相同
  • 对于负数,符号位不变,其它部分取反(1变0,0变1)
十进制数反码
+150000 1111
-151111 0000
+00000 0000
-01111 1111

反码运算也不方便,通常用来作为求补码的中间过渡

2.7.3 补码

在计算机系统中,数值一律用补码来存储

补码特点:

  • 对于正数,原码、反码、补码相同
  • 对于负数,其补码为它的反码加1
  • 补码符号位不动,其他位求反,最后整个数加1,得到原码
十进制数补码
+150000 1111
-151111 0001
+00000 0000
-00000 0000
#include <stdio.h>

int main()
{
	int  a = -15;

	printf("%x\n", a);
	//结果为 fffffff1
	//fffffff1对应的二进制:1111 1111 1111 1111 1111 1111 1111 0001
	//符号位不变,其它取反:1000 0000 0000 0000 0000 0000 0000 1110
	//上面加1:1000 0000 0000 0000 0000 0000 0000 1111  最高位1代表负数,就是-15

	return 0;
}
2.7.4 补码的意义

示例1:用8位二进制数分别表示+0和-0

十进制数原码
+00000 0000
-01000 0000
十进制数反码
+00000 0000
-01111 1111

不管以原码方式存储,还是以反码方式存储,0也有两种表示形式。为什么同样一个0有两种不同的表示方法呢?

但是如果以补码方式存储,补码统一了零的编码:

十进制数补码
+00000 0000
-010000 0000由于只用8位描述,最高位1丢弃,变为0000 0000

示例2:计算9-6的结果

以原码方式相加:

十进制数原码
90000 1001
-61000 0110

在这里插入图片描述

结果为-15,不正确。

以补码方式相加:

十进制数补码
90000 1001
-61111 1010

在这里插入图片描述

最高位的1溢出,剩余8位二进制表示的是3,正确

在计算机系统中,数值一律用补码来存储主要原因是:

  • 统一了零的编码
  • 将符号位和其它位统一处理
  • 将减法运算转变为加法运算
  • 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃
2.7.5 数值溢出

当超过一个数据类型能够存放最大的范围时,数值会溢出

有符号位最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失

数据类型占用空间取值范围
char1字节-128到 127(-2 7 ^{7} 7 ~ 2 7 ^{7} 7-1)
unsigned char1字节0 到 255(0 ~ 2 8 ^{8} 8-1)
#include <stdio.h>

int main()
{
	char ch;

	//符号位溢出会导致数的正负发生改变
	ch = 0x7f + 2; //127+2
	printf("%d\n", ch);
	//	0111 1111
	//+2后 1000 0001,这是负数补码,其原码为 1111 1111,结果为-127

	//最高位的溢出会导致最高位丢失
	unsigned char ch2;
	ch2 = 0xff+1; //255+1
	printf("%u\n", ch2);
	//	  1111 1111
	//+1后 10000 0000, char只有8位最高位的溢出,结果为0000 0000,十进制为0

	ch2 = 0xff + 2; //255+1
	printf("%u\n", ch2);
	//	  1111 1111
	//+1后 10000 0001, char只有8位最高位的溢出,结果为0000 0001,十进制为1

	return 0;
}
2.7.5.c: In function ‘main’:
2.7.5.c:15:8: warning: unsigned conversion from ‘int’ to ‘unsigned char’ changes value from ‘256’ to ‘0[-Woverflow]
  ch2 = 0xff+1; //255+1
        ^~~~
2.7.5.c:20:8: warning: unsigned conversion from ‘int’ to ‘unsigned char’ changes value from ‘257’ to ‘1[-Woverflow]
  ch2 = 0xff + 2; //255+1
        ^~~~
tao@Taoc:~/Desktop/C/2$ ./2.7.5 
-127
0
1

2.8 类型限定符

限定符含义
extern声明一个变量,extern声明的变量没有建立存储空间。 extern int a;//变量在定义的时候创建存储空间
const定义一个常量,常量的值不能修改。 const int a = 10;
Volatile防止编译器优化代码
register定义寄存器变量,提高效率。register是建议型的指令,而不是命令型的指令,如果CPU有空闲寄存器,那么register就生效,如果没有空闲寄存器,那么register无效。

2.9 字符串格式化输出和输入

2.9.1 字符串常量
  • 字符串是内存中一段连续的char空间,以’\0’(数字0)结尾
  • 字符串常量是由双引号括起来的字符序列,如“china”、“C program”,“$12.5”等都是合法的字符串常量

字符串常量与字符常量的不同:

在这里插入图片描述

每个字符串的结尾,编译器会自动的添加一个结束标志位’\0’,即 “a” 包含两个字符’a’和’\0

2.9.2 printf函数和putchar函数

printf是输出一个字符串,putchar输出一个char

printf格式字符:

打印格式对应数据类型含义
%dint接受整数值并将它表示为有符号的十进制整数
%hdshort int短整数
%huunsigned short无符号短整数
%ounsigned int无符号8进制整数
%uunsigned int无符号10进制整数
%x,%Xunsigned int无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF
%ffloat单精度浮点数
%lfdouble双精度浮点数
%e,%Edouble科学计数法表示的数,此处"e"的大小写代表在输出时用的"e"的大小写
%cchar字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
%schar *字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符)
%pvoid *以16进制形式输出指针
%%%输出一个百分号

printf附加格式:

字符含义
l(字母l)附加在d,u,x,o前面,表示长整数
-左对齐
m(代表一个整数)数据最小宽度
0(数字0)将输出的前面补上0直到占满指定列宽为止不可以搭配使用-
m.n(代表一个整数)m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度,用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。
#include <stdio.h>
int main()
{
	int a = 100;
	printf("a = %d\n", a);//格式化输出一个字符串
	printf("%p\n", &a);//输出变量a在内存中的地址编号
	printf("%%d\n");

	char c = 'a';
	putchar(c);//putchar只有一个参数,就是要输出的char
	long a2 = 100;
	printf("%ld, %lx, %lo\n", a2, a2, a2);

	long long a3 = 1000;
	printf("%lld, %llx, %llo\n", a3, a3, a3);

	int abc = 10;
	printf("abc = '%6d'\n", abc);
	printf("abc = '%-6d'\n", abc);
	printf("abc = '%06d'\n", abc);
	printf("abc = '%-06d'\n", abc);

	double d = 12.3;
	printf("d = \' %-10.3lf \'\n", d);

	return 0;
}

输出结果:

a = 100
0x7ffd3443b718
%d
a100, 64, 144
1000, 3e8, 1750
abc = '    10'
abc = '10    '
abc = '000010'
abc = '10    '
d = ' 12.300     '
2.9.3 scanf函数与getchar函数
  • getchar是从标准输入设备读取一个char
  • scanf通过%转义的方式可以得到用户通过标准输入设备输入的数据
#include <stdio.h>

int main()
{
	char ch1;
	char ch2;
	char ch3;
	int a;
	int b;

	printf("请输入ch1的字符:");
	ch1 = getchar();
	printf("ch1 = %c\n", ch1);

	getchar(); //测试此处getchar()的作用

	printf("请输入ch2的字符:");
	ch2 = getchar();
	printf("\'ch2 = %ctest\'\n", ch2);

	getchar(); //测试此处getchar()的作用
	printf("请输入ch3的字符:");
	scanf("%c", &ch3);//这里第二个参数一定是变量的地址,而不是变量名
	printf("ch3 = %c\n", ch3);

	printf("请输入a的值:");
	scanf("%d", &a);
	printf("a = %d\n", a);

	printf("请输入b的值:");
	scanf("%d", &b);
	printf("b = %d\n", b);

	return 0;
}

请输入ch1的字符:a
ch1 = a
请输入ch2的字符:b
'ch2 = btest'
请输入ch3的字符:c
ch3 = c
请输入a的值:d
a = 1513391056
请输入b的值:b = 32765

内容概要:本文围绕“单相逆变器闭环逆变电路PWM模型仿真研究”展开,基于Simulink平台构建单相逆变器的闭环控制系统仿真模型,重点研究PWM调制技术在逆变电路中的应用与实现。文中详细阐述了系统架构设计、电压电流双闭环控制策略的实现原理、控制器参数设计及仿真建模全过程,并通过仿真结果验证了控制方案在动态响应、稳态精度与系统稳定性方面的有效性。同时,文档还涵盖多种电力电子系统典型应用场景,如多类型短路故障仿真(中性点不接地、经小电阻接地、经消弧线圈接地等)、软开关技术、微电网能量管理、MPPT控制等,体现出较强的技术综合性和工程实践价值。; 适合人群:电气工程、自动化、电力电子与新能源等相关专业的高校本科生、研究生、科研人员,以及从事电力系统仿真、逆变器设计与新能源并网技术研发的工程技术人员。; 使用场景及目标:①掌握基于Simulink的单相逆变器闭环控制系统建模与PWM仿真方法;②深入理解双闭环控制、SPWM/SVPWM调制、系统稳定性分析等核心技术原理;③为课程设计、毕业设计、科研项目或实际工程开发提供可复用的仿真模型与技术支持; 阅读建议:建议结合文中仿真模型动手实践,重点掌握PI控制器参数整定、PWM信号生成机制与仿真结果分析方法,同时可延伸学习文档中涉及的软开关、故障仿真、微电网控制等关联技术,以拓展系统级设计能力。
重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
内容概要:本文系统阐述了CUDA并行计算的核心优化技巧,围绕提升SM利用率、最大化内存带宽、隐藏访存延迟和减少指令开销四大目标,从GPU硬件架构、线程模型、内存访问、指令执行、内核设计及工程实践六个维度展开。重点讲解了线程块配置、Warp分支发散规避、全局内存合并访问、共享内存Bank冲突避免、寄存器与常量内存使用、异步传输与多流并行、快速数学函数、原子操作优化、内核拆分与融合、Tensor Core利用等关键技术,并提供了编译优化参数和Nsight系列性能分析工具的使用指导,形成了一套完整的CUDA性能优化方法论。; 适合人群:具备CUDA编程基础,从事高性能计算、深度学习、科学计算或GPU加速开发的工程师与研究人员,尤其适合工作2年以上的开发者提升底层优化能力。; 使用场景及目标:①解决CUDA程序中SM利用率低、内存带宽不足、访存延迟高等性能瓶颈;②掌握从基础到高阶的系统性优化策略,实现程序性能的指数级提升;③结合Nsight工具进行性能剖析与迭代优化。; 阅读建议:学习时应结合实际代码调试与性能分析工具(如Nsight Compute和Nsight Systems)进行验证,优先实施线程块配置、合并访问、-O3编译等低成本高回报的基础优化,再逐步深入共享内存优化、内核融合、Tensor Core利用等高阶技术,同时推荐优先使用cuBLAS、cuDNN等NVIDIA官方优化库以逼近硬件极限性能。
内容概要:本文提供了一份完整的“大学生创新创业训练计划项目”申报材料模板包,围绕“基于深度学习的智能垃圾分类回收箱设计与实现”项目,详细展示了从项目申报书、答辩PPT、中期检查表到结题报告的全套规范文档。内容涵盖项目背景、目标、研究内容、技术路线、创新点、进度安排、预期成果、经费预算及风险应对等关键环节,并以实际案例呈现各阶段成果,如YOLOv8轻量级模型识别准确率达96%、单台成本控制在780元、校园试点回收520kg可回收物、获得软著与论文成果等,形成可复制推广的校园绿色解决方案。; 适合人群:参与大学生创新创业训练计划(大创项目)的本科生团队,尤其是工科类、计算机相关专业、有意向开展人工智能+环保类实践项目的1-3年级学生;同时也适用于指导教师和项目评审人员作为参考模板。; 使用场景及目标:①帮助学生团队系统规划并撰写高质量的大创项目申报书与结题报告;②指导项目全过程管理,包括技术实施、进度控制、经费使用与成果凝练;③支撑项目答辩展示,提升项目规范性与竞争力,冲击“互联网+”“挑战杯”等赛事奖项; 阅读建议:此资源不仅提供文本模板,更体现了项目从立项到结题的完整逻辑链条,使用者应结合自身课题,参照其结构化表达方式、量化目标设定和技术落地路径进行模仿与创新,注重理论与实践结合,强化数据支撑与成果可视化。
内容概要:本文提供了一个基于Simulink的光伏储能单相逆变器并网仿真模型,系统实现了并网逆变电路的PWM调制控制、闭环控制策略及并网运行特性的仿真分析,涵盖系统建模、控制算法设计、稳定性验证与动态性能评估等关键环节。该模型不仅支持对单相逆变器在并网过程中的电流谐波、功率因数、电能质量及系统稳定性的深入研究,还可拓展应用于多类型电力系统仿真场景,如MPPT控制、软开关技术、微电网能量管理、短路故障分析(包括单相、两相接地及相间短路)、直流电机双闭环控制、Buck/Boost类变换器控制等,展现出广泛的科研适配性与工程实践价值。; 适合人群:面向具备电力电子、自动控制理论或电气工程背景,熟练掌握Simulink/Matlab仿真工具,从事新能源发电系统、微电网控制、逆变器拓扑与控制策略研究的硕士/博士研究生、科研人员及电力系统相关领域的工程技术人员。; 使用场景及目标:①开展光伏发电系统并网控制策略的设计与仿真验证;②学习并掌握单相逆变器PWM调制、锁相环(PLL)、电压电流双闭环控制等核心技术的建模方法;③作为课程设计、毕业设计或科研项目的仿真平台,支撑控制系统开发与优化;④结合文中提供的多种电力系统案例(如故障仿真、储能控制、微网调度),进行横向对比与综合能力提升; 阅读建议:建议读者结合文中列出的多个仿真案例进行扩展学习,重点关注控制器参数设计与系统动态响应之间的关系,动手复现模型并进行仿真调试,通过改变负载、电网条件或控制参数,深入理解并网逆变器的工作机理与控制规律,从而提升实际科研与工程应用能力。
重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
因为工作需要,每天需要打很多次卡,然后忙起来就忘了,忙完了就会想,刚才打卡了吗?弄错就会漏打卡了,漏打卡会有处罚。就想到写一个程序来解决这个痛点。就有了本次发布的这个程序。 PHP项目,修改起来也简单,也方便二开。本来就是H5页面布局,部署好,直接手机浏览器打开,或者使用封装工具,封装成apk。本人已打包为微信小程序,使用起来很方便。 项目简介 本项目是一个多用户打卡记录系统,基于 PHP + MySQL 开发,提供简洁的用户打卡功能和记录管理。 核心功能 功能模块 描述 用户认证 支持用户注册、登录、密码修改、密码重置 打卡功能 用户可进行每日打卡,记录打卡时间 记录查询 支持按日期查询打卡记录 用户管理 支持头像上传、个人信息查看 数据统计 提供打卡统计功能 技术特点 轻量级架构:纯 PHP 开发,无需框架依赖,部署简单 响应式设计:移动端友好的 UI 界面,支持触摸操作 安全性: 使用 prepare + bind_param 防止 SQL 注入 密码采用哈希加密存储 Session 会话管理用户状态 模块化设计:API 接口与前端分离,便于扩展 项目结构 Plain Text ├── api/ # RESTful API 接口 │ ├── checkin.php # 打卡接口 │ ├── login.php # 登录接口 │ ├── register.php # 注册接口 │ ├── records.php # 记录查询接口 │ ├── stats.php # 统计接口 │ └── … ├── config/ # 配置文件 │ ├── database.php # 数据库配置 │ └── auth.php # 认证配置 ├── sql/ # 数据库脚本 │ └── init.sql # 初始化脚本 ├── avatars/ # 头像存储目录 ├── ind
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值