1. 下方程序输出结果
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
short* p = (short*)arr;//shor*指针一次能访问两个字节。+1一次跳过两个字节
//0x 00 00 00 01 - 1的十六进制
//0x 00 00 00 02 - 2的十六进制
//0x 00 00 00 03 - 3的十六进制
//0x 00 00 00 04 - 4的十六进制
//0x 00 00 00 05 - 5的十六进制
//数据在内存中存放的时候,有一个顺序问题。大小端字节序。实际存放情况如下:
//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
//左边是低地址,右边是高地址
//因为int类型是四个字节,short*指针一次访问两个字节,
//所以下方循环4次,总共改了8个字节,即前两个整数
int i = 0;
for (i = 0; i < 4; i++)
{
*(p + i) = 0;
}
for (i = 0; i < 5; i++)
{
printf("%d", arr[i]);//0 0 3 4 5
}
return 0;
}
2. 下方程序输出结果
int main()
{
unsigned long pulArray[] = { 6,7,8,9,10 };
unsigned long* pulPtr;
pulPtr = pulArray;
*(pulPtr + 3) += 3;//下标为3的元素在加3
printf("%d, %d\n", *pulPtr, *(pulPtr + 3));//6 12
return 0;
}
3. 下方程序输出结果
同第一题一样,0x11223344在内存顺序是44332211。因为修改了第一个字节,所以修改了44为00
int main()
{
int a = 0x11223344;
char* pc = (char*)&a;
*pc = 0;
printf("%x\n", a);//0x11223300
//任何一个变量或表达式都有2个属性:值属性;类型属性
//int a = 3;
//a + 4.5 -> 7.5(值属性)
//类型属性:double
//a的值是3,类型属性是int。 &a的类型属性是int*,a的值属性就是地址
return 0;
}
4. 使用指针打印数组内容
void print(int* p, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));
}
printf("\n");
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr, sz);
return 0;
}
5. 将一个字符串str的内容颠倒过来,并输出。
#include <string.h>
int main()
{
char arr[10001] = {0};//加1是为了放下\0
//scanf("%s", &arr);//scanf遇到空格就不读取了
gets(arr);
int left = 0;//从下标0开始
int right = strlen(arr) - 1;
while (left < right)
{
char tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
printf("%s\n", arr);
return 0;
}
6. 计算求和
求Sn = a + aa + aaa + aaaa + aaaaa的前5项之和,
其中a是一个数字例如 : 2 + 22 + 222 + 2222 + 22222
//2
//2*10+2 = 22
//22*10+2 = 222
//222*10+2 = 2222
int main()
{
int a = 0;
int n = 0;
scanf("%d %d", &a, &n);
int sum = 0;
int k = 0;//每一项
int i = 0;
for (i = 0; i < n; i++)
{
k = k * 10 + a;
sum += k;
}
printf("%d\n", sum);
return 0;
}
7. 求出1 ~ 10009之间的所有“水仙花数”并输出。
水仙花数是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”。
非函数版本
#include <math.h>int main()
{
int i = 0;
for (i = 0; i <= 100000; i++)//判断i是否为水仙花数
{
//1234
//1234/10=123 1位
//123/10=12 2位
//12/10=1 3位
//1/10=0 4位
//1. 计算i是几位数 -> n
int n = 1;//任何一个数至少是一位数
//下方有一个问题,i不停除以10直到等于0,但是上方又是遍历i,i要++。所以矛盾了
//这里是典型的循环内部改变循环变量,所以需要一个临时变量来存放i,这样就可以不修改i变量
int tmp = i;
int sum = 0;//sum不能创建在循环外面,因为每一个i都要求和验证,所以每次都要从0开始
while (tmp / 10)
{
n++;//如果i/10不等于0,位数就加1
tmp /= 10;
}
//2. 得到i的每一位,计算他的n次方之和
//上方经过循环,每次tmp最后都等于0,所以再次把i放到临时变量中,得到i的每一位
tmp = i;
//1234%10=4
//1234/10=123
//123%10=3
//123/10=12
//通过上述方法得到每一位的数,直到tmp变成0说明所有位都取出
while (tmp)
{
sum += pow(tmp % 10, n);//得到每一位,在计算它的n(位数)次方;即某一位的位数的次方
tmp /= 10;//算完某一位的次方后,再去掉那一位
}
if (sum == i)//判断每一位 位数次方的和是否等于它本身
{
printf("%d ", i);
}
}
return 0;
}
函数版本
//函数版本
int is_narcissistic_number(int i)
{
int n = 1;
//1. 计算i是几位数 -> n
int tmp = i;
int sum = 0;
while (tmp / 10)
{
n++;
tmp /= 10;
}
//2. 得到i的每一位,计算他的n次方之和
tmp = i;
while (tmp)
{
sum += pow(tmp % 10, n);//得到每一位,在计算它的n(位数)次方;即某一位的位数的次方
tmp /= 10;//算完某一位的次方后,再去掉那一位
}
return sum == i;//等效下方,如果sum等于i,表达式为真,返回1;如果不等于表达式为假,返回0
//if (sum == i)//判断每一位 位数次方的和是否等于它本身
// return 1;
//else
// return 0;
}
int main()
{
int i = 0;
for (i = 0; i <= 100000; i++)//判断i是否为水仙花数
{
if (is_narcissistic_number(i))
{
printf("%d ", i);
}
}
return 0;
}
8. 打印菱形
思路:分上下两个部分(上半部到第7行,即最多那一行)。上半部空格在减少,星星在增多;下半部分空格增多,星星减少
int main()
{
int line = 0;
scanf("%d", &line);
//上 - 上半部分是line行
int i = 0;
for (i = 0; i < line; i++)//上半部分的打印
{
//上半部每一行的打印,分为空格和*
//空格的打印 - 随着行的增长,空格数量减少。假设有7行,第一行有6个空格,依次减少。第7行没空格
int j = 0;
//line-1表示只有6行有空格。随着行数增加1,空格减少1,所以减去行数
for (j = 0; j < line - 1 - i; j++)
{
printf(" ");
}
//*的打印 - *和行的关系是2*i+1就是每行*的数量,i第一次等于0
for (j = 0; j < 2 * i + 1; j++)
{
printf("*");
}
printf("\n");
}
//下 - 下半部分是line-1行,最终打印的行数是2*line-1行
for (i = 0; i < line - 1; i++)//下半部分的打印
{
//打印一行
//下半部空格打印 - 随着行数增长,空格数量增加,第几行就有几个空格
int j = 0;
for (j = 0; j <= i; j++)
{
printf(" ");
}
//*的打印 - *和行的关系是,假设有6行,第一行是2*6-1,第二行是2*5-1
for (j = 0; j < 2*(line-1-i)-1; j++)
{
printf("*");
}
printf("\n");
}
return 0;
}
9. 下面程序要求输出结构体中成员a的数据,以下不能填入横线处的内容是()
//A a.a
//B *p.a - 此为错误选项,p是结构体指针,不能用.操作符
//C p->a
//D (*p).a *p解引用找到了结构体变量a,和A选项一样
struct S
{
int a;
int b;
};
int main()
{
struct S a, *p = &a;//这里还有一个结构体指针变量struct S* p = &a;
a.a = 99;
printf("%d\n", ________);
return 0;
}
10. 下面程序输出结果
struct stu
{
int num;
char name[10];
int age;
};
void fun(struct stu* p)
{
printf("%s\n", (*p).name);
return;
}
int main()
{
//students是数组
struct stu students[3] = {
{9801, "zhang", 20},
{9802, "wang", 19},
{9803, "zhao", 18}
};
fun(students + 1);//这里的students数组名就是地址
return 0;
//结果是 wang
}
11. 喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。
思路:
1. 买了20瓶,有20个空瓶,换10瓶汽水
2. 10个空瓶再换5瓶汽水
3. 5个空瓶换2瓶汽水,还剩余1空瓶
4. 2瓶汽水喝完,总共有2+1(这个是上次剩下的)空瓶
5. 3个空瓶换了1瓶汽水,还剩1个空瓶,喝的加剩下的1个空瓶,总共有2个空瓶
6. 2个空瓶换1瓶汽水,此时只有1个瓶子,换不了,结束
int main()
{
//方法一
//三个变量
//钱money -> 输入的
//喝的总瓶数total,刚开始等于money
//空瓶empty,一开始也等于money
//接下来置换,条件是empty>=2
int money = 0;
scanf("%d", &money);
int total = money;
int empty = money;
//置换
while (empty >= 2)
{
//empty/2是置换到的汽水,置换到的喝了以后加到已经喝了的总数里
total += empty / 2;
//empty是喝完以后,当前手里的总空瓶数。
//empty/2既是能置换到的汽水,也是下次能获得的空瓶数。除去已经拿去置换的空瓶,还要加上手里不足以置换的空瓶数
empty = empty / 2 + empty % 2;
}
printf("%d\n", total);
//方法二
if (money > 0)
printf("%d\n", 2 * money - 1);
else
printf("%d\n", 0);
return 0;
}