C语言复习
存储类型:auto,register,static,extern
auto:默认使用,被auto修饰过的变量称为自动变量,只能修饰局部变量,存储在栈区;
extern:声明其他文件当中定义的变量。从外部引入一个全局变量或者函数
static:声明静态变量,存储在静态区;
(1)修饰局部变量:表示可以延长该局部变量的生命周期
(2)修饰全局变量或者函数:都表示隐藏,只能在本文件内使用
register:声明寄存器变量,只能修饰局部变量,存储在寄存器中;
总结:
(1)除了被static修饰的局部变量,其余均存储在栈区
(2)static修饰的变量包含两部分:静态全局和静态局部
注意:当被static修饰的变量没有被初始化时,其值为0.
运算符
算数运算符:+ - * / % ++ - -
int i = 10;
//i++;//11
//++i;//11
i++是先取i的值之后再自加;而++i则是先让i自加,再取其值。
例子:
#include <stdio.h>
int main()
{
int i = 3,j=0,k=0,m=0,n=0,t=0,l=0;
j = (i++)+(i++)+(i++);
printf("i=%d,j=%d\n",i,j);
i=3;
k = (++i)+(++i)+(++i);
printf("i=%d,k=%d\n",i,k);
i=3;
l = (++i)+(++i)+(i++);
printf("i=%d,l=%d\n",i,l);
i=3;
m = (i++)+(++i)+(++i);
printf("i=%d,m=%d\n",i,m);
i=3;
n=(i++)*(++i)*(++i);
printf("i=%d,n=%d\n",i,n);
i=3;
t=(++i)*(++i)*(i++);
printf("i=%d,t=%d\n",i,t);
return 0;
}
运行结果
i=6,j=12
i=6,k=16
i=6,l=15
i=6,m=14
i=6,n=90
i=6,t=125
#include <stdio.h>
int main()
{
int i=0;
printf("%d,%d,%d,%d\n",i++,--i,++i,i--);
return 0;
}
输出 -1, 0, 0, 0
从右往左运算即可
再看看数组 a[i]++ a[i++]
a[i]++:表示对当前数组元素值自增,此时可以把a[i]简单看做一个变量x,操作后,x的值加1;
a[i++]:表示指向下一个数组元素值;
#include <stdio.h>
int main()
{
int a[2];
int b[2] = {9, 5};
int i = 0;
a[i] = 6;
a[i]++;
b[i++];
printf("a[i] = %d\n", a[i]);
printf("b[i++] = %d\t i = %d\n", b[i], i);
return 0;
}
关系运算符:> < >= <= !=
逻辑运算符:&& || !
#include <stdio.h>
int main()
{
int x , y;
x = y = 1;
//++x||++y;
//printf("y = %d\n", y); //输出为1
--x|| y++;
printf("y = %d\n", y); //输出为2
return 0;
}
当执行 ++x || ++y 的时候
由于编译器的优化问题 当执行到++x 不为 0的时候 || 后面的 ++y
所以 y 还是 初始值 1
赋值运算符:= += -=
条件运算符(三目运算符):表达式1 ?表达式2 : 表达式3
位运算符:<< >> & | ~ ^
十进制转二进制:使用短除法将数字余数连起来即是二进制数
int i = 3;-->11 000011
int j = i <<3; -->011000 = 2^4 +2^3 =24
**注意:不可移出位数
二进制转十进制:哪一位有1就时2^(n-1),后将所有有1的位的数值相加**
&:对应位都为1,则为1;有一个为0,则为0;
int i = 3; 011
int j = 5; 101
int k = i & j; 001
|:对应位有一个为1则为1;俩个都为0则为0;
int i = 3; 011
int j = 5; 101
int k = i | j; 111
~:将0变1,1变0
^:对应位相同为0,不同为1
int i = 3; 011
int j = 5; 101
int k = i ^ j; 110
占位符:
%o —>打印八进制数据
%x —>打印十六进制数据(打印出的十六进制是小写字母)
%X —>会以大写的方式打印十六进制
%#o----> 打印时自动在八进制前面添加前导符0 —》(意味着#是一个前导符)
%#x / %#X
%d —>int
%hd —>short
%ld —>long (long int)
%lld —>long long (long long int)
%c ---->char
%f —>float
%lf —>double
%p —>打印地址
%s —> 打印字符串
%e —>以指数形式打印
%g ----> 会自动选择以最短的方式去打印数据
%Md ---->注意:M是域宽,代表所需要打印的数据所占的长度
%M.Nf —>M代表域宽(包含小数点在内),N代表小数点后的位数
数组
数组:一组有序且相同类型元素的集合
为什么需要数组?
只要大量数据不关心数组的时候
数组的特点:
(1)内存连续
(2)元素数据类型相同
对于数组的输入和输出要利用循环完成
如果数组是满初始化时,则打印数组数组会按照原样输出
如果数组部分初始化,则剩余未被赋值的元素会自动补0
如果想要去清空一个数组,则可以利用第三条:int arr[5] = {0}
一维数组中的元素个数可以被省略不写,当被省略时,则会根据后面所赋值的元素个数来决定到底省略的元素个数是谁.
#include<stdio.h>
//遍历数组函数
void arrayprint(int array[],int cnt){ //形式参数中,虽然写的是一个数组的样子,中括号中数组的大小是无效的!!
//无论中括号写多少,都不能代表形式参数数组多大。这里的中括号的作用仅仅用来表示,该参数是一个地址!!!
int i;
for(i = 0;i<cnt;i++){
printf("%d\n",array[i]);
}
}
int main(){
int datas[5] = {11,22,33,44};
arrayprint(datas,sizeof(datas) / sizeof(datas[0]));//参数 1.数组名 = 数组首地址 2.数组中元素个数
arrayprint(&datas,sizeof(datas) / sizeof(datas[0]));
return 0;
}
定义整型变量:
int a;
定义p为指向整型数据的指针变量:
int *pa;
定义整型数组 p,它由4个指向整型数据的指针元素组成;
int *pa[4]; //指针数组
p为指向包含4个元素的一维数组的指针变量:
int (*p)[4]; //数组指针
f为返回整型函数值的函数:
int f( );
p为返回一个指针的函数,该指针指向整型数据:
int *p( );
p为指向函数的指针,该函数返回一个整型值:
int (*p)( );
p是一个指针变量,它指向一个指向整型数据的指针
int **p;
p是一个指针变量,基类型为void(空类型),不指向具体的对象 :
void *p;
字符串
- 用双引号引起来的就是字符串,字符串由字符组成
- 字符串使用%s格式化输出
- 字符串以\0结尾,没有\0就不是字符串
- 只要是用双引号括起来的都是字符串
- 字符串的本质就是数组
注意: 字符串变量和普通的字符数组有一定的区别,C语言规定,字符串必须以\0结尾(作为字符串的结束符号),所以字符串变量的元素个数比字符数组的元素多一个\0
字符串初始化函数:memset();
char *pstr = NULL;
pstr=(char *)malloc(128);
//1.申请了空间
//2.一旦用了malloc就要注意内存泄漏的问题
//3.申请可能失败,要对返回值做判断
if(pstr == NULL){
printf("申请内存失败\n");
exit(-1);
}
memset(pstr , '\0' , 128);
查找子字符串函数 strchr();
**char strchr(const char str , int c);
参数说明:
1.*str //要被检索的字符串
2.int c //要在str中搜索的字符
功能:在参数str所指向的字符串中搜索第一次出现字符c(一个无符号字符)的位置。
返回值:返回一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回NULL空指针。
#include<stdio.h>
#include<string.h>
int main(){
char *str = "hello world";
char c= 'w';
char *p = NULL;
p = strchr(str ,c);
if(p == NULL){
printf("没有找到\n");
}else{
printf("找到了\n");
puts(p); //输出world
}
return 0;
}
查找子串函数 strstr();
**char *strstr(char str , char substr);
参数说明:
1.str为要检索的字符串。
2.substr为要检索的子串。
功能:用来检索子串在字符串首次出现的位置
返回值:返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回NULL。
字符串分割的函数: strtok();
**strtok(char str , char tokseps);
参数说明:
1.str //要进行分割的字符串。
2.tokseps //要分割的字符类型 (以什么来分割)
功能:用于将字符串进行分割。