入门后指针进阶习题深度分析

简介: 入门后指针进阶习题深度分析

1.sizeof()  整形数组


#include<stdio.h>
int main()
{
  //整形数组
  int a[] = { 1,2,3,4 };    //注意:数组名在 1.sizeof(数组名) 2.&数组名 这两种情况时表示整个数组
  printf("%d\n", sizeof(a));   //sizeof(数组名) 这里为整个数组 一共4个元素 每个类型为int  4*4=16
  printf("%d\n", sizeof(a+0));//不是特殊情况 表示首元素地址 是地址(指针)   就是4/8
  printf("%d\n", sizeof(*a));//对首元素地址解引用得到的还是首元素 一个int大小 4
  printf("%d\n", sizeof(a+1));//首地址+1 变成第二个元素的地址  指针是存放地址的 所以是地址大小就为 4/8 
  printf("%d\n", sizeof(a[1]));//a[1]实际上是 *(a+1) 对第二个地址解引用 得到第二个元素为 int 4
  printf("%d\n", sizeof(&a));//&a 表示拿到整个数组的地址 但实际还是个(地址)指针 大小为4/8(x64)
  printf("%d\n", sizeof(*&a));//&a 拿到整个数组的地址 再解引用得到整个数组 为 4*int  16
  printf("%d\n", sizeof(&a+1));//先&a得到整个元素的地址 再+1 跳过一个数组的大小 得到其地址 4/8
  printf("%d\n", sizeof(&a[0]));//&a[0]等价于 &*(a+0) 实际上第一个元素的地址 4/8
  printf("%d\n", sizeof(&a[0]+1));//同理 先得到第一个元素的地止再+1 为第二个元素地址 4/8
  return 0;
}

2.sizeof()  字符数组


#include<stdio.h>
int main()
{
  //字符数组
  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", sizeof(arr));  //整个数组 6*char  6
  printf("%d\n", sizeof(arr+0));//首元素地址 4/8
  printf("%d\n", sizeof(*arr)); //首元素  1
  printf("%d\n", sizeof(arr[1]));// *(arr+1) 1
  printf("%d\n", sizeof(&arr));  //整个数组地址 4/8
  printf("%d\n", sizeof(&arr+1)); //跳过整个元素指向后面的地址 4/8
  printf("%d\n", sizeof(&arr[0]+1));//跳过首元素 第二个元素地址 4/8
  return 0;
}

3.streng()  字符数组


#include<stdio.h>
#include<string.h>
int main()
{
  //字符数组
  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", strlen(arr));  //首元素地址给出 往后找\0 可是没有 随机值
  printf("%d\n", strlen(arr+0));//同上 随机值
  //printf("%d\n", strlen(*arr)); //解引用 首地址拿到 a的阿斯克码值 97 strlen当做地址访问 err
  //printf("%d\n", strlen(arr[1]));// *(arr+1) 拿到b的阿斯克码值98  当地址访问 err
  printf("%d\n", strlen(&arr));  //整个数组地址 传到strlen中强转成char*   随机值
  printf("%d\n", strlen(&arr+1)); //跳过整个元素指向后面的地址 随机值-6
  printf("%d\n", strlen(&arr[0]+1));//跳过首元素 第二个元素的地址 随机值-1
  return 0;
}

4.sizeof()  字符串


#include<stdio.h>
#include<string.h>
int main()
{
  char arr[] = "abcdef";  //arr里放的其实是 a b c d e f \0
  printf("%d\n", sizeof(arr));  //整个数组 7*char  7
  printf("%d\n", sizeof(arr+0));//首元素地址  4/8
  printf("%d\n", sizeof(*arr)); //解引用 首地址 1
  printf("%d\n", sizeof(arr[1]));// *(arr+1) 第二个元素 1
  printf("%d\n", sizeof(&arr));  //4/8
  printf("%d\n", sizeof(&arr+1)); //跳过整个数组指向后面的地址 4/8
  printf("%d\n", sizeof(&arr[0]+1));//跳过首元素 第二个元素的地址 4/8
  return 0;
}

5.strlen()  字符串


