当前位置: 首页 > news >正文

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

Leetcode 322. 零钱兑换(完全背包)

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

怎么恢复回收站?分享4个宝藏方法!

案例&#xff1a;怎么恢复回收站 【请问大家怎么恢复误删的文件呀&#xff1f;如果回收站被清空了&#xff0c;又应该怎么恢复呢&#xff1f;】 电脑回收站是我们存储被删除文件的地方。但是有时候&#xff0c;我们会不小心把一些重要的文件或者照片误删了。这时候&#xff0…...

大模型混战,最先实现“智慧涌现”的会是谁?

作者 | 曾响铃 文 | 响铃说 几秒钟写出了一篇欢迎词&#xff1b; 小说人物乱入现实&#xff0c;快速创作不重样的故事&#xff1b; 鼠标一点&#xff0c;一封英文工作沟通邮件撰写完成&#xff1b; 准确解出数学应用题&#xff0c;还给出解题步骤&#xff1b; 甚至还能理…...

Powerlink协议在嵌入式linux上的移植和主从站通信(电脑和linux板通信实验)

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

快速理解基本的cookie、session 和 redis

一、Cookie 1、什么是Cookie 1、Cookie实际上是一小段的文本信息&#xff0c;是一种keyvalue形式的字符串。客户端请求服务器&#xff0c;如果服务器需要记录该用户状态&#xff0c;就使用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定位到导致错误的代码&#xff0c;是metric.py&#xff0c;Collect values for Confusion Matrix 收集混淆矩阵的值时出错 …...

Java 中String对象详解

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

k8s nfs运行问题、etcd问题、calico网络问题

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

Qt--QString字符串类、QTimer定时器类

目录 1. QString 字符串类 dialog.cpp 2. 容器类 2.1 顺序容器 QList 示例代码&#xff1a; student.h student.cpp dialog.h dialog.cpp 运行结果&#xff1a; 2.2 关联容器 QMap 示例代码&#xff1a; dialog.h dialog.cpp 运行结果&#xff1a; 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操作系统&#xff0c;它基于Red Hat Enterprise Linux系统&#xff0c;是一款稳定、可靠、安全的操作系统。本文将介绍Centos系统的基本使用方法&#xff0c;包括安装、命令行操作、软件安装和系统管理等方面的内容。 安装Centos系统 Centos系统可以从…...

IDEA生成ER图、UML类图、时序图、流程图等的插件推荐或独立工具推荐

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

Python心经(3)

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

单工,半双工,全双工通讯

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

【2023-05-09】 设计模式(单例,工厂)

2023-05-09 设计模式&#xff08;单例&#xff0c;工厂&#xff09; 单例模式 顾名思义&#xff0c;就是整个系统对外提供的实例有且只有一个 特点&#xff1a; ​ 1、单例类只有一个实例 ​ 2、必须是自己创建唯一实例 ​ 3、必须给所以对象提供这个实例 分类&#xff…...

批量任务导致页面卡死解决方案

需求背景 需要基于高德地图展示海量点位&#xff08;大概几万个&#xff09;&#xff0c;点位样式要自定义&#xff08;创建DOM&#xff09;&#xff0c;虽然使用了聚合点&#xff0c;但初始化时仍需要将几万个点位的DOM结构都创建出来。 这里补充一句&#xff0c;高德地图在2.…...

避免“文献综抄”,5种写作结构助你完成文献综述→

很多作者可能有过这样的体验&#xff1a;读了很多文献&#xff0c;但在写综述的时候总感觉不像是在写文献综述&#xff0c;更像在写文献总结 如果引用方面不注意&#xff0c;甚至会成为文献综抄。 那么&#xff0c;你可以参考下我们整理的以下资料哦~ 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&#xff08;全称为Microsoft Access&#xff09;是一个关系型数据库管理系统&#xff08;RDBMS&#xff09;。它是由微软公司开发的数据库软件&#xff0c;用于创建、管理和操作数据库应用程序。 Access提供了一个可视化的开发环…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...