欢迎光临散文网 会员登陆 & 注册

C语言程序设计[浙江大学·翁恺]

2022-11-15 22:51 作者:善假001  | 我要投稿

printf()在使用·时,所有小于int的如:char,short都会·转化为int,大于int的都会转化为longlong

如果要以整数的形式输入一个char,是没有办法的,必须先输入给一个整数类型,再赋值给char


1、abs( x )函数

格式:int abs( int i );

作用:求整型数的绝对值

例子:

#include<stdio.h>

#include <stdlib.h>

#include<math.h>

main(  )

{

int a = 1, b = -2 ;

printf("%d的绝对值是%d,%d的绝对值是%d\n", a, abs( a ), b, abs( b ));

}

运行结果为:1的绝对值是1,-2的绝对值是2

2、fabs( x )函数

格式:float fabs( float i ); / double fabs( double x );

作用:求浮点数的绝对值

例子:

#include<stdio.h>

#include<math.h>

main(  )

{

float a = 1.4, b = -2.7 ;

printf("%f的绝对值是%f,%f的绝对值是%f\n", a, fabs( a ), b, fabs( b ));

}

运行结果为:1.400000的绝对值是1.400000,-2.700000的绝对值是2.700000


扩展资料:

其他math.h头文件包含函数介绍:

1、 三角函数

double sin(double);正弦

double cos(double);余弦

double tan(double);正切

2 、反三角函数

double asin (double); 结果介于[-PI/2,PI/2]

double acos (double); 结果介于[0,PI]

double atan (double); 反正切(主值),结果介于[-PI/2,PI/2]

double atan2 (double,double); 反正切(整圆值),结果介于[-PI,PI]

3 、双曲三角函数

double sinh (double);

double cosh (double);

double tanh (double);

4 、指数与对数

double frexp(double value,int *exp);这是一个将value值拆分成小数部分f和(以2为底的)指数部分exp,并返回小数部分f,即f*2^exp。其中f取值在0.5~1.0范围或者0。

double ldexp(double x,int exp);这个函数刚好跟上面那个frexp函数功能相反,它的返回值是x*2^exp

double modf(double value,double *iptr);拆分value值,返回它的小数部分,iptr指向整数部分。

double log (double); 以e为底的对数

double log10 (double);以10为底的对数

double pow(double x,double y);计算x的y次幂

float powf(float x,float y); 功能与pow一致,只是输入与输出皆为单精度浮点数

double exp (double);求取自然数e的幂

double sqrt (double);开平方根

5 、取整

double ceil (double); 取上整,返回不比x小的最小整数

double floor (double); 取下整,返回不比x大的最大整数,即高斯函数[x]

变量定义的一般形式就是:类型名称+变量名称+;

如:int price;

int amount;

int price,amount

在scanf里读取什么东西,需在该东西前加&否则无法读取

整数除法会省略小数点后面的数,要求有小数点的数值,需要使用浮点数





数据类型:

1.整数:int,printf(“%d”,...)

scanf(“%d”,...)

2.带小数点的数:double,printf(“%f”,...),scanf(“%lf”,...)

3.运算符(operator):是指进行运算的动作,比如加法运算符“+”,减法运算符“-”

算子(operand):是指参与运算的值,这个值可能是常数,也可能是变量,还可能是一个方法的返回值

4.两个整数的运算结果只能是整数

整数运算没有小数部分,因此要使用浮点数,若在设置变量,则变量的赋值有小数,因此用double,而不用int,输出时,有小数,因此使用%f,而不是%d

一般自左向右

单目+-赋值=自右向左

赋值运算会把右边的式子先算完再来和左边的变量结合,如:

total*=sum+12

total=total*(sum+12)



如果

if(条件成立){

...

}


优先级:所有的关系运算符的优先级比算数运算符,但是比赋值运算符


else,if后面可以没有大括号,但只有那第一句(;之前)是有效的

注意:写程序是写步骤,而不是写关系和说明。(非常重要)

区分内嵌式和级联


使用级联时:大于,从上往下数字大到小小于,从上往下数字小到大


平均数代码的选择,一个判断做两次会浪费,如下


随机数:每次召唤rand()就得到一个随机的整数


两种形式:1.i=0;i<n

2.i=1;i<=n

