初识C语言
1. 初识C语言
C语言是一门通用计算机编程语言,广泛应用于底层开发。
C语言是一门面向过程的计算机编程语言,它与C++,Java等面向对象的编程语言有所不同。
第一个C语言程序:
#include<stdio.h>int main(void)
{printf("hello world!\n");return 0;
}
注释:
stdio:标准输入输出
main函数:main函数是主函数,也是程序的入口,并且有且仅有一个
main(void):加参数void表示main函数不需要参数
printf函数:它是一个库函数,主要用于在屏幕上打印相关的数据,使用库函数就得包含对应的头文件
//一种旧式写法,在一些老式的编译器中可以使用
void main()
{
...
}
2.数据类型
类型的存在主要是为创建变量服务的,常用的数据类型如下:
字符类型:char
整数类型:short int long longlong
浮点类型:float double
int main()
{printf("%d\n",100);//100printf("%d\n",sizeof(char));//1printf("%d\n",sizeof(short));//2printf("%d\n",sizeof(int));//4printf("%d\n",sizeof(long));//4printf("%d\n",sizeof(long long));//8printf("%d\n",sizeof(float));//4printf("%d\n",sizeof(double));//8return 0;
}
注释:
%d:用于打印整数
sizeof():是一个操作符,用来计算类型和变量的大小
计算机的基本单位
bit:比特位,存一个二进制位1或者0
byte:字节,1byte=8bit
KB:1KB=1024byte
MB:1MB=1024KB
GB:1GB=1024MB
C语言标准规定:sizeof(long)>=sizeof(int) ,但是long的大小不一定要是8只要是比4的数字即可
C语言有没有字符串类型?
C语言没有原生字符串类型。像Java有自己的字符串类型string,而在C语言中,字符串则往往是被当做字符数组或者字符指针来进行处理的。在C语言中,字符串有3个核心要点:第一是用指针指向字符串的头;第二是固定尾部(字符串总是以\n来结尾);第三是组成字符串的各字符彼此地址相连。
3.常量与变量
常量
常量:用来描述变化的数据
定义变量:
int age=150;
float weight=55.5f(加f表面是个float的类型);
char ch='w';
变量的分类:
局部变量:在大括号内定义的变量
全局变量:在大括号外定义的变量
int a=100;//全局变量void test()
{
int c=1000;//局部变量
}
int main()
{//运行时会报错,因为a是局部变量,只能在括号以内使用{int a = 10;//局部变量}printf("%d\n",a);//可以运行,不会发生错误int a = 10;//局部变量printf("%d\n", a);return 0;
}
局部变量优先原则:
当局部变量和全局变量同名时,局部变量优先使用
int a = 100;
int main()
{int a = 10;//局部优先原则printf("a=%d\n",a);//输出结果为10return 0;
}
变量的使用:
//求两数之和
int main()
{int num1 = 0;int num2 = 0;int sum = 0;//输入scanf("%d %d",&num1,&num2);//求和sum = num1 + num2;//输出printf("sum=%d\n",sum);printf("%d %d\n",num1,num2);return 0;
}
注释:
scanf():输入函数
printf():输出函数
%s:输出字符串
%d:输出整数
scanf()函数为什么不安全?如何解决?
因为scanf() 函数不会对存放数据的内存空间进行检测,在使用的过程中输入的数据可能会大于原本分配的内存空间,进而导致溢出,造成越界访问,所以scanf()函数不安全。
解决办法:
法1:在源文件开头定义:#define _CRT_SECURE_NO_WARNINGS 1(比较麻烦,每次新建工程都要重新定义,建议采用方法2)
法2:在VS的安装路径下搜索到newc++file.cpp这个文件,复制一份到桌面,并在文件中加入#define _CRT_SECURE_NO_WARNINGS 1并保存,然后以管理员的身份替换到原来的文件即可
法:3:通过项目 -> 属性 -> C/C++ -> 预处理器 -> 预处理器定义 -> 编辑,在框内写入 _CRT_SECURE_NO_WARNINGS
法4:在源文件开头加入一行命令:#pragma warning(disable:4996)
变量的作用域和生命周期
作用域:通常来说,一段程序中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域
局部变量:局部变量的作用域就是局部变量所在的局部范围
全局变量:全局变量的作用域是整个工程
//局部变量:局部变量的作用域就是局部变量所在的局部范围
int main()
{{int a = 10;//a只能在括号内使用,超出这个范围就不能使用}printf("%d\n",a);//运行时会发生报错,因为a超出所在范围
}//全局变量:全局变量的作用域是整个工程
int a = 10;
void test()
{printf("test:%d\n",a);
}
int main()
{test();printf("main:%d\n",a);return 0;
}//在另一个文件中定义的全局变量,需要声明外部符号:extern
extern int g_val;
int main()
{printf("%d\n",g_val);return 0;
}
生命周期:变量的生命周期指的是变量的创建到销毁之间的一个时间段
局部变量的生命周期:进入作用域生命周期开始,出作用域生命周期结束
全局变量的生命周期:整个程序的生命周期
常量:
常量:用来描述不变的数据
常量的类型:
字面常量
const修饰的常变量
#define定义的标识符常量
枚举常量
字面常量`
int a = 100;
char ch = 'c';
const修饰的常变量
//这里的n属于变量其值是可以修改的
int n = 10;//n为变量
printf("n=%d\n",n);//10
n = 20;//n为变量
printf("n=%d\n",n);//20
//这里的n属于常变量其值是不可以修改的
const int n = 10;//常变量
printf("n=%d\n",n);
n = 20;//运行时会报错,n的值不能修改
printf("n=%d\n",n);
int arr[10] = {0};//C99标准之前的语法int n = 10;
int arr[n] = {0};//运行不通过,因为n是个变量,中括号里面的值必须是个常量,但是在C99标准中增加一个变长数组的概念,这里指定数组大小的时候,可以使用变量了const int n = 10;
int arr[n] = {0};//运行不通过,虽然n具有常属性,但本质上仍是个变量
#define定义的标识符常量
#define MAX 100MAX = 101;//MAX是个标识符常量,其值不能进行修改
int m = MAX;
printf("%d\n",m);//100
printf("%d\n",MAX);//100
枚举常量
enum Sex
{male,female,secret
};//枚举是C语言提供的一种自定义类型的方法
male = 10;//male是常量,其值不能修改
printf("%d\n",male);//0
printf("%d\n",female);//1
printf("%d\n",secret);//2enum Sex s = male;//常规用法
4.字符串+转义字符+注释
字符串:
字符串:由双引号引起来的一串字符称为字符串
字符串的结束标志是一个名为\0的转义字符,在计算字符串长度的时候\0是结束标志,不算作字符串内容
%s:打印字符串
int main()
{char arr1[] = "abcdef";//结尾处包含一个结束标志\0char arr2[] = {'a','b','c','d','e','f'};//结尾处不包含结束标志\0char arr3[] = {'a','b','c','d','e','f','\0'};//结尾处自行添加一个结束标志\0char arr4[] = "abc\0def";printf("%s\n",arr1);//输出结果为abcdefprintf("%s\n",arr2);//输出结果为abcdef烫烫烫烫烫abcdef,因为不包含字符串的结束标志\0printf("%s\n",arr3);//输出结果为abcdefprintf("%s\n",arr4);//输出结果为abcreturn 0;
}
转义字符:
转义字符:转义也就是转变它的意思
int main()
{//\?:在书写连续多个问号时使用,防止他们被解析成三字母词,三字母词??)->]printf("(are you ok??)");//原本应该输出(are you ok],但最后的运行结果还是输出(are you ok??),编译器无法演示printf("(are you ok\?\?)\n");//输出(are you ok??),常规用法//\':用于表示字符常量//\":用于表示一个字符串内部的双引号//%c:用于打印字符printf("%c\n",'a');//输出结果为aprintf("%c\n",'\'');//输出结果为'printf("%s\n","abc");//输出结果为abcprintf("%s\n","a");//输出结果为aprintf("%s\n","\"");//输出结果为"//\\:用于表示一个反斜杠,防止它被解释为一个转义序列//printf("c:\\code\\test.c\n");//\ddd:ddd表示1-3个八进制的数字,如\130对应X//\xdd:x表示十六机制,dd表示2个十六进制数字,如\x30对应0printf("%c\n",'\130');//八进制表示的130转化为十进制为:64+24+0=88,而88对应的ASCII值为字符Xprintf("%c\n",'\x30');int len = 0;len = strlen("abcdef");printf("%d\n",len);//结果为6,不计入字符串的结束标志\0printf("c:\test\628\test.c\n");printf("%d\n",strlen("c:\test\628\test.c"));//14,十四个字符分别为 c : \t e s t \62(\062) 8 \t e s t . c //可能有人会问,为什么不是\628,而是\62呢?原因:\ddd中的ddd代表的是八进制数,八进制数中没有8这个数,所以很显然\62 相当于\062char arr1[] = "abcdef";char arr2[] = {'a','b','c','d','e','f'};char arr3[] = { 'a','b','c','d','e','f','\0'};printf("%d\n",strlen(arr1));//6printf("%d\n",strlen(arr2));//22 因为不包含字符串零终止符,所以22是个随机值printf("%d\n",strlen(arr3));//6return 0;
}
注释:
C语言风格的注释:/xxxxxx/,缺点:不能嵌套注释
C++风格的注释://xxxxxx,优点:可以注释一行也可以注释多行
5.选择语句
int main()
{int input = 0;printf("你要好好学习吗(1/0)?:");scanf("%d",&input);if (input == 1){printf("好offer!");}else{printf("卖红薯!");}return 0;
}
6.循环语句
int main()
{int line = 0;while (line<20){line++;printf("我要继续努力敲代码:%d\n",line);}if (line >= 20){printf("迎娶白富美!\n");}
}
7.函数
函数的特点:简化代码,代码复用
int Add(a, b)
{int sum = 0;sum = a + b;return sum;
}int main()
{int n1 = 0;int n2 = 0;int sum = 0;//输入scanf("%d %d", &n1, &n2);//计算求和sum = n1 + n2;sum = Add(n1, n2);//输出printf("sum=%d\n", sum);
}
8.数组
数组:一组相同类型元素的集合
C语言规定:数组的每个元素都有一个下标,下标是从0开始的
数组可以通过下标来访问
int main()
{int arr[10] = {10,11,12,13,14,15,16,17,18,19};printf("%d\n",arr[5]);//15int i = 0;//输入while (i < 10){scanf("%d",&arr[i]);i++;}i = 0;//输出while (i < 10){printf("%d ",arr[i]);i++;}char ch[5] = {'a','b','c','d','e'};return 0;
}
9.操作符
算数操作符:+ - * / %
flaot:打印输出用%f
double:打印输出用%lf
int main()
{int c = 10 / 3;printf("%d\n",c);//3float c = 10 / 3;printf("%f\n",c);//3.000000//想要得到3.333333,10和3两个操作数必须含有一个小数或者两个都带小数,如10.0,3.0等float c = 10.0/ 3;printf("%f\n", c);float d = 10/3.0;printf("%f\n", d);float e = 10.0/ 3.0;printf("%f\n", e);//%:取模,两边的操作数必须都是整数int a = 10 % 3;printf("%d\n",a);//1//移位操作符:>> << 移动的是二进制位,必须把十进制数字转化为二进制演示//位操作符:& ^ | 操作的是二进制位//赋值操作符int a = 10;//初始化a = 20;//赋值return 0;
}
‘0’:字符0,对应的ascii码值为48
‘\0’:转义字符,对应的ascii码值为0
0:数字0,就是0,当需要’\0’的地方,放上0也是没问题的
EOF:END OF FILE,文件结束标志,本质是-1,是文件结束标志
一个全局变量未被初始化时,默认会被初始化为0;
一个局部变量未被初始化时,默认会被初始化为随机值;
int a;//一个全局变量未初始化时,默认会被初始化为0
int main()
{//一个局部变量未初始化时,默认是随机值int b;printf("%d\n",b);printf("%d\n",a);char ch[10] = "hello bit";//h e l l o '' b i t '\0' return 0;
}
多组输入:
scanf()返回值:scanf()返回值为读取到的输入值的个数,可以用EOF文件结束标志来判断
案例一:
//多组输入
//scanf()返回值:scanf返回值为读取到的输入值的个数,可以用EOF文件结束标志来判断
int main()
{int iq = 0;//输入while (scanf("%d", &iq)==1)//scanf如果读到一个有效数据,则进入循环,或者写成while(scanf("%d", &iq)!=EOF){//输出if (iq >= 140){printf("Genius\n");}}return 0;
}
运行结果如下:
案例二:
int main()
{int iq = 0;int q = 0;//输入while (scanf("%d %d", &iq,&q)==2)//scanf如果读到两个有效数据,则进入循环,或者写成while(scanf("%d %d", &iq,&q)!=EOF){//输出if (iq >= 140&&q>=140){printf("Genius\n");}}return 0;
}
运行结果如下:
单目操作符:
int main()
{//逻辑反操作!,在C语言中,0就是假,非0就是真int a = 10;int b = !a;//a为10为真,逻辑反操作即为假0printf("b=%d\n", b);//结果为0int a = 0;int b = !a;printf("b=%d\n",b);//结果为1int flag = 5;//如果flag为真做什么事情if (flag){printf("hehe!\n");//输出hehe!}int flag1 = 0;//如果flag1为假做什么事情if (flag1){printf("haha\n");//什么也不输出}//sizeof:计算操作数的类型长度,以字节为单位int a = 10;printf("%d\n",sizeof(a));//4printf("%d\n",sizeof(int));//4//~:对一个数的二进制按位取反//++,--int a = 10;int b = ++a;//前置++,先++,后使用,即先对a+1=11,再将a=11的值赋给bprintf("a=%d b=%d",a,b);//11,11int a = 10;int b = a++;//后置++,先使用,后++,即先将a=10赋值给b,再将a+1=11printf("a=%d b=%d", a, b);//11,10int a = 10;int b = --a;//前置--,先--,后使用,即先对a-1=9,再将a=9的值赋给bprintf("a=%d b=%d", a, b);//9,9int a = 10;int b = a--;//后置--,先使用,后--,即先将a=10赋值给b,再将a-1=9printf("a=%d b=%d", a, b);//9,10//(类型):强制类型转换int a = 3.14;//从double转换到int,可能会丢失数据,输出结果为3int a = (int)3.14;//强制类型转换printf("%d\n",a);//输出结果为3return 0;
}
关系操作符:
==:相等,是两个等号
逻辑操作符:
逻辑操作符:关注的是真与假
&&和||:逻辑与和逻辑或
int main()
{int a = 10;int b = 3;//不输出if (a == 3 && b == 4){printf("hehe\n");}//输出if (a == 10 || b == 8){printf("haha\n");}return 0;
}
条件操作符:
exp1?exp2:exp3:如果1为真,运行2;如果1为假,运行3
int main()
{int a = 3;int b = 5;int m = 0;m = ((a>b)?a:b);printf("%d\n",m);//输出5return 0;
}
逗号操作符:
逗号表达式:会从左向右依次计算,整个表达式的结果是最后一个表达式的结果
int main()
{int a = 1;int b = 3;int c = 4;int d = (a=b-3,b=a*2,c=a-b);//a=0,b=0,c=0printf("%d\n",d);return 0;
}
下标引用操作符[ ]:
int main()
{int arr[10] = {1,2,3,4,5};//后面会默认补0printf("%d\n",arr[8]);//0return 0;
}
10.常见关键字
typedef:类型重定义
typedef unsigned int uint;//将unsigned int重命名为uint
int main()
{//无符号的整型变量unsigned int num1 = 0;uint num2 = 0;return 0;
}
register:寄存器关键字
寄存器:计算机中的一种存储器,是集成到CPU上的
寄存器<-高速缓存(cache)<-内存<-硬盘<-网盘(越往上速度越来越快,造价越来越高)
int main()
{register int num = 10;//register只是起到一个建议的作用,建议将num的值放在寄存器中,但最终是否放入还是由编辑器决定的//寄存器变量是不能取地址的,因为取地址取的是内存的地址,而register是集成在cpu上的,因而是无法取地址的return 0;
}
static关键字:
static修饰的局部变量:
static修饰局部变量的时候,改变了局部变量的存储类型,本来一个局部变量是存储在栈区,而被static修饰的局部变量是存储在静态区的;
在栈区上的局部变量,出了作用域生命周期结束,变量被销毁;而被static修饰的局部变量,出了作用域生命周期没有结束,变量也不销毁;
static修饰的局部变量的生命周期和程序的生命周期一样;
static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束
案例一:
void test()
{int n = 1;n++;printf("%d ",n);//n的值不发生变化,为2
}int main()
{int i = 0;while (i < 10){test();i++;printf("%d\n",i);}return 0;
}
运行结果:
案例二:
void test()
{static int n = 1;n++;printf("%d ",n);//n的值为2,3,4,5,6,7,8,9,10,11
}int main()
{int i = 0;while (i < 10){test();i++;}return 0;
}
运行结果:
static修饰的全局变量:
static修饰全局变量的时候,改变了全局变量的链接属性,本来一个全局变量是具有外部链接属性的,但是被static修饰后就变成了具有内部链接属性,这时static修饰的全局变量只能在本源文件(.c)中使用,其他文件无法再使用;
在c中,源文件扮演模块的角色。任何带有static属性声明的全局变量或者函数都是模块私有的。类似的,任何不带static属性的全局变量和函数都是公有的,可以被其他模块访问
案例一:
add.c
int g_val = 10;
test.c
//extern是用来声明外部符号的
extern int g_val;//extern可加可不加int main()
{printf("%d\n",g_val);//10return 0;
}
运行结果:案例二:
add.c
static int g_val = 10;
//test.c函数编译不通过,因为static修饰的全局变量,改变了全局变量的链接属性
test.c
//extern是用来声明外部符号的
extern int g_val;//extern可加可不加int main()
{printf("%d\n",g_val);//运行不通过return 0;
}
运行结果:
static修饰函数:
static修饰函数和修饰全局变量是类似的,一个函数本来也是具有外部链接属性的,当被static修饰的时候,外部链接属性就变成了内部链接属性,这个函数就只能在本源文件内部使用,其他文件不能再使用
案例一:
add.c
//函数也是具有外部链接属性的
int Add(int x, int y)
{int z = x + y;return z;
}
test.c
//声明来自外部的函数
extern int Add(int,int);int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int sum = Add(a, b);printf("%d\n",sum);return 0;
}
运行结果:
案例二:
add.c
//static修饰的函数
static int Add(int x, int y)
{int z = x + y;return z;
}
test.c
//声明来自外部的函数
extern int Add(int,int);int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int sum = Add(a, b);printf("%d\n",sum);return 0;
}
运行结果:
10.#define定义常量和宏
#define定义标识符常量
//#define 定义标识符常量
#define NUM 100
#define STR "hehe" int main()
{printf("%d\n",NUM);//100printf("%s\n",STR);//hehereturn 0;
}
#define定义宏
//#define 定义宏 宏是有参数的
#define ADD(x,y)((x)+(y))//带括号
int main()
{int a = 10;int b = 20;int sum = ADD(a, b);//int sum = ((a)+(b));printf("%d\n",sum);//30return 0;
}
11.指针
内存:
外存:又叫外部存储器,长期存放数据,掉电不丢失数据
内存:又叫内部存储器,暂时存放数据,掉电数据丢失,又可分为物理内存和虚拟内存。物理内存:实实在在存在的存储设备;虚拟内存:操作系统虚拟出来的内存。在32位系统下,每个进程(运行的程序)的寻址范围是4G,即0x00 00 00 00-0xff ff ff ff。在写应用程序时,我们看到的都是虚拟地址。
在运行程序时,操作系统会将虚拟内存进行分区:
堆区:在动态申请内存时,在堆区开辟内存;
栈区:主要存放局部变量,主要是在函数内部或者复合语句内部定义的变量;
静态全局区:未初始化的静态全局区(静态变量(定义的时候,前面加static修饰)或全局变量在没有初始化时,存放在此区域);初始化的静态全局区(全局变量或静态变量赋过初值的,存放在此区));
代码区:存放咱们的程序代码
文字常量区:存放常量的
内存是以字节为单位来存储数据的,咱们可以将程序中的虚拟存储空间,看成一个很大的一维的字符数组
指针:
系统给虚拟内存的每个存储单元分配了一个编号,从0x00 00 00 00-0xff ff ff ff,这个编号就称之为地址,指针就是地址。
指针变量:是个变量,是个指针变量,即这个变量用来存放一个地址编号;
在32位平台下,地址总线是32位的,所以地址是32位编号,所以指针变量是32位的,即4个字节;
无论什么类型的地址,都是存储单元的编号,在32位平台下都是4字节,即任何类型的指针变量都是4字节大小。
对应类型的指针变量,只能存放对应类型的变量的地址
多字节的变量,对应多个地址编号,编号最小的地址编号就是多字节变量的地址
指针变量的定义方法:
int *p;//在定义指针变量的时候,*是用来修饰变量的,说明变量p是个指针变量,变量名为p
&:取地址;*:取值
int main()
{int num = 10;#//取出num的地址printf("%p\n",&num);//打印地址,%p以地址的形式打印return 0;
}
int a=0x1234abcd;
int *p=NULL;
P=&a;//p保存了a的地址,也可以说p指向了a
//a的值是0x1234abcd,假如a的地址是:0xbfe89868,则关系图如下图所示
int num;
num=*p;//在调用时,*代表取值的意思,*p就相当于p指向的变量,即a,所以num=*p和num=a的效果是一样的
如果在一行当中定义了多个指针变量,每个指针变量的前面都需要加*来修饰
int *p,*q;//定义了两个整型的指针变量p和q
int *p,q;//定义了一个整型指针变量p,和整型的变量q
int main()
{int a = 100, b = 200;int* p_1, * p_2 = &b;//表示该变量的类型是一个指针变量,指针变量名是p_1而不是*p_1;//p_1在定义的时候没有赋初值,p_2赋了初值p_1 = &a;//p_1先定义后赋值printf("%d\n",a);printf("%d\n",*p_1);printf("%d\n",b);printf("%d\n", *p_2);return 0;
}
//在定义p_1的时候,因为是个局部变量,局部变量没有赋初值,它的值是随机的,p_1指向哪里不一定,所以p_1是个野指针
指针的大小:
32位机器:支持32位的虚拟地址空间,产生的地址就是32bit位的,那么就需要32bit的空间存储->4byte;
64位机器:支持64位的虚拟地址空间,产生的地址就是64bit位的,那么就需要64bit的存储空间->8byte;
32位平台下地址是32bit位(即4个字节);
64位平台下地址是64bit位(即8个字节);
int main()
{char ch = 'w';int n = 100;double d = 3.14;char* pc = &ch;int* pi = &n;double* pd = &d;printf("%d\n",sizeof(pc));//4printf("%d\n",sizeof(pi));//4printf("%d\n",sizeof(pd));//4return 0;
}
指针和变量的关系:
*+指针变量:就相当于指针指向的变量
int main()
{int* p1, * p2, temp, a, b;p1 = &a;p2 = &b;printf("请输入a,b的值:\n");scanf("%d %d",&a,&b);temp = *p1;*p1 = *p2;*p2 = temp;printf("a=%d b=%d\n",a,b);printf("*p1=%d *p2=%d\n",*p1,*p2);return 0;
}
运行结果:
如果想让不同类型的指针相互赋值的时候,需要强制类型转换;
通用指针void* p:可以存放任何类型的变量的地址编号
int main()
{int a = 0x12345678, b = 0xabcdef66;char* p1, * p2;printf("%0x %0x\n",a,b);p1 = (char*)&a;p2 = (char*)&b;printf("%0x %0x\n",*p1,*p2);p1++;p2++;printf("%0x %0x\n",*p1,(0xff)&(*p2));return 0;
}
运行结果:
注意:
*+指针:取值,取几个字节,由指针类型决定的;指针为字符指针则取一个,指针为整型指针择取四个字节,指针为double型指针则取8个字节。
指针++:指向下个对应类型的数据。字符指针++,指向下个字符数据,指针存放的地址编号加1;整型指针++,指向下个整型数据,指针存放的地址编号加4
12.结构体
//定义一个结构体
struct Stu
{char name[20];int age;char sex[5];double score;
};int main()
{struct Stu s1 = {"张三",20,"男",90.5};struct Stu s2 = {"如花",40,"女",99.5};//输入scanf("%s %d %s %lf",s1.name,&(s1.age),s1.sex,&(s1.score));//age和score前面必须要加&//方式一printf("%s %d %s %lf\n",s1.name,s1.age,s1.sex,s1.score);//结构成员访问操作符:结构体变量.结构体成员//方式二:struct Stu* ps = &s1;printf("%s %d %s %lf\n",(*ps).name,(*ps).age,(*ps).sex,(*ps).score);//方法三:printf("%s %d %s %lf\n",ps->name,ps->age,ps->sex,ps->score);//结构成员访问操作符:结构体指针->结构体成员return 0;
}
相关文章:

初识C语言
1. 初识C语言 C语言是一门通用计算机编程语言,广泛应用于底层开发。 C语言是一门面向过程的计算机编程语言,它与C,Java等面向对象的编程语言有所不同。 第一个C语言程序: #include<stdio.h>int main(void) {printf("hello worl…...

Leetcode 322. 零钱兑换(完全背包)
Leetcode 322. 零钱兑换(完全背包)题目 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&…...

怎么恢复回收站?分享4个宝藏方法!
案例:怎么恢复回收站 【请问大家怎么恢复误删的文件呀?如果回收站被清空了,又应该怎么恢复呢?】 电脑回收站是我们存储被删除文件的地方。但是有时候,我们会不小心把一些重要的文件或者照片误删了。这时候࿰…...

大模型混战,最先实现“智慧涌现”的会是谁?
作者 | 曾响铃 文 | 响铃说 几秒钟写出了一篇欢迎词; 小说人物乱入现实,快速创作不重样的故事; 鼠标一点,一封英文工作沟通邮件撰写完成; 准确解出数学应用题,还给出解题步骤; 甚至还能理…...

Powerlink协议在嵌入式linux上的移植和主从站通信(电脑和linux板通信实验)
使用最新的openPOWERLINK 2.7.2源码,业余时间搞定了Powerlink协议在嵌入式linux上的移植和测试,并进行了下电脑和linux开发板之间的通信实验。添加了一个节点配置,跑通了源码中提供的主站和从站的两个demo。这里总结下移植过程分享给有需要的…...

快速理解基本的cookie、session 和 redis
一、Cookie 1、什么是Cookie 1、Cookie实际上是一小段的文本信息,是一种keyvalue形式的字符串。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端会把Cookie保存起来。 2、当浏览器再请求…...

STANet代码复现出现的问题
1 IndexError: boolean index did not match indexed array along dimension 0; dimension is 4194304 but corresponding boolean dimension is 65536定位到导致错误的代码,是metric.py,Collect values for Confusion Matrix 收集混淆矩阵的值时出错 …...

Java 中String对象详解
Java语言中的String对象是一个非常常见的数据类型,大多数情况下我们都是在使用String对象来表示字符串类型的数据。Java中的String类是一个final class,它是不可被继承的。本文将对Java中的String对象进行详细全面的描述,包括以下几个方面&am…...

k8s nfs运行问题、etcd问题、calico网络问题
服务器重启后nfs运行问题导致服务不能正常重启 解决办法 在每个节点下使用如下命令进行查看nfs是否正常启动 systemctl status nfs 如果没有启动,则使用如下命令启动,保证三个节点下的nfs都正常启动 systemctl start nfs 再次查看nfs是否正常启动 syst…...

Qt--QString字符串类、QTimer定时器类
目录 1. QString 字符串类 dialog.cpp 2. 容器类 2.1 顺序容器 QList 示例代码: student.h student.cpp dialog.h dialog.cpp 运行结果: 2.2 关联容器 QMap 示例代码: dialog.h dialog.cpp 运行结果: 3. Qt类型 3.1 跨平台数据类型…...

2023.5.13>>Eclipse+exe4j打包Java项目及获取exe所在文件的路径
Eclipseexe4j打包Java项目及获取exe所在文件的路径 1、打包exe文件1.1 打jar包1.2 打包exe2、在程序中获取exe所在路径3、遇到问题4、JDK version和class file version(Class编译版本号)对应关系5、参考文章 1、打包exe文件 1.1 打jar包 右单击项目选择“Export…” 1.2…...

Centos系统的使用基本教程
Centos是一款流行的Linux操作系统,它基于Red Hat Enterprise Linux系统,是一款稳定、可靠、安全的操作系统。本文将介绍Centos系统的基本使用方法,包括安装、命令行操作、软件安装和系统管理等方面的内容。 安装Centos系统 Centos系统可以从…...

IDEA生成ER图、UML类图、时序图、流程图等的插件推荐或独立工具推荐
以下是几个常用的IDEA插件和独立工具,可以用于生成ER图、UML类图、时序图、流程图等: Visual Paradigm (独立工具) Visual Paradigm是一个强大的建模工具,可以生成UML类图、时序图、流程图等。它支持多种语言和框架,包括Java、Spr…...

Python心经(3)
这一节总结点demo和常用知识点 目录 有关字符串格式化打印的 lambda匿名函数,,将匿名函数作为参数传入 文件读写 生成器 python的装饰器 简单的网站代码: 有关三元运算 推导式: 新浪面试题: 有关面向对象里…...

单工,半双工,全双工通讯
对于点对点之间的通信,按照消息传送的方向与时间关系,通信方式可分为单工通信、半双工通信及全双工通信三种。 单工通信 单工通信(Simplex Communication)是指消息只能单方向传输的工作方式。 在单工通信中,通信的信…...

【2023-05-09】 设计模式(单例,工厂)
2023-05-09 设计模式(单例,工厂) 单例模式 顾名思义,就是整个系统对外提供的实例有且只有一个 特点: 1、单例类只有一个实例 2、必须是自己创建唯一实例 3、必须给所以对象提供这个实例 分类ÿ…...

批量任务导致页面卡死解决方案
需求背景 需要基于高德地图展示海量点位(大概几万个),点位样式要自定义(创建DOM),虽然使用了聚合点,但初始化时仍需要将几万个点位的DOM结构都创建出来。 这里补充一句,高德地图在2.…...

避免“文献综抄”,5种写作结构助你完成文献综述→
很多作者可能有过这样的体验:读了很多文献,但在写综述的时候总感觉不像是在写文献综述,更像在写文献总结 如果引用方面不注意,甚至会成为文献综抄。 那么,你可以参考下我们整理的以下资料哦~ 01 文献总结和文献综述的…...

Java异常和反射
JAVA 异常分类及处理 概念 } final Entry<K,V> getEntryUsingComparator(Object key) { K k (K) key; // 获取该 TreeMap 的 comparator Comparator<? super K> cpr comparator; if (cpr ! null) { // 从根节点开始 Entry<K,V> p …...

Accesss数据库的那点事
Accesss数据库的那点事 1.Access的简介 Access(全称为Microsoft Access)是一个关系型数据库管理系统(RDBMS)。它是由微软公司开发的数据库软件,用于创建、管理和操作数据库应用程序。 Access提供了一个可视化的开发环…...

网络基础学习:osi网络七层模型
osi网络七层模型 什么是OSI,什么是ISO?为什么ISO要提出OSI网络七层模型?OSI七层的划分以及具体内容第七层 应用层第六层 表示层第五层 会话层第四层 传输层第三层 网络层第二层 数据链路层第一层 物理层 每一层与设备的对应关系 什么是OSI,什…...

EndNote X9 引用参考 单击文献编号,不能跳转到文尾文献列表处,咋解决?文献编号 不能跳转 ,怎么办?
文章目录 1 正常情况下 引用文献编号 是可以跳转的2 问题分析3 解决方法4 EndNote X9 插入参考文献常见问题总结5 EndNote X9 快速上手教程(毕业论文参考文献管理器) 1 正常情况下 引用文献编号 是可以跳转的 正确的插入文献后, 正常情况下&a…...

用免费蜜罐工具配置Modbus工控蜜罐
导语:本文将用DecoyMini免费蜜罐工具来配置自定义的ModbusTCP工控仿真模板,并介绍部署后的Modbus蜜罐的使用效果。 DecoyMini是一个免费的蜜罐工具,其特色是仿真能力采用与软件松耦合的仿真模板来进行管理。通过一键式导入云端仿真模板库里的…...

DataGridXL中快速搜索单元格和底部全屏模式区域隐藏
DataGridXL表格是在2020年发布,DataGridXL在设计时就考虑到了性能。提供最快、最简单、最可靠的数据网格。DataGridXL支持所有常用所有的浏览器,为 Web 应用程序提供类似于 Microsoft Excel 的体验,它支持前端框架有Vue、React、Angular等。 …...

DotNet几种微服务框架,你用过吗?
最近有群友问,.NET有哪些微服务框架?.NET的微服务框架还真不多,一般企业都会自己搭建微服务框架,或者基于其它框架搭建微服务(比如abp)。本文将介绍几种微服务框架,供大家学习参考。 一、Servi…...

Nature | 生成式人工智能如何构建更好的抗体
疫情高峰期,研究人员竞相开发一些首批有效的COVID-19治疗方法:从已经康复的人的血液中分离出来的抗体分子。 现在,科学家已经证明,生成式人工智能(AI)可以通过一些繁琐的过程提供捷径,提出增强抗…...

【hive】基于Qt5和libuv udp 的lan chat
作者已经不更新了,但是很棒 在线用户列表: 聊天窗口 主程序 单独的网络线程: network_thread data管理关联网络管理的 程序update升级更新 和消息收到 即可...

Java版本工程项目管理系统源码,助力工程企业实现数字化管理
Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示…...

什么是零拷贝?
零拷贝 什么是零拷贝 零拷贝指的是,从一个存储区域到另一个存储区域的copy任务无需CPU参与就可完成。零拷贝的底层是 通过DMA总线技术实现的。零拷贝与具体的编程语言无关,完全依赖于OS,OS支持就可使用,不支持 设置了也不起作用…...

计算机专业含金量高的证书
目录 第一种证书:计算机技术与软件专业资格考试证书 第二种证书:微软认证 第三种证书:Oracle认证 第四种证书:思科认证 第五种证书:华为认证 第六种证书:红帽认证工程师 第七种证书:阿里…...