- 1.sizeof二维数组
- 2.
- 3.
- 4.
- 5.
- 6.水仙花数
- 7.指针-指针(遗留?)
- 我直接上代码解读指针加减公式
- 8.字符'*'菱形打印
- 打印示意图:
- 代码
- 代码解读
- 9.
- 代码一:
- 代码二:
- 10.
- 题目
- 代码
- 错误
- 重制代码
- 错误
- 解决方案
- 正确代码
- 代码优化
- 优化代码中存在的问题
- 解决
main()
{
int a[3][4] = { 0 };
//a[0]单独放在sizeof内部,a[0]相当于作为第一行数组的数组名
//sizeof(arr[0])计算的是第一行的大小
printf("%dn", sizeof(a[0]));
//a[0]没有单独放在sizeof内部,a[0]表示二维数组第一行第一个元素的地址
//a[0]+1表示第一行第二个元素的地址
printf("%dn", sizeof(a[0] + 1));
printf("%dn", sizeof(a[0] + 1));
printf("%dn", sizeof(*(a[0] + 1)));//4-*(a[0]+1)是第一行第二个元素,大小是4个字节。
printf("%dn", sizeof(a + 1));//a是二维数组的数组名,没有sizeof(数组名),也没有&(数组名),所以a是首元素地址
//而二维数组的首元素就是它的第一行,a就是第一行(首元素)的地址
//a+1就是第二行的地址
printf("%dn", sizeof(&a[0] + 1));//第二行地址
printf("%dn", sizeof(a[3]));//16,sizeof后面()里的表达式不会计算
//a[3]是一个4个整形的一维数组,但实际并不存在
}
2.
main()
{
int a[5][5];
int(*p)[4] = a;
printf("%p %dn", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//a[4][2]表示*(*(a+4)+2)第五行第三个元素
//p[4][2]表示*(*(p+4)+2)第4行第4个元素,*(*(p)+0)表示第一行第一个元素
//%p ,-4打印的是-4补码的直接值
}
3.
main()
{
int aa[2][5] = {1,2,3,4,5,6,7,8,9,10};
int *a = (int*)(&aa + 1);
int *b = (int*)(*(aa + 1)); //*(aa + 1)= aa[1]-第二行首元素地址
printf("%d %dn",*(a-1),*(b-1));//10 5
}
4.
main()
{
char *p = "abcdef";//把字符串首字符a的地址放到p里面
char* a[] = { "work", "at", "alibaba" };
//元素类型为char*,a数组里面存放的都是字符指针
//所以a里面存放的是‘w’的地址,‘a’的地址和‘a’的地址
char** pa = a;
pa++;
printf("%sn", pa);//打印at
}
解读图:(或许不准确,会补充讲行指针和列指针)
main()
{
char*c[] = { "ENTER", "NEW", "POINT", "FIRST" };
char**cp[] = {c+3,c+2,c+1,c};
char***cpp = cp;
printf("%sn", **++cpp);//POINT
printf("%sn", *--*++cpp+3);//ER而且它把字符二级指针数组的内容改了
printf("%sn", *cpp[-2]+3);//ST
printf("%sn", cpp[-1][-1]+1);//EW
int i;
for (i = 0; i < 4; i++)
{
printf("%pn", cp[i]);
}
}
最后一个循环打印结果为(证明了在二级字符型指针数组里c+1变成了c)
解读:找出1·100000中数值等于各个位上的数字的几位数的平方的数。
疑难:有一个关键问题我没注意到:就是2的n次方不能写成2^n。
#include#include main() { int i; for (i = 0; i <= 100000; i++) { //定义一个变量j,得出它是一个几位数 int j = 1,h=i,f=i; while (f /= 10)//i的值变化 { j++; } //得出i各个位j次方之和,结果为w int x,w=0;//x是一个计数器, for (x = 0; x < j; x++) { w = w + pow(h % 10, j); h /= 10; } if (w == i) printf("%dn", i); } }
结果为:
指针-指针得到的是指针之间的字节个数说法是错误的.
指针-指针得到的是指针之间的元素个数。
指针的加减并不是直接的算术加减,而是一种特殊意义。苏明宇先生提出公式:p = p ±sizeof(*p)*n。
p是指针类型,n代表加减多少。
main()
{
char arr1[] = "abcde";
char* p1 = arr1;//字符型指针
printf("%pn", p1);
printf("%pn", p1+1);
printf("%pn", p1 + 2);
printf("n");
char(*p2)[5] = &arr1;//数组指针里的[]中的数字是不可省略的?
printf("%pn", p2);
printf("%pn", p2+1);
printf("%pn", p2+2);
printf("n");
char(*p3)[6] = &arr1;//数组指针里的[]中的数字是不可省略的?
printf("%pn", p3);
printf("%pn", p3 + 1);
printf("%pn", p3 + 2);
printf("n");
int arr2[2] = { 1, 2 };
int* p4 = arr2;
printf("%pn", p4);
printf("%pn", p4 + 1);
printf("%pn", p4 + 2);
printf("n");
int(*p5)[2] = &arr2;
printf("%pn", p5);
printf("%pn", p5 + 1);
printf("%pn", p5 + 2);
printf("n");
}
结果是:
int arr[2] = { 1, 2 };
int* p1 = &arr[0];
int* p2 = &arr[1];
printf("%dn", p2 - p1);
printf("%dn", &arr[1] - &arr[0]);
printf("%pn", &arr[0]);
printf("%pn", &arr[1]);
结果为:
#include代码解读main() { //上 //自己定义底有多少列 int max_num=26; for (;max_num%2==0;) { scanf("%d", &max_num); if (max_num % 2 == 0) printf("不符合图形规则,重新输入n"); } //定义一个变量row判断上要打印多少行 int row=(max_num-1)/2; int count, x;//定义一个计数器 for (count = 0; count < row;count++) { for (x = 0; x < (max_num - count * 2 - 1) / 2; x++) { printf(" "); } for (x = 0; x < count*2+1;x++) { printf("*"); } for (x = 0; x < (max_num - count * 2 - 1) / 2; x++) { printf(" "); } printf("n"); } //中 for (x = 0; x < max_num; x++) printf("*"); printf("n"); //下 for (count = 0; count < row; count++) { for (x = 0; x < count+ 1; x++) { printf(" "); } for (x = 0; x < max_num - (count+1)*2; x++)//关于这个条件区别于上是有一个底层逻辑的 { printf("*"); } for (x = 0; x < count+ 1; x++) { printf(" "); } printf("n"); } }
1.定义的max_num实际表示的是最大列数(行最多字符‘*’数量)
2.定义的row实际上是指上部分(下部分)的行数
3.我先完成的上面的代码,然后在完成下面的代码时复制粘贴时出现了条件紊乱这个问题,这里想详细说明一下。
上面代码的三个内循环条件
外循环是:for(count = 0; count < row;count++)//外循环只表示行数 for(x=0;x<(max_num-count*2-1)/2;x++) for(x=0;x在这里:(max_num-count2-1)/22+count*2-1恰好是最大列数max_num.
然后在写下代码的时候我认为对比上下的区别是冗余的,可直接根据我们定义的变量所代表的实际意义直接去写这个for条件。外循环是:for(count = 0; count < row;count++) 然后打印空格,那么空格是从1开始公差为1的一个等差数列 for(x=0;x<1+count;x++) for(x=0;x这里条件代数和为max_num。
9.题目:
代码一:
#include代码二:main() { //换过来的汽水 int sum = 0,money=20,bottle=0; //买过来的汽水 while (money > 0 || bottle > 1) { sum += money;//1块钱中的一个水 bottle += money;//一块钱中的一个瓶 money = bottle / 2;//两个瓶就是一块钱 bottle-=money*2;//从总数里去掉换钱所用的瓶子 } printf("%dn", sum); } #include10. 题目 代码main() { int sum = 20, bottle = 20;//初始阶段把钱都换成水和瓶 while ( bottle > 1) { int a = bottle / 2; //两个瓶子换一个水和瓶,a代表已有瓶子能换取的最大量 sum += a;//水算到sum里 if (bottle % 2 == 0)//瓶子算到bottle里 bottle = a; else bottle = 1 + a; } printf("%dn", sum); } void exchange(int arr[],int num) { int i; for (i = 0; i < num; i++) { if (arr[i] % 2 == 0) { int tmp = arr[i]; arr[i] = arr[5];//error arr[5] = tmp; } } } main() { int arr[5] = { 1, 2, 3, 4, 5 }; int num = sizeof(arr) / sizeof(arr[0]); exchange(arr, num); int i; for (i = 0; i < num; i++) printf("%d ",arr[i]); }错误1.下表不要写5,arr[5]越界访问。对于这个代码最大下标是num-1(也就是4)。原谅我晚上10点状态不佳。
重制代码
2.我后一天又发现了一个致命的逻辑性问题,交换前面的偶数与最后一个数字的位置的时候,有一个前提条件是最后一个数字一定要是奇数,但这个前提条件是无法总是满足的。由此,这个代码需要重制。void exchange(int arr[],int num) { int i, x = num - 1; //从下标为0开始一步一步排查 for (i = 0; i < num; i++) { //x>i证明下标i后面没有奇数了,也就不用交换了 while (x > i) { //找到数组前面的偶数元素的下标 if (arr[i] % 2 == 0) { //在后面(要满足x>i)并且是奇数(arr[x]%2==0) for (; arr[x] % 2 == 0&&x>i; x--); int tmp = arr[i]; arr[i] = arr[x]; arr[x] = tmp; } } } } main() { int arr[5] = { 1, 2, 3, 5, 4 }; int num = sizeof(arr) / sizeof(arr[0]); exchange(arr, num); int i; for (i = 0; i < num; i++) printf("%d ",arr[i]); }错误函数内循环进去了就出不来。(死循环)
解决方案1.(下策)在while内循环的最后加入break.
正确代码
2.(上策)把while改成if。
总结:设置一个循环条件,条件所包含的这些变量一定要在循环里面变化,否则条件的结果恒为1或者恒为0,条件判断失去意义。void exchange(int arr[],int num) { int i, x = num - 1; //从下标为0开始一步一步排查 for (i = 0; i < num; i++) { //x>i证明下标i后面没有奇数了,也就不用交换了 if (x > i) { //能进入这个if,就说明已经找到数组前面的偶数元素的下标 if (arr[i] % 2 == 0) { //在后面(要满足x>i)并且是奇数(arr[x]%2==0) //那么如果出循环 //要么是不满足arr[x]%2==0也就是说arr[x]%2==1,即找到后面的奇数下表x //要么就是不满足x>i(x=i)也就是说下标i后面元素全偶,如果出现这种情况这个数和它自己交换(等价于不交换) for (; arr[x] % 2 == 0&&x>i; x--); int tmp = arr[i]; arr[i] = arr[x]; arr[x] = tmp; } } } } main() { int arr[] = { 4, 6,8,1}; int num = sizeof(arr) / sizeof(arr[0]); exchange(arr, num); int i; for (i = 0; i < num; i++) printf("%d ",arr[i]); }代码优化exchange(int arr[],int num) { int left = 0; int right = num - 1; while (right > left) { for (; arr[left] % 2 == 1; left++);//在前面找偶数 for (; arr[right] % 2 == 0; right--);//在后面找奇数 if (right > left) { int tmp = arr[left]; arr[left] = arr[right]; arr[right] = tmp; } } } main() { int arr[5] = {1,3,5,7,9}; int num = sizeof(arr) / sizeof(arr[0]); exchange(arr, num); print1(arr,num); }优化代码中存在的问题面对一个特殊情况:数组中元素全奇数,那么会出现越界访问。
解决for (; arr[left] % 2 == 1; left++); for (; arr[right] % 2 == 0; right--); 改为 for (; arr[left] % 2 == 1&&right>left; left++); for (; arr[right] % 2 == 0&&right>left; right--);



