【C精进】从3个小例子看数组和指针

数组指针和偏移

先看第一段代码

int a[5] = {
     0, 1, 2, 3, 4};
printf("a:\t%p\n", a);
printf("&a:\t%p\n", &a);
printf("a+1:\t%p\n", a+1);
printf("&a+1:\t%p\n", &a+1);
  1. 打印数组名,也就是数组的标识符a,结果是0133FD80,表示数组的首地址
  2. 数组名前加上取地址符&,结果是0133FD80,也表示数组的首地址
  3. 打印数组名加1,结果是0133FD80,因为int占4字节,数组首地址加1并不代表地址值直接加1,而是地址偏移4个字节,指向数组下一个元素的首地址
    4.数组名取地址符&后加1,结果是0133FD94,增加了20,是数组内5个元素所占用空间的大小,说明先用&后表示整个数组的整体,再加1表示偏移整个数组那么大的地址空间

字符数组

再看第二段代码

char *cp;
char *cp1;
cp =(char *) malloc(strlen("hello") + 1);
if(NULL == cp)
{
     
	exit(1);
}
strcpy(cp, "hello");
cp1 = cp;
printf("%s\n", &cp[0]);
printf("%s\n", cp1);
free(cp);
  1. strlen()函数返回的是一个字符串的有效长度,而sizeof()函数返回的是一个字符串实际所占的空间大小,包括结尾的\0字符,所以在为一个字符指针分配地址时的大小需要加1
  2. 在使用strcpy()给一个字符指针空间赋值时,字符串大小不能超过之前开辟的空间,否则编译能通过,但运行时会出错
  3. 可以直接把一个字符指针赋值给另一个字符指针,这样两个指针指向同一块内存区域
  4. 使用字符指针、字符指针加&、字符指针加&加[0]就能打印出完整的字符串hello
  5. 使用malloc分配内存后要记得free,同时要判断分配不成功的情况1

作为函数参数的数组指针

再看第三段代码

void dealArr(int num, int* pArr)
{
     
	int i = 0;
	for(i = 0; i < num; i++)
	{
     
		*(pArr+i) = (*(pArr+i))++;
	}
}

int a[5] = {
     0, 1, 2, 3, 4};
int j = 0;
dealArr(5, a);
for(j = 0; j < 5; j++)
{
     
	printf("%d,", a[j]);
}
  1. 定义的函数参数类型是int*,表示指向整型数的指针
  2. 可以直接传入数组名a,也可以传入整个数组&a,但会提示实参与形参类型不兼容,因为&a的类型是int(*)[5],还可以传入a[0],编译会通过,但运行会出错
  3. 函数中传入指针可以改变地址指向的值,打印结果是1,2,3,4,5,

  1. 《C陷阱与缺陷》 ↩︎

你可能感兴趣的:(C语言,c语言)