C进阶 指针基础习题

重要习题:
第一组:

#include <stdio.h>
#include <stdlib.h>

int main(){
	
	int arr[] = { 1, 2, 3, 4 };
	printf("%d\n",sizeof (arr));// 16 计算一个整型数组所占的字节数
	printf("%d\n", sizeof (arr+0));//4 指针 int*
	printf("%d\n", sizeof (*arr)); //4 arr隐式转为指针,指向首元素的地址.在对其进行解引用得到一个int 
	printf("%d\n", sizeof (arr + 1));//4 数组名参与运算的时候,隐式转化为指针
	printf("%d\n", sizeof (arr[1]));// 4 int
	printf("%d\n", sizeof (&arr ));// 4 数组名取地址,成为数组指针int(*)[],只要是指针在32位操作系统下占4个字节

	printf("%d\n", sizeof (*&arr)); // 16 &arr数组指针,然后在对其进行解引用
	printf("%d\n", sizeof (&arr+1));//数组指针加1,仍然是数组指针
	printf("%d\n", sizeof (&arr[0] ));//4  得到一个int*
	printf("%d\n", sizeof (&arr[0]+1));// 4 int*
	
	system("pause");
	return 0;
}

** 第二组**

#include <stdio.h>
#include <stdlib.h>

int main(){
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };

	printf("%d\n", sizeof (arr));// 6 查看字符数组所占的字节数
	printf("%d\n", sizeof (arr+0));// 4 数组名参与运算会转化成指针,指针在32位操作系统下占4个字节
	printf("%d\n", sizeof (*arr));// 1 数组名不能取*,但是指针可以,arr隐式指向首元素的地址,在取*就是进行解引用得到一个字符a(char)
	printf("%d\n", sizeof (arr[1]));//1 指向一个字符b(char类型)
	printf("%d\n", sizeof (&arr));// 4 数组名取地址转化为数组指针,只要是指针在32位操作系统下占4个字节
	printf("%d\n", sizeof (&arr+1));//4 同上
	printf("%d\n", sizeof (&arr[0]+1));// 4 char* 
	
	system("pause");
	return 0;
}

第三组

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){

	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n",strlen(arr)); // 未定义行为 产生一个随机数,因为strlen函数是计算字符串的长度,遇到\0结束
	printf("%d\n", strlen(arr+0));//  未定义行为
	printf("%d\n", strlen(*arr)); // 数组名不能直接取*但是指针可以数组名转为 指针,然后在取*进行解引用得到一个char 类型
	//***char和chr*属于不同的类型:
	//char表示的是一个字符(通过一个整数来表示一个字符)大小是一个字节
	//char*表示的是一个指针变量,这个变量存储的是一个整数,这个整数对应到内存的一个地址.
	printf("%d\n", strlen(arr[1]));// 未定义行为 arr[1]指的是一个字符,与strlen()括号中所需要的类型不符合
	printf("%d\n", strlen(&arr));//对数组名取地址得到一个数组指针,char(*)[],由于没有\0的缘故因此无法计算出来结果
	printf("%d\n", strlen(&arr+1));//数组指针+1,仍然得到一个数组指针
	printf("%d\n", strlen(&arr[0]+1));//得到指向字符b的地址,但是根据这个地址找不到\0

	system("pause");
	return 0;
}

第四组

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
	char arr[] = "abcdef";
	printf("%d\n",sizeof(arr));// 7 计算时要加上\0,
	printf("%d\n", sizeof(arr+0));//4 char* 	数组隐式转为指针
	printf("%d\n", sizeof(*arr));// 1 对首元素的地址进行解引用 得到一个字符a
    printf("%d\n", sizeof(arr[1]));//1 字符b 同上
	printf("%d\n", sizeof(*(arr+1)));// 1 字符b  arr[1]=*(arr+1)
	printf("%d\n", sizeof(&arr));// 4 数组指针占4个字节char(*)[]
	printf("%d\n", sizeof(&arr+1));// 4 数组指针+1 仍然是一个数组指针
    printf("%d\n", sizeof(&arr[0]+1));// 4  char*

    printf("%d\n",strlen (*arr));// 未定义行为 char和char*不匹配
	printf("%d\n", strlen(arr[1]));//同上
	printf("%d\n", strlen(&arr));//&arr 属于char(*)[]类型和char*不是同一个类型
	printf("%d\n", strlen(&arr+1));// 跳过整个数组,访问数组后面的空间
	printf("%d\n", strlen(&arr[0]+1));// 5 指向b的地址,然后往后面数遇到\0就结束
	system("pause");
	return 0;

}

