11、&和*
优先级都属于第二级,从右向左运算
12、*与++、--运算符
都属于第二级,从右向左计算
*p++ 等价于 *(p++)
*++p 等价于 *(++p)
13、[ ]和*
[ ]优先级高于*
13、二维数组的行地址和列地址
int a ={1,2,3,4};
则a为首地址,第一行首地址;*a和a[0]都是第一行第一个元素的地址
a+1为第二行行地址
*(a+1)为第二行第一个元素地址,a 也为第二行第一个元素地址
14、指向数组的指针变量(数组指针)
int *(p) ;表示一个指向含有4个int元素的数组的指针。
(1)p指向一维数组的首行地址
main()
{
int a ={1,2};
int (*p) ;
p=&a;//p是指向数组的指针,即行指针,因此要用&a给其赋值,&a为数组地址
printf("%d\n",**p);//取第一个元素,其中p为行地址,*p为元素地址,**p为元素值
printf("%d\n",*(*p+1));//取第二个元素
//也可以如下取值
printf("%d\n",(*p)[0]);//(*p)可以取代a
printf("%d\n",(*p) );
}
(2)p指向二维数组的首行地址
main()
{
int a ={1,2,3,4};
int (*p) ;
p=a;//p指向二维数组的首行地址
printf("%d\n",**p);//*p是元素的地址,**p则为元素内容
printf("%d\n",*(*(p+1)+1));
}
15、指针数组
int *p ;表示一个数组中含有4个int型指针。
char *p ;表示一个数组中含有4个char型数组,或则4个字符串
16、二维数组中的各个地址
int a ;
则a为首行地址,*a为首行第一个元素地址,**a为首行第一个元素的值
a+1为第二行地址,*(a+1)为第二行第一个元素的地址,**(a+1)为第二行第一个元素的值
*(a+1)与a 等价:都代表第二行第一个元素的地址
例子:
main()
{
int a ={1,2,3,4};
printf("a=%d\n",a);
printf("*a=%d\n",*a);
printf("**a=%d\n",**a);
printf("*a+1=%d\n",*a+1);
printf("a+1=%d\n",a+1);
printf("a =%d\n",a );
printf("a +1=%d\n",a +1);
printf("*a =%d\n",*a );
}
17、字符指针变量在接受输入字符串时,必须先开辟存储空间
char *cp;
scanf("%s",cp);
以上是错误的。
可以改为:
char cp[20];
scanf("%s",cp);
或者
char *cp,str[20];
cp=str;
scanf("%s",cp);
总之,一定要先开辟空间,再接受字符串
18、c和c++中的返回值不能是数组,java返回值可以是数组
19、指针函数和函数指针
指针函数:int * function();
函数指针:
int (*p) ();
int max(int a,int b);
p=max;
int a=(*p)(2,3);
20、关于变量的生命周期
函数中定义的局部变量是不能作为返回值的,因为函数结束后,局部变量就被回收了。
21、结构体
结构体中可以嵌套结构体,但不能是其本身。且成员结构体的定义必须在主结构体之前。
22、malloc
malloc函数位于stdlib.h中,函数原型为void * malloc(unsigned size);
eg: struct student *p=(struct student *)malloc(sizeof(struct student));
因为malloc返回的是一个void类型的指针,所以要强制转换。
23、free
该函数原型为
void free(void * ptr)
释放有指针ptr指向的动态分配的内存空间。为保证动态存储区的有效利用,当某个存储空间不再使用时,就应该及时释放它。
24、结构体和共用体
(1)结构体
结构体可以作为函数的参数和返回值。
结构体只有在初始化的时候才能直接用大括号{}形式赋值;当先声明,后赋值时候,就只能单个元素赋值,不能再用大括号形式了。这个跟数组的赋值类似。举例如下
struct student
{
int bh;
char *name;
};
struct student stu={1,'typ'};//是正确的
但是下面的是错误的
struct student stu;
stu={1,"typ"};//是错误的
此时这能stu.bh=1;stu.name="typ"