语法总结
1. 指针
表达式 | 含义 |
---|---|
&cp | 取变量cp的存储地址 |
*cp | 指向cp所指向的值 |
*cp+1 | cp指向的值+1 |
*(cp+1) | cp移动一个存储单元,然后取值 |
++cp=(++cp) | 先++,再取值 |
cp++=(cp++) | 先取值,再++ |
2. 数组
- 指针和数组
/***********************************/
int i[]={100,200,300,400,500};
int *pi=i; //pi指向i[0]=100的首地址
/**********************************/
*pi++=*(pi++); //输出*pi,然后pi++
*++pi=*(++pi);//pi++,然后输出*pi++*pi; //300+1
/**********************************/
//等价array[i]=*(array+i);
&array[i]=array+i=array[0]+i;
二维数组
( [ ]和*是等价的 )
//一维数组 int i[7]={0,1,2,3,4,5,6}; int *pt=i; *(i+2)=i[2]=*(pt+2)=pt[2]; //二维数组int j[2][3] = {01,2,3,4,5}; int j[1][2]=*(*(j+1)+2); j+1=*(j+1)=j[1]; //下一个一维数组的首地址 *(j+1)+5 ;//一维数组的第5个元素
指向数组的指针
ppint (*p)[10];
指针数组
char* parr[4]={"dee","iss","mah"}; **par=*par[]=par[][]
3. 字符串
字符串和指针
字符串以 “\0” 结尾
数组以NULL结尾
字符串的拷贝和比较使用 strcpy 和 strnpy,“=”赋值的是字符串指针
cchar \*str1="Apple iPOD";
CHAR str2\[11\]="Apple ipod";
字符串的修改(字符串和数组)
int main()
{ char str[]="JulyEdu";
str[4]='a';
str[5]='p';
str[6]='p';
printf("%s\n",str);
return 0;
}
//输出julyApp
int main()
{
char* str="julyEdu"; //修改为,str指向的是字符串常量
//const char* str="jultEdu";
str[4]='a';
cout<<str<<endl;
return 0;
}
//输出错误
//加const
/**********************/
//修改
int main()
{
char* str=new char[100];
strcpy(str,"julyEdu");
cout<<str<<endl;
str[4]='a';
cout<<str<<endl;
}
/***********************/
char s[]="atudent";
char *a=s;
*a = 's';
4 函数
函数传参
- 值传递
void swap(int p, int q){
int tmp;
temp=p;
p=q;
q=temp;
}
swap(a,b);
- 指针传递
void swap(int *p, int *q)
{
int *tmp;
temp=p;
p=q;
q=temp;
}
swap(&a,&b);
- 引用传递
void swap(int &p, int &q)
{
int tmp;
temp=p;
p=q;
q=temp;
}
swap(a,b);
函数的数组参数
int f(char* string)
int f(char string[])
函数指针
int *pf(int); //返回值是int*
int (*pf)(int); //pf是指向函数的指针,返回值值是int
//函数指针数组
void (*fun[256])
(void) f[0]=function0
f[1]=function1
递归函数
初始化: 变量入栈
满足条件
输出: 销毁堆栈的值,出栈
-参考 c和指针 P130
5. 结构体
声明
struct{
int a;
int b;
float c;
}x,y[20],z;
//标签
struct simple{
int a;
char b;
float c;
};
struct simple x, y[20],*z;
//typede
typedef struct{
int a;
int b;
float c;
}simple;
simple x,y[20],*z;
成员的访问
struct complex{
int a;
int b;
float c;
};
strcut complex comp;
//直接访问
comp.sa[];
//间接访问
comp->f;
自引用
struct s1{
int a;
strcut s1 b; //错误
struct s1 *b; //正确
int c;
};
6. 位运算
- 原操作码:s;掩码:mask
或,与,异或
&(与)AND | 0 | 1 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
清零特定位置 | mask特定位设置为0,其他为1 | s=s&mask |
取某数的某个值 | mask特定位设置为1,其他为0 | s=s&mask |
|(或)OR | 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 1 |
将s中某些位置为1 | mask特定位设置为1,其他为0 | s=s|mask |
^(异或) | 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 0 |
使s的特定位取反 | mask特定位设置为1,其他为0 | s=s^mask |
1111010^00001111=011110101 | NULL | NULL |
和0^ | 保留原值 | 00001010^000000000=00001010 |
交换3和4 | NULL | NULL |
a=3,b=4;
a=a^b;//a=011^b=100=>a=111(a=7)
b=b^a;//b=100^a=111=>b=011(b=3)
a=a^b;//a=111^b=011=>a=100(a=4)
移位操作
算术左移和算术右移主要用来进行有符号数的倍增、减半;
逻辑左移和逻辑右移主要用来进行无符号数的倍增、减半。
(1) 左移
00001010<<2 = 00101000
(2)右移
00001010>>2 = 00000010; //逻辑右移(无符号)
10001010>>3 = 11110001; //算术右移 (有符号)
补齐
不同长度的数据,位运算,需要补齐
如果正数:左端补0
如果负数:左端补1
7.异常
assert:捕捉程序员自己的错误。永远不应该发生
异常:捕获用户或者环境的错误。捕捉预期会发生
assert(string!=NULL); //不可以是空
assert(*string!='\0');//不可以是空
assert(strlen(string)>2); //长度超过2
//安全监测
assert((dst!=NULL) && (src!=NULL))