指针相关的一些题目

253 阅读3分钟

指针

#include <stdio.h>
#define SIZE 4

int main(void)
{     
	short dates[SIZE];     
	short * pti;     
	short index;  

	double bills[SIZE];     
	double * ptf;     
	pti = dates;    // 把数组地址赋给指针     
	ptf = bills;     

	printf("SIZEOF short %d ", sizeof(short));
	printf("SIZEOF double %d\n", sizeof(double));

	printf("%23s %15s\n", "short", "double");     
	for (index = 0; index < SIZE; index++)          
		printf("pointers + %d: %10p %10p\n", index, pti + index, ptf + index);     
	return 0;
}
SIZEOF short 2 SIZEOF double 8
                  short          double
pointers + 0: 000000B6F28FFB28 000000B6F28FFB88
pointers + 1: 000000B6F28FFB2A 000000B6F28FFB90
pointers + 2: 000000B6F28FFB2C 000000B6F28FFB98
pointers + 3: 000000B6F28FFB2E 000000B6F28FFBA0

short:2个字节大小,double为8个字节大小。 从输出结果可以看出指针加一 是递增它指向类型的大小

000000B6F28FFB28 + 2bytes =000000B6F28FFB2A 【A:10】

000000B6F28FFB88+ 8bytes=000000B6F28FFB90 【十六进制 逢16进位】


指针相关的练习题目 (目的掌握 指针所指向的对象和*解引用)

解引用:

一个指针(在指针前使用 *运算符)或在数组名后使用带下标的 []运算符,得到引用对象代表的值。

问题1:下面程序输出的内容

#include <stdio.h>
int main(void)
{
    int ref[] = { 8, 4, 0, 2 };     
    int *ptr; //指针变量    
    int index;    
    // ptr = ref  ref:首元素地址 -- 8的地址
    for (index = 0, ptr = ref; index < 4; index++, ptr++)          
        printf("%d %d\n", ref[index], *ptr); // *ptr 解引用: *ptr得到引用对象代表的值    
    return 0;
}

问题2: ptr和(ptr + 2)的值分别是什么?

#include <stdio.h>
int main(void)
{
    int* ptr; //指针变量
    int torf[2][2] = { 12, 14, 16 }; //torf 首元素({12,14})的地址
    ptr = torf[0];//首元素的第一个元素12的地址
    
    //*ptr和*(ptr + 2)的值分别是什么?
    //*ptr解引用 -- 12 
    //*(ptr + 2)//第三个元素 解引用 16

    printf("%d %d\n", *ptr, *(ptr + 2)); //12 16   
    return 0;
}

*(ptr + 2) 输出为16? 初始化的时候,里面的花括号可以省略。个数按照第二个方括号数字依次分割。

int torf[2][2] = { 12, 14, 16 } 类似于 int torf[2][2] = { {12, 14}, {16} }

#include <stdio.h>
int main(void)
{
    
    int* ptr; 
    int fort[2][2] = { {12}, {14,16} }; //fort首元素({12})的地址
    ptr = fort[0];//首元素的第一个元素12的地址

     //*ptr和*(ptr + 2)的值分别是什么?
    //*ptr解引用 -- 12 
    //*(ptr + 2)//第三个元素 解引用 14 ? 
    printf("%d %d\n", *ptr, *(ptr + 2)); //12 14
    return 0;
}

*(ptr + 2) 为什么是14?

分析:

fort[2][2] :代表两行,没行有两个元素。虽然 int fort[2][2] = { {12}, {14,16} } 第一个行{12}里面只有一个元素12,但是还是占据的是两个int空间。


问题3: ptr和(ptr + 1)的值分别是什么? 这是些双重解引用的题目

#include <stdio.h>
int main(void)
{
    
    int(*ptr)[2];//二维数组指针
    int torf[2][2] = { 12, 14, 16 };// {{12,14},{16}}
    ptr = torf;//torf 首元素{12,14}的地址

    printf("**ptr %d,**(ptr+1) %d", **ptr, **(ptr + 1));

    return 0;
}

分析:

*ptr 是个二维数组指针 ,torf数组名代表首元素的地址{12,14}

分析解引用

第一层*ptr首元素第一个元素12的地址

第二层 **ptr首元素第一个元素12的地址 的内容 :12

**(ptr + 1) 先分析小括号内,ptr+1我们知道ptr代表首元素的地址,加1,增加大小为指向对象的字节大小,int(*ptr)[2]为两个int类型的字节大小为8个字节,即为就是第二个元素{16}。

分析解引用

第一层*(ptr+1)第二个元素的第一个元素地址;

第二层 **(ptr+1)第二个元素的第一个元素内容 -- 16;

int (*ptr)[2];
int fort[2][2] = { {12}, {14,16} };
ptr = fort;

同理分析,结果为12 和 14;

问题3:

假设有下面的声明:int grid[30][100];  
a.用1种写法表示grid[22][56]的地址 &grid[22][56]
b.用2种写法表示grid[22][0] 的地址 &grid[22][0]  *(grid+22)  
c.用3种写法表示grid[0][0] 的地址  &grid[0][0]   (int *)grid  &grid[0]

问题4:

正确声明以下各变量:  
a.digits是一个内含10个int类型值的数组 int digits[10] 
b.rates是一个内含6float类型值的数组  float rates[6] 
c.mat是一个内含3个元素的数组,每个元素都是内含5个整数的数组 int mat[3][5] 
d.psa是一个内含20个元素的数组,每个元素都是指向char的指针  char * psa[20]
e.pstr是一个指向数组的指针,该数组内含20个char类型的值     char (*pstr)[20]