C语言 1.double指的是双精度实型变量,也就是说赋给变量的值将以双精度实型格式存储在内存中。 %d (十进制有符号的整形) %u (无符号的十进制整数) %o (是可以显示八进制) 在数前面用0开头表示的是8进制的数 %x (显示十六进制) 在数前面使用0x开头表示的是16进制 % 在数字前面使用0b开头表示的是2进制 2.小数对应的,,,printf(x=“%lf”,x) 针对于double 因为double的浮点数更长 通常使用的是%f,进行了打印的(针对于float) 这个是打印出来的 printf(x=“%.1lf”) 这表示的是保留一位小数, %.2lf 表示的是保留两位小数 计算浮点数时,要有小数点,如果全是整型的,那么结果就算是循环的,最后得到的也是整数 float a=0.5f 意思就是浮点数的常量赋给浮点数的变量 3.char 后面加的字母要用单引号包起来,单引号里面只能放一个字符 %c 是以字符的形式显示的 一个汉字占两个字节,一个 ? 也占两个字节 char str[ ] =”xxxx“ ; 这样的可以在双引号里面接字符串 打印时用的是%s 4.无符号数 如果int中出现负号的,那么这个数字会变成他的补码形式 5.强制类型转换 在上面是double的话,下面要是想给整成int的话,就要在下一行int a=(int) d 打印时是将a进行打印 5.运算时小括号可以充当大括号的样式 6.<<1是让所有bit位进行左移动一位,如果原赋值是10,那么移动一位就是在10的基础上乘以2的1次幂, 要是移动两位那就是10乘以2的两次幂
1将比特位右移,就是将前面表示的数值进行除2 7.逻辑运算符 1)判断a的值是否小于0,我们可以直接使用小于符号进行判断,得到结果只能是0或1; 虽然结果是一个整数,但是这里推荐使用_Bool类型进行接收,它只能表示0和1(更加专业一些) 非0的数表示的是真, 2)使用&&表示逻辑与,逻辑与要求两边都是真,结果才是真 printf(“xxxxxx”,c>='A'&&c<='Z'); 3)使用||表示逻辑或,只要其中一个为真或是都为真,结果就是真 printf(“xxxxxxx”,c<'A'||c>'Z'); 4)!= 是不等于的意思 == 是判断等不等于的意思 )printf(“xxxx” ,!(c=‘A’)); 打出来,如果里面原来是1,加上!之后显示的就是0 6)三元运算符 样式char c=i >10? 'A' : 'B'; 表示的是如果c的值大于10,那么打印出来的就是A,否则就是B 8.+= 一个数加上1后再返回 == 是判断运算符,表示的是等号前面的量与后面的是否一致, 通常使用 int price=28; if(price=28){ printf(“符合条件”); ni}
9.布尔函数
#include<stdbool.h>放在头函数那里然后后面可以使用布尔函数
bool xxx=ture或false
10.使用
int price = 28000;
if((price!=28)==ture){
printf(“符合条件”);
} 这样表示的意思就是当price不等于28时,表现的就是ture,打印出来的符合条件
11.逗号运算符
int a=(100,200); 使用到逗号运算符,将逗号后面的值赋给a
样式就是
a=(a+=2,aa); += 表示的是a加上2,结果再赋给a,逗号运算符在这里面表示的是将aa的结果再赋予a本身
12. a++ 这样的表示一般是a先参与运算,然后再进行自增
++a 这样是a先自增,然后再打印
++n + ++n + ++n 是将n+三个一才开始求和
13.运算的优先级
一般都是从左到右,但也有从右到左的
从右到左的样式,
int a,b,c,d;
a=b=c=d=100;
a += b += c += d += 100;
printf(“%d,%d,%d,%d“,a,b,c,d);
14.
if语句
if (sum>200){sum -=5;
}
else {
sum;
}
if else if……语句 其中if和else可以重复使用 if(sum>200){ sum -=10; } else if(sum>100){ sum -=5; } else if(sum>5){ sum -=3; } printf("%d\n",sum); 如果第一个条件为true,那么执行后面{ }里面的内容 如果第一个条件为false,那么就会判断第二个条件 15.scanf输入内容 scanf_s("%d",&num); 在scanf后面加上_s是比较安全的,这样系统不会报错,&这个符号表示的是把参数送到地址 16.switch条件分支 也是条件判断语句的一种,是对于某一个变量的判断 switch(要判断的变量){ case 情况一: 情况一要执行的代码 break; case 情况2: 情况二要执行的代码 break; default:xxx; } 其中break表示的是断点,每一个case是每一个情况,如果有一个满足那么就会到那个case断开,后面的就不再执行;default后面接的死上述情况都不满足的时候执行的代码 注:switch中 case后面接的只能是常量,不能是变量 17.switch中涉及到的穿透 样式是 int month=2; switch(month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: printf("31天"); break; case 2: printf(“28天”); break; 后面剩下的也差不多是一样的 } 18.while循环 为了保证不发生死循环会让while后面的值发生改变 int n=0; while (n<3){ printf("%d\n",n); n++; } 一定要有自身条件的改变,否则就会陷入死循环 n++ 中加的数值就是步长 19.while实战 int n=0; printf(“请输入数字\n”); scanf("%d",&n); 输入 int sum=1; while(n>=1){ sum*=n; 按照输入的数字依次减一然后想乘 n--; } printf("%d",sum); 20. do while 样式 1)int n=1; do { printf("%d",n); }while(n>1); 意思就是先做(就是进行判断一下),然后再进行循环 2)int n=1; int sum=0; do{ sum +=n; n++; }while(n<=100); 这样就是在累加中应用do while 21.for循环 其中i可以改变其步长 for(int i=0;i<10;i++ ){ printf("%d\n",i); } 这里面的意思就是i从0开始,经过i++后,判断i<10,然后再打印出来 注:i放在括号里面使用,防止对外界干扰 22.循环控制语句 break 在程序中输入break,程序会直接结束 通常都在if语句中使用break,那么如果程序中出现不满足if里面的,当程序走到break的时候就会自动断开 continue continue在的那部分条件语句程序会直接跳过去,不再执行 23.函数 定义一个函数, 下面括号里的叫行参 xxxx_printf( ){ printf( “xxxx”); } 然后在下文中可以直接引用 xxxx_printf(); 1)函数内部变量外部是无法访问的 2)实参 形式参数是放在上面的,就是在主体函数里的,而实参则是进行实际操作输入的 在xxx_printf(X){ printf( “xxxx”); } 调用函数x可以搞函数有多少行 在括号里面要是整形的数,括号里面的数叫实参 24.函数还可以计算 就是 xxx(int x,inty,int z){ int sum=0; sum = x +y +z; printf("%d",sum); } int main{ xxxx(10,20,30); } 25.函数的返回值 在函数里面将printf不要了 然后返回值变成上面的量 在下面直接就是 xxx(int x,y,z){ sum=x+y+z; return sum; } int main( ) {int mysum=xxx(10,20,30); printf(“%d”,mysum);} 通常要是int类型,返回值都是return 0; 一般要是会出现值的话,就可以不用返回值,那样在最前面写上void(空返回) 26.返回值也可以当断点使用 比break更强,直接得出结果 return 可以在函数中间位置停掉,使后面的程序不在执行 27.函数的声明 把自己要调用的函数放在main函数上面,以便后面进行调用 函数整体分为三部分,声明,调用,定义 其中调用放在主体部分,也就是main的后面 定义放在最后 #include <stdio.h> void xxx( ); //声明 int main{ xxx( ); //调用 } void xxx(){ //定义 printf("hello kerwin"); } 28.一般用<>这样包的都是调用库函数 在#include“ ” 里面写着要调用的路径,且后面不要有任何符号 然后在头文件里面在 前面写上extern + 函数 然后在原文件里面可以直接引用 29.内存:物理内存、虚拟内存 物理内存:实实在在存在的存储设备 虚拟内存:操作系统虚拟出来的内存 操作系统会在物理内存和虚拟内存之间做映射 在写程序时,看到的都是虚拟地址 30.在运行程序的时候,操作系统会将虚拟内存进行分区 1)堆 在动态申请内存的时候,在堆里开辟内存 2)栈 主要存放局部变量 3)静态全局区 1.未初始化的静态全局区 静态变量(定义变量的时候,前面加static修饰),或全局变量没有初始化的加在此区域 2.初始化的静态全局区 全局变量、静态变量、赋过初始值的、存放在此处 4)代码区 放代码 5)文字常量区 存放常量 31.全局变量 在函数外部定义的变量,叫全局变量 32.%p 是可以显示打印出来的东西在程序中所占的内存的地址 设置在另一个源文件里面的,在两个文件里都输入%p的样子, 33.静态变量 在正常变量前面加上 static int mysum; 就是对那个变量进行特定的标记,即使后面有一样的,再详细的也会不同 34.局部变量 main里面的不能拿到外面使用, 局部的静态变量,能让程序每进行一次时不开辟新的空间 35.数组 数组是若干个相同类型的变量在内存中有序存储的集合 int a [ 5 ]; 定义了一个整形的数组a,a是数组的名字,数组中有五个元素,每个元素类型都是int类型,而且在内存中连续存储 这5个元素分别是a[0] a[1] a[2] a[3] a[4] 样式 int a[5]={1,2,3,4,5}; 定义: 1、初始值多的不行 2、少可以;默认值是0 打印是printf(“”%d\n ,a[4]); int b[ ]={1,2,3,4,5 }; 这种情况是未知赋值空间的,直接在花括号中输入,要是想将值附进去就直接写b[1]=200;这样的 36.sizeof( 类型 ) 表示的是在内存中所占的字节数, printf(“%d\n”,siezof(weight2)/sizeof(int)); 这样可以灵活的表示单个数据在内存中占的内存 37. float b[5]={1.1f,2.2f,3.3f}; for(int i=0;i<5;i++){ printf("%f\n",a[i]); } 循环的目的是为了将所有的数组中的数字打印出来 38.字符串 char name1[ ]= "kerwin"; printf("%s\n",name1); 共三个形式: char name2[ ]={'k', 'e', 'r', 'w', 'i', 'n', '\0'}; char name3[ 7 ]="kerwin"; 标清有几个字符和上面的那个分开写的差不多,但上面的最后要加上‘\0’, 39.二维数组 int grades[ 3] [3]={ 表示的是前面的那个3,表示的是行,后面那个表示的是列 然后前面的那个3叫做行下标,后面的3叫做列下标
{ 98, 99,100 },
{ 100,102,103 },
{ 104,105,106 },
}
在这里可以省略行数,但不能略列数
在这里面要是打印特定的,就是
printf(
"%d\n",grades[ 0][2 ]
) ; 这样要表示的就是在grades这个数组中要打印第一行第三个数
40.用char数组还可以存放字符串
char str[ ][ 100 ]={
"hdkgsu","huifbiuey","hubev","诸葛山珍"
};
for(int i=0,i<sizeof (str)/(sizeof(char)*100) ,i++ )
printf("%s", str[i] ); 还可以是printf(“%d”,str[ ][ ]);
前面的表示行后面的表示列
41.放置更多的数据
int school[2][2][2]={
{100,99},
{ 98,100 }
},
{
{100,99},
{98,100}
}
表示的就是第一个2,表示大体上的数组,第二个是表示在小范围里面的行,第三个则表示的是列
这里面的计数法是从0开始计数的
42.冒泡排序法
要使数据中的数进行排序,那么就要使用数组及循环的应用
for(int i=0;i<sizeof(arr)/sizeof(int)-1;i++){
if(arr[i]>arr[i+1]){
// printf("%d\n",arr[i+1]);
int temp=arr[ i ];
arr[i]=arr[ i +1];
arr[i+1]=temp;
} } 在这里使用到了减一,这是为了最后一个数据能有可比的 多次使用这样的for循环,会使大的数逐渐沉到底部, 然后在后面进行for循环的时候 要在i<sizeof(arr)/sizeof(int)-1-1 这样是为了能够使前面的数有可比的后一个数,以为最后面的大数一直是大的,如果不变的话那样就没有了意义
还有更简单的方法就是在外面再嵌套一个for循环 for(int i=0; i<sizeof(arr)/sizeof(int)-1; i++){ for(int j=0; j<sizeof(arr)/sizeof(int)-1-i ; j++){ int temp =arr[ j ]; arr[j]=arr[j+1]; arr[j+1]=temp; } } 打印时还要使用到for循环 for(int i=0;i<sizeof(arr)/sizeof(int);i++){ printf("%d\n", arr[ i ]); } 43.选择排序法 在前面设置的index是整形函数,如果后面要是把它给放在数组里面表示的是数组中数据的具体位置 for(int i=0;i<sizeof(arr)/sizeof(int);i++){ int index=i; for(int j=i+1;j<sizeof(arr)/sizeof(int);j++){ if(arr[ j ]<arr[ index ]){ index=j; } } int temp=arr[i]; arr[i]=arr[index]; arr[index]=temp; //这就是相当于转换数据,引入第三方的中间量,使两个值的位置进行调换 } 44.在取地址符那里面可以加上变量里面的的可以存放的字节数量 char name[7]; scanf("%s",name,7); 这样的 45. int a; scanf("%d",&a); 要是不写&是不可以的,因为int a中的a是一个不被定义初始值,只有加上&号才会显示它的地址 取a的地址,使用%p的占位形式,可以显示a在程序中的地址 要是char name[ 7 ]; scanf("%p",name);这样的就可以省略& 46.指针 int p=&a; printf(“%p\n”,p); 指针在这里面是存储a的地址,修饰p是个指针变量 在一个函数中 void kerwin_scanf(int p){ p=1000; 通过地址访问了这个变量 } int main( ){ int b; printf("%p\n",&b); kerwin_scanf(&b); printf("%d\n",b); } 47.指针与数组 在前面给一个数组初始化然后在后面 int p=arr; 在打印时printf(“%d\n”,(p+1)); arr[0] p[0] (p+1) ,,这样显示的是数组中的第一个数 现在放在printf后面的arr,&arr表示的是一样的 然后再看&arr+1,与其他的不同,表示的是它跳过整个数组长度 48.指针类型 字符型指针:字符型数据地址 charp;定义了一个字符型指针变量,只能存放字符型变量地址 短整型指针: shortp;定义一个短整型的指针变量,这能存放短整型变量的地址 整型指针: intp;定义一个整型的指针变量,这能存放整型变量的地址 长整型指针: longp;定义一个长整型的指针变量,这能存放长整型变量的地址 float型的指针 floatp:定义一个float型的指针变量,这能存放float型变量的地址 double型指针 doublep;定义一个double型的指针变量,这能存放double型变量的地址 无论什么类型下的指针,在32位系统下,都是4个字节 49.实操 char ch='k'; 先定义个字符变量 char*p=&ch; 再定义个字符型指针变量 *p='e'; 然后通过这个指针变量来改变原来的 50.指针数组 定义一个数组,数组中有若干个相同类型的指针变量,这个数组被称为数组int *p[5],指针数组本身是个数组,是个指针数组,是若干个相同类型指针变量构成的集合 char *str1[ ]={"kerwin"}; char *str2[ ]={"xxxx"}; 可以将他们整合 char str[3]={"kerwin","xxxx"}; 打印的时候如果打印的是str[i];则后面显示的是首字母 printf(“%c\n”,str[i]); 如果将c改成了s那么打印出来的就是整个字符串了 printf(“%s”,str[i]); 51.想将值给数组,在给数组弄上指针 int arr1[ ]={10,20,30}; int arr2[ ]={40,50,60}; int arr3[ ]={1,2,3}; int arr[ ]={arr1,arr2,arr3}; 通过使用printf(“%d\n”,arr[i][0]); 还可以使用printf("%d\n",(arr[i]+1)); 这里面指的是取到了arr这类的指针数组的地址,然后打印的是%d,所以显示出来的就会是具体的值 52.存两个就是对指针的地址t读取 要是取指针的地址的话就要在里面加上两个星号
如果在printf那要是写**p2的话,那么指示的就是a的值但同时还要注意前面%后面的东西 53.
int arr[][3]={ };
int (p)[3]=arr;
这里所表示的是一个有三列的二维数组指针
55.
在打印中要是printf(''%p'',&arr+1);这样的,改变的是他这个数组的一行,意思就是将地址直接跳转他这个数组元素的最后,且不为最后那元素的地址
要是将它的地址给二维数组的指针,最后出来的地址和上面的一样
int (p)[5]=&arr;
然后打印
56.关于指针返回值
一维数组的指针返回值是一个
二维数组的指针返回值是两个
然后这里的返回值多用于在调用函数里面的
int(* func())[2]{ 这是返回二维指针的写法
static int arr[][2]{ 这里面要是用静态的整形存储
{11,22},{33,44}}
return arr;}
57.定义一个新类型
typedef int(kerwinerwei)[2];
58.函数指针
先定义一个函数,int max(int x,int y);
然后再调用它
int(p)(int ,int)=max;
p(30,20);
但是还可以在这里面放置函数的数组指针
就是int(p[ ])(int,int)={max,add};
要是放到运行上就是
int res1=(p)(1,2);
这样显示的就是指针p指向的第一个函数类型,然后再将这两个值放进去
或者写成
int res2=(p[1])(11,22); 这样也可以显示11,22使用的函数
59.回调函数
把一个函数当成参数,然后在另一个函数中可以进行回调
void myshow(int a,int b){
printf("压缩进度%d----%d\n",a,b)
}
void compress(char file_name, void(cb)(int,int)){
printf("开始压缩数据");
pritnf("开始更新压缩进度\n");
cb(50,120);
}
int main(){
compress("kerwin.jpg",myshow);
}
60.要是想显示出指针数组里面的具体的值
就要用到双指针
1)int a[5]; 这里是指针数组,数组里面每个元素都是int类型的指针变量
2)int(a)[5]; 这是数组指针变量,这里表示的是一个二维数组,如果要是打印a+1的话,在系统中就会跳到他的下一行,也就是直接跳过20个字节
数组指针变量主要存储的是数组的地址
3)int **p; 这里是指针的指针,保存指针变量的地址
4)int f(void);
注意:f没有用括号起来
这是个函数的声明,声明的这个函数返回值为int类型的
5)int(f)(void);
f用括号括起来了,修饰f说明,f是个指针变量
f是个函数指针变量,存放函数的地址,他指向的函数
必须有一个int型的返回值,没参数
61.特殊指针
int num=0;
void vp=&num;
printf("%d\n",(int )vp); 这里面的样式是为了将指针类型的量转换成int类型的量,而且在这里只能保存指针的值,并不会记录指针指向的类型
这里面涉及的是空类型指针
他还可以指向数组
charp[2]={"kerwin","tiechui"};
voidarrp=p;
printf("%c\n",((char )arrp)[0][0]) 这里用了强制转换char,两个表示的是char带的一个和去=取地址的那个,后面的【】【】第一个是kerwin 第二个表示的是k
因为对于这种通用型接口,你不知道用户的数据是什么,但是你必须能够处理用户的各种类型数据时会使用到void能包容的接受各种类型的,也就是说,如果你期望接口能够接受任何类型的参数,你可以使用void类型,但是在使用的时候,你必须转化为具体的这类型,例如你转入接口的是int那么你在使用的时候就应该按照int使用。
为了能够接收不同类型的数据,
void swap(voida,voidb,type){
if(type==1){
int temp=(int*)a;
(int)a=(int)b;
()intb=temp;
}else{
float temp=(float )a;
(float)a=(float)b;
(float)b=temp;
}
int main(){
float c=1.1f;
float d=2.2f;
swap(&c,&d,2);
printf("%f\n",c);
printf("%f\n",d);
}
在这里还可以使用宏定义,
在上面
#define KERWIN_INT 1
#define KERWIN_FLOAT 2
然后将下面的做一些改变就是可以实现的了
62.malloc函数
使用这个函数要现在上面写出#include<stdlib.h>
再在下面写上
int main(){
intp=(int )malloc(43);
}
malloc后面的括号里面放着动态申请的字节
<1>malloc函数
voidmalloc(int size)
在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明符指定的类型。函数原型返回void指针,使用时必须做相应的强制类型转换
返回值:
分配空间的起始地址(分配成功)
NULL(分配失败)
注意:
在调用malloc之后,一定要判断一下,是否申请内存成功。
如果多次malloc申请的内存,第一次和第二次申请的内存不一定是连续的
正所谓动态申请
可以将malloc后面括号里的写成指定的字节乘一个变量参数 ,在这里最好写成sizeof(int)的形式
63.free函数(释放内存函数)
free函数释放p指向的内存
free(p)
64.calloc函数
在内存的堆中,申请n块,每块的大小为size个字节的连续区域
函数的返回值:
返回申请的内寸的首地址(申请成功)
返回NULL(申请失败)
注意:malloc和calloc函数都是用来申请内存的
区别:
1)函数的名字不一样
2)参数的个数不一样
3)malloc申请的内存,内存中存放的内容是随机的,不确定的,而calloc函数申请的内存中的内容为0
65.calloc函数的申请格式
int number=0;
scanf("%d",&number);
char(p)[TOTAL]=(char()[TOTAL])calloc(number,TOTAL);
if(!p) return;
这里要是数组指针,每个+1,程序会跳过一行的字节,所使用的是二维数组
但是在打印的时候
for(int i=0;i<number;i++){
scanf("%s",(p+1),TOTAL); 由于调用了这个calloc函数,所以要在后面写出申请分配的数量
}
66.realloc函数
在原先s只想的内存基础上重新申请内存,新的内存大小为new_size个字节,如果原先内存后面有足够大的空间,就追加,如果后边的内存不够用,则relloc函数会在堆区找一个newsize个字节大小的内存申请,将原先内存中的内容拷贝过来,然后释放原先的内存,最后返回新内存的地址
int* p=(int*)malloc(12);
if(!p)return;
p[0]=100;
p[1]=200;
p[300]=300;
int p1=realloc(p,16);
if(!p1)return;
p1[3]=400; 通常都是写p1的
free(p1); 对p1进行释放就可以
67.内存泄漏
申请的内存,首地址丢了,找不了,再没法使用了,也没法释放了,这块内存就泄露了
泄露主要就是 刚申请完一个空间,但是将这个赋上了其他的值
char p;
p=(char*)malloc(100);
p="kerwin"; 这样显然就是不可以的
还有就是调用函数的时候,要在这里用到函数指针的返回值
char* func(num){
char* p=(char*)malloc(num);
return p;
}
然后在主函数里面用指针来接收
char x=func(100);
68.
给申请的空间里面放东西
charp=(char*)malloc(100);
charstr="kerwin";
for(int i=0;i<7;i++){
p[i]=str[i];
}这样就是可以放进去的
还可以使用字符串字符
但是要引入头文件,#include<string.h>
strcpy(p,str); 这里指的意思是将str里面的值的地址给p这个指针,
在p和str之间还可以加上字节(p,7,str);
69.测量字符串长度
一般的可以使用sizeof(p1)/sizeof(char)
这样的适用于
char p1[ ]="kerwin";
而带有指针的
charp2=“kerwin”
printf(“%zd\n”,strlen(p2));
要是与申请动态空间的联系起来的话
charp=(char)malloc(100);
strcpy(p,strlen(p2)+1,p2);
这里面的strlen(p2)+1的原因是strlen只能读取到\0的地方,所以还要再加一位,
如果要控制它复制的多少,那么就使用strncpy
strncpy(p,strlen(p2)+1,p2,6);
第一个是目标指针,第二个是指要复制字符串的长度,第三个指的是将p2上的字符串复制给p,6指的是这回只复制6个字符
70.使用strcat字符
charp=(char)malloc(120);
if(!p) return;
scanf("%s",p,100); 这里的意思是p指针里面输入的不能超过100个字节
charstr="先生/女士“;
strcat(p,120,str); 这里就给p这个指针赋上了值
120指的是将这个后加的函数放进去,一共也不超过120个字节
printf("%s\n",p);
这里也是可以有strncat的,就是在括号里的最后面加上所要限制进来函数的字节就可以
71.字符串比较函数strcmp
比较s1和s2指向的字符串大小,比较方法逐个字符去比较ascII码,一旦比较出大小,返回,如果所有字符都一样则返回0
chara="abc";
charb="acd";
int res=strcmp(a,d);
printf("%d",res);
还有strncmp
int res=strncmp(a,b,2); 后面的第三个参数指的是比较前几个字符
用的时候要引用头文件#include<string.h>
还可以用到判断两次输入密码是否一致身上
charp1=(char*)malloc(100);
charp2=(char)malloc(100);
if(p1==NULL||p2==NULL) return;
scanf("%s",p1,100);
printf("请再次输入密码\n");
scanf("%s",p2,100);
if(strcmp(p1,p2)==0){
printf("输入正确\n");
}else{
printf("两次输入密码不匹配");
}
72.strchr 可以找到某字符所在地址
给定一个值
charstr="kerwin";
charres=strchr(str,'x');
这样就是可以获取到x所在的地址,如果想要获取的单个字符是重复的,那么只能获取到第一个对应的字符的地址
还可以使用strrch这个字符函数
charres=strrch(str,'x'); 这个strrch叫末次匹配
要是遇见重复的字符,会从后面来找想要找字符的地址
为了安全
通常会加上if(res==NULL){
printf("不在");
return;
}
在使用strstr这个函数的时候,要给他拼接(strcat)上" ",这个东西上去,意思是让他后面显示的是0,这样读取的时候就会读到0这个位置就停止了
73.字符串匹配函数strstr
意思就是可以给出多个字符来找到与其对应的字符串
strstr(str[i],search) 这样的
74.字符串转换数值atoi
atoi/atol/atof 字符串转换功能
atoi 转换成数值
atol 转换成长整型
atof 转换成双精度
person=atoi(personStr);
这样会将personStr的值给转换成数值
但是在入的时候要再persobStr后面拼接个" "
75.strtok字符串处理函数
char str[100]="辽宁|大连|xxx"
char buf=NULL;
splitStr[0]=strtok(str,"|",&buf); 后面的&buf是缓冲区
这里面的buf是可以存放strtok函数后的值的
这个函数的含义是将" | "变成"\0",这样数据就会读取到这
int i=0;
while(splitStr[i]){
i++;
splitStr[i]=strtok(NULL,"|",&buf);
} 这里面i是可以递增的,然后后面这个函数可以按照i的不同来改变所要截取的值
打印的时候也是可以一样操作的
while(splitStr[m]){
printf("%s\n",splitStr[m]);
m++;
}
还有就是设置分割的可以不是"|",还可以是逗号,
在旁边将设的改一下就可以"|,"
split(str,splitstr,"%,")
split是分割函数,是将str里面的数据按照引号里面的来进行分割,然后将值赋给splitstr
76.将指针数组当作参数,要使用双指针来接收
77.空间设定函数memset
可以调整所要改变的量
charp=(char)malloc(100);
if(!p) return;
memset(p,0,1);
memset函数是将p中的值的1个变成0
就是说括号里面第一个是要改变的,第二个是要变成的特定值,第三个是改变前多少个
字符串使用是很友好的,但是要是想弄int类型的,改变值只能将值变成0或-1
78.sprintf函数
char str[100];
sprintf(str,100,"尊敬的%s先生/女士","keriwn");
100是起到一个限定作用的,可以控制后面的占str这个数组,后面的那个占位符所占的是再后面的那个字符串,拼接之后,再将整体给到str这个数组
后面的可以是其他类型的数据,多个数据中间用逗号隔开
79.sscanf函数
1)起到先录入再赋值
char*address="辽宁 大连 高新";
char str[3][100];
sscanf(address,"%s %s %s",str[0],str[1],str[2]);
先声明录入的地址,然后在表明要录入的东西范围,最后就是把录进来的东西放进去
要是为了保证安全可以在放入的后面加上限制的字节数
str[0],100 这样的
但要是在辽宁大连高新之间加上 | 这个就要使用不同的转义自符
%[^|] 这个
2)在sscanf这个函数里面
<1>有跳过数据的转义自符:就是在%*s %d 在这中间加上
<2>指定宽度:在% s的中间加上要跳过的字节宽度
<3>集合操作:%[ ] 中括号里面的东西可以是a-z,abc,^abc
[a-z]在给出这样的操作以后,程序就会把原来给的那个地址里面的东西,显示中括号里面的东西
[kerwin]要是中括号里面的是具体的字符串,那么程序中就会只显示这个字符串
[^kerwin]只要不是这里面这个字符的就行,但是要考虑顺序,如果字符串第一个值就不符合那么跳出来的就是乱码,如果有符合不是kerwin这里的,那么就可以显示出来
80.结构体
结构体是一种构造类型的数据结构,是一种或多种基本类型或构造类型的数据的集合
struct Student{
char name[100];
int age;
int score;
};
这里是一个结构体,名称是Student,位置可以放在int main()上面
结构体位置可以放在main函数的里面和外面
放在外面,这个结构体函数在哪里都可以在使用
要用结构体函数时,就可以声明struct student student1;
也可以在结构体后面给写出
struct person{
}person0,person1; 81.结构体声明 typedef struct student{ char name[100]; int age; }STU; int mian(){ STU student0={ "kerwin", 100 }; printf("%s,%d",student0.name,student0.age); 这里是可以访问到student名称的结构体 } 要是想要取结构体里面的值,先是已经有给结构体里面的量赋值的,如果要打印的话,就先是student.name这样的 <>在结构体中也可以再进行一个嵌套, 在一个student结构体里面,写ADDR address,其中ADDR是另一个结构体的名称,address是要表示的量,在下面要是在student 里面调用的话就直接引入studnet0这个下一级的量来表示 82.结构体数组 结构体数组由若干个相同类型的结构体变量构成的集合 83.结构体指针 即结构体的地址,结构体变量存放内存中,也有起始地址,定义一个变量来存放地址,那么这个变量就是结构体指针变量 struct student{ char name; int age; }; int main(){ struct student stu={"kerwin",100}; struct student myp=&stu; printf("%s\n",(*myp).name); 像这样的还会有另一种写法 printf("%s\n",myp->name); 这里面能用箭头的必须前面是地址 } 84.结构体函数 void input(STU *p){
}
input(p+i); 这里面的实参是p+i,行参是STU p;行参要声明好,是在STU里的
85.结构体里面的内存分配
规则1:
以多少个字节为单位开辟内存 给结构体分配内存的时候,会去结构体变量中找基本类型的成员的哪个基本类型的成员占字节数多,就以它的大小为单位开辟内存
1)两个int 占8个字节
多个char 是12字节
还有就是会嵌套的情况,
struct add{
int adda;
int addb;
};
struct stu{
char a;
sturct add address;
};
这样stu里面就是占到了12个字节
2)规则2
还是以最大的字节为分配单位
但是里面的其他值,是以其自己本身的字节倍数来分配的
86.链表
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接顺序来实现的
phead 头部指针
pend 结束指针
pnew 指针
87.在链表中插入
可以是执行删除操作
上面是要写个结构体删除函数的
struct student Delete(struct student* pHead){
pritnf("----删除之后---");
return pHead->pNext; 这里的意思就是将第一个的头给到了第二个的地方,所以第一个就不再显示,被删除了
}
在main函数里面写
pHead=Delete(pHead);
要是像删除第二个地方的
要在
struct studentDeletePosition(struct student pHead,int index){
struct student* pTemp=pHead;
struct student* pPre=pHead; 这里的意思就是将pHead暂时存放在PTemp里面,然后pPre是存放要删除位置的前一个,把pHead放进去
for(int i=1;i<index;i++){
pPre=pTemp;
pTemp=pTemp->pNext;
就是把要删除那个给架空了
}
} 88.在链表中插入东西 使用Insert struct student* Insert(struct student* pHead){
} 在下面 pHead=Insert(pHead); 括号里面的是原来的pHead 89.共用体------union 几个不同的变量共同占用一段内存的结构 申请好内存之后共用那部分内存 共用体特点: 1)同一内存段可以用来存放集中不同类型的成员,但每一瞬时只有一种起作用 2)共用体变量中起作用的成员是最后一次存放的成员,在存入一个新成员后原有的成员的值会被覆盖 3)共用体变量的地址和它的各成员的地址都是同一地址 总而言之,共用体开辟的内存空间可以分配给在共用体里面的元素, 90.枚举 将变量的值一一列举出来,变量的值只限于列举出来的范围 枚举的关键字是,enum 在枚举里面放置的一些变量 enum week{mon,tue,wed,thu,fir,sat,sun}; 这里面的值要是打印出来的话,就会是从0开始的数字, 要是不想从0开始,就可以在第一个变量那里进行一些改变 91.位运算 %o 是8进制 %x 是16进制 将输入进来的数以二进制进行运算 典型就是,在主函数中调用函数 void to Bin(int value){ int temp[10]={ 0 }; int i=0; while(value){ temp[i]=value%2; value=value/2; i++; } 然后要是想将数给整出来,就得倒序的打印 for(i=i-1;i>=0;i--){ printf("%d",temp[i]); } itoa 是一个函数,可以将一个十进制的数转换成其他进制的数 char string[100]; itoa(value,string,2); value--是传进来的十进制数, string--是代表着储存转换之后放置数的地方 2 --表示的是转换成多少进制 源码是正数的 一个整数占4个字节,一个字节里面是八位 在所有1,0里面,最前面的那个是符号位,0为正数,1为负数 反码是将除了符号位的数全部1,0调换 补码就是在反码的基础上加1 92.在位运算里面的& | 运算 & 二进制的数要是0,1相遇,就都变成0 | 二进制的数要是0,1相遇,就变成1 ~ 是取反的符号,给出一个数,先将这个数变成反码,再补码,然后再推原码 ^ 异或 一样的为0,不一样的为1 << 左移两位
右移两位,是在二进制里面移的
93.预处理-宏定义 1)预编译 将.c中的头文件展开、宏展开生成的文件是.i文件 2)编译 将预处理之后的.i文件生成.s汇编文件 3)汇编 将.s汇编文件生成.o目标文件 4)链接 将.o文件链接成目标文件 5)执行 94.宏定义 #define STUDENT 1 这是不带参数的宏定义 这个书写位置是在头文件那块 终止 直接写 #undef STUDENT就可以 位置在定义完量之后,就可以写这个 带参数的宏定义 #defineMAX(a,b)(a>b?a:b) 然后在主函数里面要是出现了那就可以直接用了 95.预处理-include指令 要引入自己定义的头文件, #include"106.h"这样的 96.预处理-条件编译 在形成.i文件之前,进行的预处理 首先进行了宏定义,然后在主函数中写 #ifdef kkk printf("xxx"); #else printf("xxxx"); 这里意思就是如果没声明,就会走#else这段代码,要是声明了就走#ifdef这段代码 #endif 防止头文件重复使用,就直接在头文件里面写 #ifndef kkk (叫条件编译) #define kkk extern void func(); #endif 这样在预编译里面就只会显示一次的头文件里面的内容 97.文件 typedef struct_iobuf{ int cnt; char ptr; char base; int flag; int fd; }FILE; 其中FILE 指针变量标识符 对文件操作的步骤: 1)对文件进行的鞋等操作之前要打开文件得到指针 2)可以通过文件指针对文件进行读写等操作 3)读写等操作完毕后,要关闭文件,关闭文件后,就不能再通过此文件指针操作文件了 使用文件 先定义一个文件指针 FILE fp; fp=fopen(" ",".\kerwin.txt"," "); 1)这个fopen()是库函数中带的,所以不需要引用和声明;括号里面放置的是要打开文件的名称和路径 在linux电脑和mac电脑中".kerwin.txt"是相对路径 在window电脑中".\kerwin.txt"是相对路径 一般距离近的使用相对路径,距离远的使用绝对路径 使用绝对路径时要多写"" 2)第三个引号里面要放的的读取的方式 'r','w','a','+' 这三个方式,r是只读;w是只写,但是在看的时候里面什么都没有,只能写;"a"是追加,在文件后面追加;"+"可以拼接 3)第一个引号那里是放置&fp,因为FILE* fp;将这个打开的文件放到fp指针里面去 打开文件之后要关闭文件,要使用到fclose 直接就是fclose(fp); 要是进行检查关没关闭完全,就让int eclose=fclose(fp);就可以了 在写if(eclose==0){ printf("关闭成功"); }else{ printf("关闭失败"); } 之后在运行就可以看出来,是否关闭成功 98.fgetc与fputc fgetc从stream所标识的文件中读取一个字节,将字节值返回 返回值:读到文件结尾返回EOF EOF是在stdio.h文件中定义的符号常量,值为-1 可以使用while循环来读取文件中的内容 while((ch=fgetc(fp1))!=EOF){ prntf("%c",ch); } 还可以使用fputc函数,通过while函数进行读取,然后再用fputc进行输出,fputc(ch,stdout); 这里stdout是在终端中输出 99.fgets和fputs char fgets(char* s,int size,FILE* stream); 从stream所代表的文件中读取字符,在读取的时候碰到换行符或是碰到文件末尾停止读取,或者是读取了size-1个字节停止读取,在读取内容后面会加一个'\0',作为字符串结尾 使用方式是 char str[100]; fgets(str,6,fp1); 从fp1中读取内容,读取6个字节长度的内容,存放到str这个数组里面 fputs使用方式是 fputs(str,fp2); 将str里面的内容放到fp2这个文件里面 100.fread与fwrite fread(str,sizeof(char),6,fp1); 还是从fp1中读取以char为一小单位字节,读取6个小部分放到str这个数组里面 要是读取的多了,就给str[100]=" "; 让这里面都是0就ok fwrite(str,sizeof(char),6,fp2); 把str这个数组里面的内容都放到fp2这个内容里面 这里个函数是以二进制的行式存储的 101.fprintf和fscanf int num=100; fprintf(fp,"%d",num); 把num中的数,按照%d格式化,放到fp中 通过先给fp这个文件放内容,一直到为0是才终止读取 那么要是进行其他操作的话,就要使用回溯函数 rewind(fp); 使用scanf(fp,"%d",&num); 将fp里面的按照%d的形式,给到num 102.在math头文件里面有个ceil函数,可以进行对带小数点的数进行取整,取大于的数, 在顶部引入一个头文件#include<math.h> 在main里面直接使用就ok了,ceil( ); 103.转换成ASII码的形式 变成数字型的%03d 104.pow函数,使用时要引入math的头文件 pow(-1,i-1); 表示的就是-1的n-1次幂