C语言常见问题
指针与数组
放一个最近改的代码。
代码中的output函数还是以前错的,input函数是改后的。
知识点很多,总结的可能不到位。如有错误,欢迎留言。
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct student
{
char name[20];
int number;
char sex[20];
float score;
int age;
} student;
void input(student *stu);
void output(student *stu);
int main()
{
student stu[N];
printf("please input five students' information you need:\n\n");
input(stu);
printf("That you input the five students' information is:\n\n");
// output(stu);
system("pause");
return 0;
}
void input(student *stu)
{
for (int i = 0; i < N; i++)
{
//这是第一种,数组的方式,理解上容易。
//scanf("%s %d %s %d %f", stu[i].name, &(stu[i].age), stu[i].sex, &(stu[i].number), &(stu[i].score));
//指针的方式
scanf("%s %d %s %d %f", (stu + i)->name, &((*(stu + i)).age), stu[i].sex, &(stu[i].number), &(stu[i].score));
//当i = 2, stu是student结构体数组的首地址,(stu + 2)就是stu[2]的首地址;根据后面的知识点5,(stu + 2)->name就是字符数组name的首地址,类型char *的数组,这里作右值。
//(*(stu + 2))就相当于 stu[2]
}
}
// void output(student *stu)
// {
// for (int i = 0; i < N; i++)
// {
// printf("%s%d%%s%d%f", stu[i]->name, stu[i]->age, stu[i]->sex, stu[i]->number, stu[i]->score);
// }
// }
知识点:
1、指针 既有值、又有类型;
比如
int *num 类型是int *
char *str 类型是char *
不容易理解的在二维数组的类型(验证过)
可能有一点错,(我后来看到,现在想不起来了)
1、数组名做右值会自动转换为 指向数组 首元素 的指针。
2、 数组名作右值时,会转换成指针,(姑且用void *表示)
1)当数组是一维的时候,int arr[10]
这个时候数组名作右值,数组名转换成-数组的首地址,
指针的类型是 int *
此时void *parr = arr;可以
如果这个时候 &arr, 类型为int(*)[10]
> 2)当数组是2维的时候,int arr[4][5]
这个时候数组名作右值,数组名也是转换成-数组的首地址
但是这个时候类型不是int *了,而是指向数组的指针,
也就是int (*p)[5];
此时void * parr = arr;警告
initialization from incompatible pointer type。
> 其实也就是这个问题 指针类型不同
int arr[10]; 一维
数值 类型
arr做右值 数组arr的首地址 int *
&arr[0] 数组arr首元素的首地址 int (*)[10] //指向数组指针
&arr 数组arr的首地址 int (*)[10]
都相同
> int arr[2][3]; 二维
数值 类型
arr做右值 数组arr的首地址 int (*)[3]
&arr[0] 数组arr首元素的首地址 int (*)[3] //指向数组指针
&arr 数组arr的首地址 int (*)[2][3]
都相同
>也就是说 int a[2][3]
int (*pa) [3] = &a[0];
int arr[2][3] = {0};
int (*p)[2][3] = &arr;//取二维数组的地址。
int (*p)[2][3] = arr;//这个是一维的。警告!!!
int *pp = arr; 警告 是a[0]的地址。
int (*ppp)[3] = arr;
2、结构体的 " . "和“ -> ”
这两个一个是结构体变量的指针用的,一个是结构体变量用的。
3、指针与数组。
int a[10];
int *p = a;
1、a[2]之所以能取到数组的第三个元素,就是因为它等价于 *(a + 2)
4、scanf函数, 后面需要指针,name是结构体里面的数组,做右值自动转化为首地址指针;age是int类型,作右值不会转换为指针。
5、运算符的优先级。
()> 结构体取成员" . " / 指向结构体的指针取成员 “ -> ” / 数组下标[] >
取地址、指针间接寻址。
问题?
1、为什么数组从0开始?
2、
int a[10];
int *p = a;
p++是什么意思?
3、数组下标负数什么意思?