#include<stdio.h>
#include<string.h>
int main()
{
  char arr[] = "abcdef";  //arr里放的其实是 a b c d e f \0
  printf("%d\n", strlen(arr));  //首元素地址  6
  printf("%d\n", strlen(arr+0));//首元素地址  6
  //printf("%d\n", strlen(*arr)); //解引用 首地址 a-97 err 
  //printf("%d\n", strlen(arr[1]));// *(arr+1) 第二个元素 b-98 err
  printf("%d\n", strlen(&arr));  //整个数组地址 相对于strlen相当于首元素地址 6
  printf("%d\n", strlen(&arr+1)); //跳过整个数组指向后面的地址 后面无\0  随机值
  printf("%d\n", strlen(&arr[0]+1));//跳过首元素 第二个元素的地址 5
  return 0;
}

6.sizeof() *p 字符串


#include<stdio.h>
#include<string.h>
int main()
{
  char *p = "abcdef";  // p 存放的是a的地址
  printf("%d\n", sizeof(p));  //首元素地址  4/8
  printf("%d\n", sizeof(p+1));//首元素地址+1 第二个元素b地址 4/8
  printf("%d\n", sizeof(*p)); //解引用 首地址 得到第一个元素 1 
  printf("%d\n", sizeof(p[0]));// *(arr+0) 首元素  1
  printf("%d\n", sizeof(&p));  //指针变量p的地址(二级指针) 4/8
  printf("%d\n", sizeof(&p+1)); //指针变量p地址之后的地址 4/8
  printf("%d\n", sizeof(&p[0]+1));// &*(p+0)+1 跳过首元素地址 第二个元素的地址 4/8
  return 0;
}

6.strlen() *p 字符串

int main()
{
  char *p = "abcdef";  // p 存放的是a的地址
  printf("%d\n", strlen(p));  //首元素地址  6
  printf("%d\n", strlen(p+1));//首元素地址+1 第二个元素b地址 5
  //printf("%d\n", strlen(*p)); //解引用 首地址 得到第一个元素 err 
  //printf("%d\n", strlen(p[0]));// *(arr+0) 首元素  err
  printf("%d\n", strlen(&p));  //指针变量p的地址(二级指针) \0 未知 随机值  
  printf("%d\n", strlen(&p+1)); //指针变量p地址之后的地址 随机值
  printf("%d\n", strlen(&p[0]+1));// &*(p+0)+1 跳过首元素地址 第二个元素的地址 5
  return 0;
}

7.二维数组

int main()
{
  int a[3][4] = { 0 };     //二维数组可以看成 3个一维数组 每个数组4个元素
  printf("%d\n", sizeof(a));   //sizeof(数组名)为整个数组 12*4=48
  printf("%d\n", sizeof(a[0][0]));//首元素 4
  printf("%d\n", sizeof(a[0]));  //二维数组可以看做一维数组  a[0]可看做第一行数组名 单独放在sizeof内 计算第一行元素大小 16
  printf("%d\n", sizeof(a[0]+1)); //数组名不是单独放的 第一行首元素地址+1 为第二个元素地址 4/8
  printf("%d\n", sizeof(*(a[0]+1)));//第一行第二个元素地址 解引用 4
  printf("%d\n", sizeof(a+1));      //不是单独放 a为第一行的地址 +1 第二行的地址 4/8
  printf("%d\n", sizeof(*(a+1)));   //对第二行的地址解引用  16
  printf("%d\n", sizeof(&a[0]+1));  //&数组名 为整个第一行数组地址 +1 第二行数组地址 4/8
  printf("%d\n", sizeof(*(&a[0]+1)));//第二行元素 16
  printf("%d\n", sizeof(*a));     //a不是单独放 为第一行地址 解引用 16
  printf("%d\n", sizeof(a[3]));   // sizeof根据类型算出 不会真正去访问 第四行和前几行一样 int [4]  16
  return 0;
}

总结:

数组名通常情况下是首地址。 二维数组的首地址是第一行的地址。


但有两个例外。1.sizeof(数组名)  2.&数组名 是表示整个数组的。


sizeof是操作符 用来计算其所占内存空间的大小 不会真实访问内存 只要知道类型就可以。


strlen是函数  用来计算字符串长度的函数 只能针对字符串 他会从你给的地址向后访问找\0 找到才停止。


目录
相关文章
|
5月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
1月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
22 2
|
5月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
3月前
|
存储 安全 编译器
C++入门 | auto关键字、范围for、指针空值nullptr
C++入门 | auto关键字、范围for、指针空值nullptr
62 4
|
3月前
|
Go 计算机视觉
Go从入门到放弃之指针
Go从入门到放弃之指针
|
4月前
|
存储 安全 编译器
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
|
5月前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
5月前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
5月前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
5月前
|
搜索推荐
指针进阶(2)
指针进阶(2)
46 4