目录
一、关于运算符的总结(简单)
二、代码逻辑的区别
三、关于指针的运算
四、关于c99上面的数组指示器
五、指针数组数组指针的例题
六、关于数据声明代表的意思
七、关于进制数的典型例题
一、关于运算符的总结(简单)
例题:
int main() { int x = 2 , y, z; x *= (y = z = 5); printf("%d\n", x);//等于号在14级,自右像左结合,所以z=5,y=5,x=10; z = 3; //x=10,y=5,z=3; x == (y = z); printf("%d\n", x);//此时y=3,z=3,x=10;x的值不会变 x = (y == z); printf("%d\n", x);// 此时y=3,z=3,x=1;y和z相等为真,此时x的值变为了true,也就为1 x = (y & z); printf("%d\n", x);//此时x=3,y=3,z=3 x = (y && z); printf("%d\n", x);//此时x=1,y=3,z=3 y = 4; x = (y | z); printf("%d\n", x);//此时x=7,y=4,z=3 x = (y || z); printf("%d\n", x);//此时x=1,y=4,z=3 printf("%d\n", y); printf("%d\n", z); }
运行结果:
10 10 1 3 1 7 1 4 3 D:\c程序\p2-1\Debug\p2-1.exe (进程 7668)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
二、代码逻辑的区别
例题(查看两端代码的区别):
第一段代码、
int main() { int a, x; for (a = 0, x = 0; a <= 1 && !x++;a++) {//!和++的优先级相同,所以从右至左看结合方向,先算++,后算! a++; //a=0->1->2 x=0->1 } printf("%d%d\n", a, x);//a=2,x=1; }
运行结果:
21 D:\c程序\p2-1\Debug\p2-1.exe (进程 1844)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
第二段代码、
int main() { int a, x; //先进行后置++,但由于后置++是先用x的值在++,所以第一次执行代码时!x为真,然后x++为1 for (a = 0, x = 0; a <= 1 && !x++; ) { a++; //a=0->1 x=0->1->2 } printf("%d%d\n", a, x); //a=1,x=2; }
运行结果:
12 D:\c程序\p2-1\Debug\p2-1.exe (进程 7356)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
三、关于指针的运算
例题:
int main() { int arr[] = { 6,7,8,9,10 }; int* ptr = arr; *(ptr++) += 123; printf("%d,%d\n", *ptr, *(++ptr)); return 0; }
运行结果:
8,8 D:\c程序\p2-1\Debug\p2-1.exe (进程 5596)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
在这段代码的执行过程中,可能会疑惑为什么打印出来的值为8,我们将代码走一遍,首先ptr指向元素首地址,然后进行*(ptr++)+=123;在这个语句中,因为ptr++是后置++,所以ptr首先进行加等123,此时首元素的值变为129,然后ptr在像后移动一位,此时ptr指向位置的值变为7,但是结果为什么又会变成8呢,这和printf函数入栈出栈顺序有关,printf入栈是从右向左入栈,所以在输出*ptr, *(++ptr)的值的时候,*(++ptr)先入栈,*ptr在入栈。而*(++ptr)此时ptr先像后面移动一位之后,指向了元素8,入栈之后,*ptr在入栈,此时*ptr所解引用的值就为8。最后再出栈,出栈首先*ptr先出栈,然后*(++ptr)在出栈。下面我们将这段话的意思用画图来看一下:
为了更加了解函数的出栈入栈,我们观察一下它们的地址,代码如下:
void Stack_test(int a, int b, int c) { printf("a=%d,&a=%x\n", a, &a); printf("b=%d,&b=%x\n", b, &b); printf("c=%d,&c=%x\n", c, &c); } int main() { int a = 1, b = 2, c = 3; Stack_test(a, b, c); }
结果如下:
a=1,&a=affb54 b=2,&b=affb58 c=3,&c=affb5c D:\c程序\p2-1\Debug\p2-1.exe (进程 17388)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
我们知道栈是从高地址像低地址进行开辟,所以看他们的地址我们可以知道是c先入的栈。
四、关于c99上面的数组指示器
#include<stdio.h> int main() {// 数组指示器只有在.c文件中才可以使用 int arr[10] = { 0,0,2,0,0,5,0,0,8,0 }; int brr[10] = { [2] = 2,[5] = 5,[8] = 8 };//剩余没有赋值的默认为0 int err[] = { [2] = 2,[5] = 5,[8] = 8 }; // 数组指示器的最大值就是数组的长度 int hrr[10] = { 1,2,3,[4] = 4,6,[8] = 8 }; //输出结果为1,2,3,0,4,6,0,0,8,0,这里的6存放在5号下标处 int lrr[] = { 5,1,9,[0] = 1,3,7,[2 * 7] = 6,7,8,[2] = 3 }; //这时数组长度为17,因为最大下标14的后面还跟了7,8,所以这两个数放在15号和16号下标 for (int i = 0; i < sizeof(lrr) / sizeof(lrr[0]); i++) { //打印出lrr printf("%d", lrr[i]); } }
运行结果:
13300000000000678 D:\c程序\p2-1\Debug\p2-1.exe (进程 16040)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
关于lrr的流程:
519->13700000000000678->13300000000000678
五、指针数组数组指针的例题
求下面数组的大小:
int main() { int arr[3]; //3*4=12 int *a[3]; //指针数组 3*4=12,落脚点在数组,表示存放指针的数组 int** aa[3][4]; //3*4*4=48 int*** aaa[3][4][5]; //3*4*5*4=240 int(*brr)[4]; //数组指针 4,落脚点在指针,指针指向这个数组 printf("%d\n",sizeof(arr)); printf("%d\n",sizeof(a)); printf("%d\n",sizeof(aa)); printf("%d\n",sizeof(aaa)); printf("%d\n",sizeof(brr)); }
运行结果:
12 12 48 240 4 D:\c程序\p2-1\Debug\p2-1.exe (进程 15024)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
六、关于数据声明代表的意思
1.下面数据声明分别代表什么意思?
float (**def)[10]; //def是一个二级指针,指向一个一维数组的指针,数组元素都是float
double *(*gh)[10]; //gh是一个一级指针,指向一个一维数组,这个数组的元素都是double*
double (*f[10])();//f是数组,有10个元素,每一个元素都是函数指针,指向的函数类型都是没 //有参数且返回值是double的函数
int *((*b)[10]); //b是一个一级指针,指向一个一维数组,且数组中元素都是int*
int (*fun)(int); //fun是一个函数指针,指向的函数只有一个int型参数且返回值也是int的函数
int (*(*F)(int,int))(int) //F是一个函数指针,这个函数指针是有两个int型的参数,
//且返回值类型还是函数指针,这个返回值的函数指针指向有一个int参数且返回int的返回值
2.补充说明:
函数指针的应用:
int Max(int a, int b) { return a > b ? a : b; } int main() { int a = 20; int b = 10; int(*p)(int, int) = Max;//函数指针,也可以写成 &Max int res=p(a, b); printf("%d", res); }
运行结果:
20 D:\c程序\p2-1\Debug\p2-1.exe (进程 7124)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
七、关于进制数的典型例题
1.13*16=244 在几进制下为真
//在7进制下为真,我们验证一下,在7进制下,13为7+3=10,16为7+6*7^0=13,244为2*7^2+4*7^1+4*7^0=130,最后变为:10*13=130;
2.15*5=101 在几进制下为真
//同理:15在8进制下为13,5在8进制下为5,101在8进制下为65,最后:13*5=65;成立