C语言基础知识
1.指针与数组
-
数组名被看做该数组的第一个元素在内存中的首地址(仅在sizeof操作中除外,该操作中是要计算整个数组所占内存大小)
数组名在其他表达式中被自动转换为一个指向数组首元素的指针常量
C语言下标运算符[]是以指针作为操作数的,ar[i]被编译系统解释为*(ar+i),无论是以下标方式还是指针方式存取数组元素时,系统都是转换为指针的方法实现的,逻辑上是两种方式,物理上其实只有一种方式 -
数组名会转化为指针非常方便,提高了效率,但是丢失了数组另一个要素,就是数组的大小,即数组元素的数量。
数组名访问
int main()
{
int ar[5] = { 1,2,3,4,5 };
printf("0x%p\n", ar);//0x008FFA30 指向数组首元素地址
printf("0x%p\n",&ar[0]);//0x008FFA30 指向数组首元素地址
printf("0x%p \n",&ar);//0x008FFA30 指向数组首元素地址
printf("0x%p \n", ar+1);//0x00F1FD74 指向数组第二个元素地址
printf("%d \n", *ar);//1 对数组首元素解引用就是数组首元素本身
printf("%d \n",*ar+1);//2 数组第二个元素解引用
printf("%d \n", *(ar + 4));//5 数组第五个元素本身
printf("%d \n", ar[4]);//5 数组第五个元素
return 0;
}
指针访问
int main()
{
const int n = 5;
int ar[5] = { 1,2,3,4,5 };
int* p = ar;
for (int i = 0; i < n; ++i)
{
printf("0x%p %d %d\n",p+i,*p+i,p[i]);
}//i[ar]和ar[i]都可以打印数组元素
}
//打印p就是数组首元素地址,打印*p就是数组首元素本身
//结果
//0x00B5FB9C 1 1
//0x00B5FBA0 2 2
//0x00B5FBA4 3 3
//0x00B5FBA8 4 4
//0x00B5FBAC 5 5
int main()
{
const int n = 5;
int ar[n] = { 1,2,3,4,5 };
int* p = NULL;
for (p = &ar[0]; p < &ar[n]; ++p)
{
printf("0x%p %d\n",p,*p);
}
return 0;
}
//运行结果
//0x006FFAB0 1
//0x006FFAB4 2
//0x006FFAB8 3
//0x006FFABC 4
//0x006FFAC0 5
指针相减
- 两个同类型指针,指向连续的空间就可以相减,减后的结果就是:
(p1地址-p2地址)/sizeof(指针类型)
int main()
{
const int n = 5;
int ar[n] = { 1,2,3,4,5 };
int* pf = &ar[0];
int* pl = &ar[4];
int* pe = &ar[5];
printf("(pl - pf): %d\n",(pl - pf));//4
printf("(pe - pf): %d\n",(pe - pf));//5
return 0;
}
当且仅当两个同类型指针变量指向同一数组中的元素时,可以用关系运算符>,==,!=等进行比较,比较规则是指向后面元素的指针大,指向同一元素的指针相等