第五组

#include <stdio.h>
#include <stdlib.h>

int main(){

	char* p = "abcdef";
	printf("%d\n",sizeof(p)); // 4   p的类型为char* (指针在32位操作系统下占4个字节)
	printf("%d\n", sizeof(p+1));// 4  指针+1仍然是指针
	printf("%d\n", sizeof(p[1])); //1 对应的是字符b char占一个字节
	printf("%d\n", sizeof(*(p+1))); // 1 *(p+1)=p[1]
	printf("%d\n", sizeof(&p)); //4 二级指针仍然是指针
	printf("%d\n", sizeof(&p+1));//4 二级指针+1仍然是二级指针
	printf("%d\n", sizeof(&p[0]+1)); // 4 p[0]对应a,然后取&得到char*

	printf("%d\n",strlen(p));// 6 指向一个字符串
	printf("%d\n", strlen(p+1));//5 从p+1个元素往后找遇到\0就结束
	printf("%d\n", strlen(*p));// 未定义行为 解引用得到一个char 类型
	printf("%d\n", strlen(p[1]));// 未定义行为 得到一个字符b同上
	printf("%d\n", strlen(&p));// 未定义行为  得到一个char** 和char*不是一个类型
	printf("%d\n", strlen(&p+1));//未定义行为  得到一个char** 和char*不是一个类型
	printf("%d\n", strlen(&p[0] + 1));//5 得到一个指向b的char* 然后依次往后面找遇到\0结束

	system("pause");
	return 0;
}

第五组

#include <stdio.h>
#include <stdlib.h>

int main(){
	//长度为3个元素的一维数组,每一个元素又是长度为4的一维数组
	int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

	printf("%d\n",sizeof(a));//48 一共12个元素,每一个元素又占4个字节
	printf("%d\n", sizeof(a[0][0]));//4 int类型
	printf("%d\n", sizeof(a[0]));//16 代表第一行的4个元素,一个元素占4个字节,一共占16个字节int[4]
	printf("%d\n", sizeof(a[0]+1));//4 等于a[0]是第一行的数组名,数组名参与运算会隐式转为指针.指针在32位操作系统下占4个字节
	printf("%d\n", sizeof(*(a[0]+1)));//4  a[0]+1类型是int*,然后在解引用得到int
	printf("%d\n", sizeof(a[0][1]));//4 *(a[0]+1)=a[0][1] a[0]相当于第一行数组名
	printf("%d\n", sizeof(&a[0]+1));// 4 &a[0]+1 数组指针int(*)[4]
 	printf("%d\n", sizeof(*(&a[0] + 1)));//16 &a[0]+1 数组指针int(*)[4],然后在*进行解引用
	printf("%d\n", sizeof(*a));//16 *(a+0)=a[0]里面有4个元素,一共占16个字节in[4]
	//特别提示:
	//sizef()是一个运算符,特点是在编译期求值,
	//数组下标越界  属于未定义行为,前提条件是内存访问越界,这是在程序运行的时候,也就是说程序在编译期的时候已经识别出了int[4]
	printf("%d\n", sizeof(a[3]));// 16

	printf("%d\n", sizeof(a[100]));//16
	//但是这个就属于数组下标越界,属于典型的未定义行为
	printf("%d\n", a[100]);//数组下标越界,未定义行为
	system("pause");
	return 0;
}

重点提示:
sizeof ()是一个运算符(不是函数),特点是在编译期求值,
数组下标越界属于未定义行为,前提条件是内存访问越界,这是内存访问的行为.

#include <stdio.h>
#include <stdlib.h>

int main(){
	//长度为3个元素的一维数组,每一个元素又是长度为4的一维数组
	int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
		printf("%d\n", sizeof(a[3]));// 16
		//在编译期就直接变成了printf("%d\n",16);
			system("pause");
	return 0;
}

重点例题:
定义一个函数指针,指向的函数有两个int形参,并且返回一个函数指针,
返回的函数指针指向有一个int形参并且返回值int的函数,正确的是
int (* (*p)(int ,int) )(int)

函数的样子:

Ptr Func(int ,int)
函数指针的样子:

Ptr (*p)(int ,int)
把函数值返回展开:

int (* (*p)(int ,int) )(int)// 将(*p)(int ,int)看做一个整体

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值