小套路:做求和的程序时,记录结果的变量应该初始化为0,而做求积的变量时记录结果的变量应该初始化为1。

循环内定义


这里while循环的i虽然也只在循环内使用,但由于进入while前需判断,故应在循环前就定义int=i



如果是在for循环里面,break后的本轮的i++是不会做的就直接跳出循环,而continue会做完本轮的i++再进入下一轮

枚举:

在除号俩边有一个是浮点数,则计算机会把另一个数也变成浮点数

整数逆序:

d=x%10

ret=ret*10+d

整数逆序只适用于末尾没有0的数

gcd:最大公因数

注意 0与一个数的最大公约数是这个数本身,所以0与0的最大公约数是0。






sizeof是静态运算符它的结果在编译时刻就决定了

不要在sizeof的括号内做运算,这些运算是不会做的







八进制输出用%o,十六进制用%x

如果赋值带字母,则小写x就输出小写的a大写的X就输出大写的A










超过范围的浮点数:

printf输出inf表示超过范围的浮点数:+-∞

printf输出nan表示不存在的浮点数





输出%得用俩个%%







承接上文:对于printf,任何小于int的类型会被转换成intfloat会被转换成double。

但是scanf不会,要输入short,需要%hd



bool:#include <stdbool.h>

之后就可以使用bool和true、false

x∈(4,6)表示为x>4&&x<6

回忆:逻辑运算符<关系运算符,单目>双目

优先级:所有的关系运算符的优先级比算数运算符的低,但是比赋值运算符的高


条件运算符:1.问号?前是条件问号后面是条件满足时的值冒号:后面是条件不满足是的值。


2.条件运算符的优先级高于赋值运算符,但是低于其他运算符

3.自右向左结合


逗号运算符:

目前来说逗号运算符只有在for循环中使用

for(i=0,j=10;i<j;i++,j--)

函数是一块代码,接受零个或多个函数,做一件事情,并返回零个或一个值

调用函数

1.函数名(参数值);

2.()起到了表示函数调用的重要作用

3.即使没有参数也需要()


可以赋值给变量;

可以再传递给函数;

甚至可以丢弃;



声明:检查你对函数的调用是不是对的,以及和定义匹不匹配。


把函数的头取出来加上分号;就变成函数原型

上图最后一点注意

当你值和函数头里的参数类型不匹配时,数据会发生混乱




本地变量



1.定义函数时后面的()是参数表,用来填入参数,当没有参数时,填(void),或者不填,但是不填表示参数表未知,并不代表没有参数。最好确认没有参数后填进void,否则当你值和函数头里的参数类型不匹配时,数据会发生混乱。当然,int main()同样

2.在调用函数时,括号里的逗号不是运算符,如:f(a,b),但如果是f((a,b)),那就是了,区别就是传了俩个还是一个参数进去

3.注意:c语言不允许嵌套定义,一个函数里允许放别的函数的声明,但不允许放别的函数的定义。

4.给return返回值时,不要加括号,虽然没影响,但是容易误解return也是定义函数,把参数i的值传进return

int main()返回return 0;是有意义的,有程序会查看



数组


右边叫右值

赋值号右边是读取,左边是写入


数组的单元

1.数组的每个单元就是数组类型的一个变量。

2.使用数组时放在【】中的数字叫做下标或索引,下标从0开始记数。


这里的下标自动从0开始计数,故循环内不用初始化cnt,否则无法定义数组d


统计数的个数

数组运算


int count[number];

for ( i=0;i<number;i++ ) {

count[i]=0;

}可以表示为:

int count[n]={};

其中大括号中第一个数字给数组的第一个单元赋值,其余没写的赋值0

数组的大小








使用平方根sqrt()必须写入#include <math.h>





a[i,j]=a[j],逗号运算符,从左向右,取逗号右边为运算结果

二维数组的初始化

大括号中的大括号也可以不打,二维数组在内存中的排列跟一维数组是一样的,将这个矩阵从左上角到右下角,用这些数字逐行的填满,为了让人类读者容易理解,可以加大括号


tic-tac-toe游戏制作步骤:



行列代码基本相同

&a==a==&a[0]==&a[1]地址相同

指针p的值是某个变量的地址

*p是一个int所以p是一个指针


以上都不行

地址中变量的地址是堆栈的,先写的变量的地址更高(大),后写的变量地址更低(小),且他们是紧挨着的


指针:定义一个指针要*+一个变量->*p,这算是一个指针

int* p=int *p只是星号位置不同,定义俩个指针需要俩个星号不能理解为int *p,q;而是int *p,*q;



*是一个单目运算符,用来访问指针的值所表示的地址上的变量

当*p作为一个整体时,可以看作是一个·整数

数组参数:

在函数参数表中是等价的

一般函数的参数与调用他的地方是没有联系的,指针改变了这种情况

数组在传入函数前后地址没发生改变,但sizeof改变,传进函数里的数组的大小是指针的大小,实际传进后就变成指针了。

故没法在函数里头用sizeof得出正确的函数个数,且在中括号里定义大小也没有用。

在参数表里把数组写成指针的样子也是可以的

64位系统下一个指针的大小是8个字节,而一个int的大小是4个字节




要么是指针不可修改,要么是通过指针不可修改

数组变量是特殊的指针,其实就是数组的第一个元素的地址当然了,其实这也是一个Const 类型的指针,其实说白了就是一个常量指针,

所以有以下性质:

1.数组变量本身表达地址,所以

int a[]; int *p=a; //无需用&取地址值

但是数组的单元表达的是变量,需要用&取地址值

a==&a[0]

2.[]运算符可以对数组做,也可以用指针做:

p[]<⇒ a[0]

3.*运算符可以对指针做,也可以对数组做

*a=25;

4.数组变量是const的指针。所以不能被赋值

int a[] <==>int *const a=



指针应用场景

1.交换俩个变量的值


2.

例子:



注意:定义了指针变量,还没有指向任何变量,就开始使用指针,这样是不行的,因为没有指向变量,则这个指针的随机初始值是个乱起八糟的东西,如果把这些当地址则会指向莫名奇妙的地方,如果*p=12则你是试图往那个地方写入12,这样往往不会成功,有时可能会,但要避免这种错误


给指针+1是让他指向下一个单元,给实际的指针值加上的sizeof的基础类型大小,char为1,int为4

*(p+1)=c【1】=p【1】






int *q-》char *p,*q=0-》p【0】--p【3】=0

一个q四个字节,一个p一个字节




下列代码能知道你的编译系统有多少空间能被你使用


注意要还空间 free()


free(NULL)不做事情

定义指针初始化为0,由于某些原因导致没有malloc,或malloc得到一个失败结果,free(0)与之配合,使程序不会崩溃,你申请了什么空间,就得还什么,不能free(1)啥的



'\0'=0就是整数0,与‘0’不一样


"Hello,"

"World"中间没有任何其他符号

"Hello,

\world"

以下三种数组初始化类型:



用指针定义字符串,这个字符数组在地址很小的地方,称为代码段,只能只读,不能修改如s【0】=B














函数名: scanf 

功 能: 执行格式化输入 

用 法: int scanf(char *format[,argument,...]);

scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。

其调用格式为:     scanf("<格式化字符串>",<地址表>);

【注意】scanf函数的返回值是重点,必须理解。

scanf()函数返回值分为3种:

(1)返回正整数。表示正确输入参数的个数。

(2)返回整数0。表示用户的输入不匹配,无法正确输入任何值。

(3)返回-1。表示输入流已经结束。在Windows下,用户按下CTRL+Z(会看到一个^Z字符)再按下回车(可能需要重复多次),就表示输入结束;Linux/Unix下使用CTRL+D表示输入结束。

printf函数介绍就忽略了,不是本题目的重点。

参考代码:

#include<stdio.h>

int main()

{

    int a=0,b=0;

    while(~scanf("%d%d", &a, &b))   //下面有关于~的解析

    {

        printf("%d\n",a+b);

    }    

    return 0;

}

上述程序正常输入时,没有任何问题,比如:

输入 1 2 打印3

输入10 20 打印30


有很多读者对 ~ 不能理解,我就重点介绍一下吧。

(重点,重点,重点!!!!!!!!!!作笔记了!!!!)

关于~的作用解析:

1、在Windows下,用户按下CTRL+Z(会看到一个^Z字符),会停止输入流,scanf会返回-1。

2、-1的补码为11111111 11111111 11111111 11111111 一共4个字节。

3、~是C语言中的按位取反,因此~(-1)结果为00000000 00000000 00000000 00000000刚好为整数0的补码。

4、因此当输入Ctrl+Z时,scanf会返回-1,while(~-1)==while(0),0为假,退出while循环。


strlen



若比较数组名

char s1[];

char s2[];

s1==s2;结果永远是flase,因为俩个数组地址不相同






若*p=strchr(s,'l');p所指的字符串为llo

p=strchr(p+1,'l');在p上再寻找l,现在p指向的字符串为lo

若要把l前的字符串复制到另一个字符串里则

*p=strchr(s,'l');

char c=*p;->c为l

*p='\0';

char *t=(char *)malloc(strlen(s)+1);

strcpy(t,s);此时s所指的字符串就是he了

printf("%s",t);

输出为he

free(t);

最后一般要把l还回去

*p=c;

寻找时第二个忽略字母大小写

























.的优先级高于&

数组之间不能赋值,但结构之间可以赋值。


结构指针作为参数比拷贝结构更有效


结构数组:


可以定义结构中的结构

struct dateAndtime {

struct date sdate;

struct time stime;

}





可以认为typedef到新名字Date之间的所有东西简化为一个新的类型名字Date

若设置的很复杂,可直接看最后一个单词,这个“一个”单词才是这个新类型的名字







_func_表达的是当前函数的名字

如果函数内部存在与全局变量同名的变量,则全局变量被隐藏


函数结束以后,那个本地变量的地址会分配给下一个函数(里面的本地变量使用)


没有值的宏


像函数一样,不过靠近函数名字的圆括号里面的变量没有类型,然后再空格后的括号里面是被替换的东西比如

#define cube(x) ((x)*(x)*(x))

cube(5)调用时会被替换成((5)*(5)*(5))

如果int i;scanf("%d",&i);然后再cube(i)也是可以的

带参数的宏

定义宏决定不能在后面加;分号



如果代码里面没有函数原型,则你调用时,系统会猜测你这个调用的函数都为int型

编译单元

一个.c文件是一个编译单元

编译器每次编译只处理一个编译单元

要把该头文件放在项目里




estern是变量的声明




%d:







%*[^,]的意思是到,前所有的东西跳过

%[^,]到字符串前所有东西当作字符串赋给变量


很多初学者会对进制存在疑惑 比如为什么在十六进制存储中一个字节是用两个字符来表示?比如用0a表示10 用03就表示3呢?


因为一个字节8个比特(8位),就是8个二进制位


四个二进制数最大表示为15,就是一个16进制数,所以8位可以表示成2个16进制的数!

所以这么理解:一个字节表示8个二进制位 表示2个16进制位

这是从存储的角度来看十六进制

然后比如要把十六进制转换成使十进制

例:2AF5换算成10进制(比如这里的5占了4位 F5就是占了一个字节 所以2AF5占了2个字节)


用竖式计算:


第0位: 5 * 16^0 = 5


第1位: F * 16^1 = 240


第2位: A * 16^2= 2560


第3位: 2 * 16^3 = 8192


直接计算就是:


5 * 16^0 + F * 16^1 + A * 16^2 + 2 * 16^3 = 10997


要区分开来理解

————————————————

版权声明:本文为CSDN博主「后季暖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_51981189/article/details/125715833

用>和<做重定向,<把输入给一个文件,>把输出给一个文件





ptr是你要对其进行操作的文件名,size是这个文件有多大



























array_at为什么是指针不直接写int?

因为直接printf是无意义的,没有初始化任何值,但如果是指针可以在printf之前,进行*赋值



这个C语言的函数为什么修改了传入的指针却没改变main函数里的值?

head只是局部指针变量,想要在另外一个函数中改变,就要用指针的指针

函数原型修改为: void add(Node **head,int number)

调用改为: add( &head, number);

赋值改为:*head = p;

在add函数里的head是指针的指针,它是main函数中head指针变量的地址

第一种方案:定义结构指针型函数,结束时传head回去,并在主函数中,head=add();

第二种,数据结构


链表遍历

print函数

搜索


意味着在->左边的指针不能是NULL

删除

清除


C语言程序设计[浙江大学·翁恺]的评论 (共 条)

分享到微博请遵守国家法律