这篇文章我很少修改,但是指针却又很牛逼,如文章中有哪些理解的不到位的地方,请留下宝贵的意见
#include <stdio.h>
int main()
{
int a = 10; // 在内存中开辟一块空间,存储10
int* p = &a; // 取变量a的地址,可以使用&操作符。
//将a的地址存放在p变量中,故p就是一个存放地址的变量。
return 0;
}
解引用
#include <stdio.h>
int main()
{
int a = 10; // 在内存中开辟一块空间,存储10
int* p = &a; // 取变量a的地址,可以使用&操作符。
// 因为p里面存储的是a的地址,要输出a的值,故要解引用,即加*
printf("%d\n",*p);
return 0;
}
指针的大小在32位平台
是4个字节,在位平台
是8个字节。
解释:
我们知道 指针的大小在32位平台
是4个字节,在位平台
是8个字节,那么指针的类型决定了指针向前或者向后走一步有多大(距离)。
举例: int 类型的指针向前走一步是4个字节
的距离,char 类型的指针向前走一步是1个字节
的距离……
总结:
指针的类型决定了,对指针解引用
的时候有多大的权限(能操作几个字节)。 比如char* 的指针解引用就只能访问一个字节,而int* 的指针的解引用就能访问四个字节。
#include <stdio.h>
int main()
{
char c = 'A';
int b = 7;
// char型指针
char* pc = &c;
// int型指针
int* pb = &b;
// 对char型指针 解引用
printf("%c\n",*pc); // A
// int型指针 解引用
printf("%d\n",*pb); // 7
return 0;
}
#include <stdio.h>
int main() {
int a = 10;
int* p = &a;
char* c = &a;
void* v = &a;
//v++; // error 不可以运算
//*v = 88; // error 不可以解引用
return 0;
}
#include <stdio.h>
int main()
{
int b[10] = { 0 };
int(*pb)[10] = &b;
/*
1. &b表示数组首元素地址,那么要存放该数组的地址,就需要指针,所以要声明一个指针,即*pb,但怎么才能是数组指针呢?
答:可以用(*pb)[],表示一个数组指针,那是什么类型的呢?
答:是整形的
*/
/*总结来说,数组指针存放数组地址,其实还是一个指针*/
return 0;
}
#include<stdio.h>
int main() {
int a[3][4] = {{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}};
int (*p)[4] = a;
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 4; j++) {
printf("%d ",*(*(p+i)+j)); // 解释说明如下
}
printf("\n");
}
return 0;
}
整型数组--->存放整型
字符数组--->存放字符
指针数组--->存放指针
#include <stdio.h>
int main(){
int a = 16, b = 932, c = 100;
//定义一个指针数组
int *arr[3] = {&a, &b, &c};// 指针数组大小为3,存放3个指针,每个指针指向一个地址
printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]); // 指针里面存放的是地址,所以要加*,解引用地址
return 0;
} // 但实际编程环境中,不会这样用指针数组。这里只是便于理解
使用案例
#include <stdio.h>
int main() {
int a1[] = {1, 1, 1};
int a2[] = {2, 2, 2};
int a3[] = {3, 3, 3};
int i, j;
int *pa[] = {a1, a2, a3};
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
printf("%d ", *(pa[i] + j)); // pa[i]:分别找到3个数组首元素地址
printf("\n");
}
return 0;
}
/*int* pa[]--->[]的优先级比*的优先级高,那么[]先和pa结合,成为一个数组。
然后这个数组要存放的数据类型是int*,即要存放的是int形指针。*/
#include <stdio.h>
void test2(int* arr, int len)
{
// 编写代码逻辑
}
int main()
{
int arr[3]={1,2,3};
test2(arr, 3);
return 0;
}
#include <stdio.h>
void test2(int (*arr)[], int r, int c)
{
// 编写代码逻辑
}
int main()
{
int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
test2(arr, 3, 5);
return 0;
}
#include <stdio.h>
void print(int* p, int sz)
{
// 编写代码逻辑
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9 };
int* p = arr;
// 一级指针p
print(p, 10);
return 0;
}
编写形参的技巧
# include<stdio.h>
void test(int** ptr)
{
// 编写代码逻辑
}
int main()
{
int n = 10;
int* p = &n;
int** pp = &p;
// 二级指针pp
test(pp);
test(&p);
return 0;
}
#include <stdio.h>
void test(int **arr[]) {
}
int main()
{
int* pa = NULL, * pb = NULL;
int* arr[2] = { pa, pb };
test(arr);
return 0;
}
建议先了解数组指针,不然不好理解函数指针
#include <stdio.h>
void test(int x, int y)
{
printf("%d\n", x + y);
}
int main()
{
// &函数名 和 函数名 都是函数的地址
void (*pfun1)(int, int)=test;
/*
1. 函数名test是一个地址,那么接收这个函数地址时就需要用指针,所以声明一个指针*pfun1
2. 函数指针 函数指针 这个指针就要指向一个函数,那么怎么才能表达它指向一个函数呢?
答:可以用(*pfun1)(),表示一个指针指向函数,那么指针指向函数的参数是什么类型呢?
答:指针指向函数的参数的类型为int int ,故可以写为(*pfun1)(int, int),那么指针指向函数的返回值是什么类型呢?
答:void,故可以写为void (*pfun1)(int, int)
*/
/*
1. pfun1表示一个指针,对指针解引用,即*pfun1,拿到test函数地址
2. 拿到test函数地址后不就可以调用函数了嘛 test(3, 4)<=>(*pfun1)(3, 4)
*/
(*pfun1)(3, 4);
//最后再看
pfun1(3, 4); // 上边也可以写成这样的形式。为什么?没有那么多为什么,死记住。(这种写法往往还经常用)
return 0;
}
用冒泡排序实现一个类似于库函数qsort()的功能
#include <stdio.h>
#include <stdlib.h> // qsort()
#include <string.h> // strcmp()
/*用冒泡排序实现一个类似于库函数qsort()的功能*/
struct Stu
{
char name[20];
int age;
};
/*
第一个参数:是待排序数组首元素地址
第二个参数:是待排序数组的个数
第三个参数:是待排序数组的每个元素的大小-单位是字节
第四个参数:是函数指针,指向自定义比较函数的地址-这个函数指针的两个参数是:代比较元素的地址
*/
void _swap(char* p1, char* p2, int width)
{
int w = 0;
//一个一个字节的进行交换
for (w; w < width; w++)
{
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2++;
}
}
// 自定义年龄的比较规则
int cmp_stu_by_name(const void* e1, const void* e2)
{
// strcmp():字符串比较函数
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
void bubble_sort(void* base, int num, int width, int(*cmp)(void* e1, void* e2))
{
int i = 0, j = 0, res = 0;
// 比较的趟数
for (i; i < num - 1; i++)
{
// 每一趟比较的对数
for (j; j < num - 1 - i; j++)
{
/*
1、(char*)base:表示先把void类型的base指针,先转换为char类型1个字节的指针
2、width:表示字节数
3、j*width:表示j个数组元素的宽度
4、(char*)base + j * width:表示第j个元素的地址
*/
res = cmp((char*)base + j * width, (char*)base + (j + 1) * width);
if (res > 0)
_swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
int main() {
int i = 0;
struct Stu s[] = { {"zhangsan",10}, {"lisi", 30},{"wangwu",20} };
int num = sizeof(s) / sizeof(s[0]);
bubble_sort(s, num, sizeof(s[0]), cmp_stu_by_name);
for (i; i < num; i++)
printf("%s\n", s[i].name);
return 0;
}
必须先了解函数指针
#include <stdio.h>
/*以下四个函数分别为 加减 乘 除*/
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
//分别将四个函数的地址,存放在一个函数指针数组*p中
int(*p[4])(int x, int y) = {add, sub, mul, div };
return 0;
}
实际运用小栗子
#define _CRT_SECURE_NO_WARNINGS 1
/*实现一个简单的计算器*/
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
// p是一个函数指针数组
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
while (input)
{
printf("*************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf("*************************\n");
printf("请选择:");
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf("输入操作数 数字间用空格隔开:");
scanf("%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf("输入有误\n");
printf("ret = %d\n", ret);
}
return 0;
}
必须先了解函数指针数组
#include <stdio.h>
void test(const char* str) {
printf("%s\n", str);
}
int main() {
// 函数指针pfun
void (*pfun)(const char*) = test;
// 函数指针的数组pfunArr
void (*pfunArr[5])(const char* str);
pfunArr[0] = test;
//指向函数指针数组pfunArr的指针ppfunArr
void (*(*ppfunArr)[10])(const char*) = &pfunArr;
return 0;
}
#include <stdio.h>
void print(char* str)
{
printf("%s\n", str);
}
void test(void (*pfun)(char*)) {
pfun("hello world!"); // 触发print
}
int main() {
test(print); // 虽然这里调用了print函数,但是print函数效应,并没有立即发生
return 0;
}
野指针成因:
1、指针未初始化
#include <stdio.h>
int main()
{
int* p; // 局部变量指针 p 未初始化,默认指向一个随机地址
*p = 20;
return 0;
}
可以看看指针是怎么初始化的
2、指针越界访问
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i; i <= 11; i++)
{
// 当指针p指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
3、指针指向的空间释放
#include <stdio.h>
int main()
{
char str1[] = "hello";
// 初始化指针
char* st = NULL;
// 使用指针
st = str1;
// 指针解引用
printf("%c",*st); // h
return 0;
}
#include <stdio.h>
int main()
{
// 以下这句话不是把"hello"整个字符串赋值给了*p,而是把首字母的地址赋值给了*p
char* p = "hello";
// 打印第一个元素
printf("%c\n", *p);
// 打印第一个元素的地址
printf("%p\n", p);
// 找到第一个元素的首地址,然后打印出整个字符串
printf("%s\n", p);
return 0;
}
#include <stdio.h>
int main()
{
char* p = "hello"; // "hello"是一个常量字符串
*p = 'x'; // 错误代码
// 找到第一个元素的首地址,然后打印出整个字符串
printf("%s\n", p);
return 0;
}
因为 "hello" 是一个常量字符串,值不能被修改,所以 *p = 'x' 是错误代码。修改为最标准的形式为 const char* p = "hello";
#include <stdio.h>
int main()
{
char str1[] = "hello";
char str2[] = "hello";
char* str3 = "hello";
char* str4 = "hello";
if (str1 == str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if (str3 == str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
解释如下:
1、char* str3 = “hello”; 代表常量字符串,不可以被修改,那么就没有必要在内存中,存储2份,1份即可。
#include<stdio.h>
int main()
{
int a[] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int* p = a+5,* q = NULL;
*q = *(p + 5);
printf("%d %d", *p,*q);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
/*求字符串的长度*/
int test(char* s)
{
char* p = s;
while (*++p); // 先进行指针运算即+1,然后对指针解引用
return p - s; // 指针 - 指针
}
/*计算字符串占用内存字节的个数*/
int test1(char* s)
{
char* p = s;
while (*p++); // 先对指针解引用,然后p++
// 虽然*p=0 时,while()循环进不去了,但是指针还要在走一步
return (p - s);
}
int main()
{
char str[] = "hello world";
printf("%d\n", test(str)); // 11
printf("%d\n", test1(str)); // 12
return 0;
}
#include <stdio.h>
int main() {
// 一维数组
/*
* 数组名表示首元素的地址,除了以下这2种情况
* 1. sizeof(数组名):数组名表示整个数组
* 2. &数组名:数组名表示整个数组
*/
// 以下为32位平台测试
int a[] = { 1,2,3,4 };
// 16 满足以上条件->sizeof(数组名):数组名表示整个数组
printf("%d\n", sizeof(a));
// 4 这里的数组名a表示首元素的地址,a+0还是首元素地址,地址的大小是4个字节
printf("%d\n", sizeof(a + 0));
// 4 这里的数组名a表示首元素的地址,*a表示首元素,首元素所占的空间为4个字节
printf("%d\n", sizeof(*a));
// 4 这里的数组名a表示首元素的地址,a+1表示第2个元素的地址,地址的大小是4个字节
printf("%d\n", sizeof(a + 1));
// 4 a[1]表示第2个元素,该元素所占的空间为4个字节
printf("%d\n", sizeof(a[1]));
// 4 满足以上条件->&数组名:数组名表示整个数组。
// 取出的是整个数组的地址,但是整个数组的地址也是地址,地址的大小是4个字节
printf("%d\n", sizeof(&a));
// 16 &a是数组的地址,数组的地址解引用访问的是整个数组
printf("%d\n", sizeof(*&a));
// 4 &a是数组的地址,&a+1虽然跳过了整个数组的地址,但依旧是地址,地址的大小是4个字节
printf("%d\n", sizeof(&a + 1));
// 4 &a[0]是第一个元素的地址,地址的大小是4个字节
printf("%d\n", sizeof(&a[0]));
// 4 &a[0] + 1是第二个元素的地址,地址的大小是4个字节
printf("%d\n", sizeof(&a[0] + 1));
return 0;
}
#include <stdio.h>
int main() {
// 字符数组
/*
* 数组名表示首元素的地址,除了以下这2种情况
* 1. sizeof(数组名):数组名表示整个数组
* 2. &数组名:数组名表示整个数组
*/
// 以下为32位平台测试
char arr[] = { 'a','b','c','d','e','f' };
// 6 满足以上条件->sizeof(数组名):数组名表示整个数组
printf("%d\n", sizeof(arr));
// 4 这里的arr,表示数组首元素的地址,arr+0还是首元素的地址,地址的大小是4个字节
// 在这里你可能有疑问了?不是char型地址吗?不应该是1个字节吗,怎么会是4个字节?请看上面专题 c 语言 指针类型的意义 然后类比
printf("%d\n", sizeof(arr + 0));
// 1 arr是首元素的地址,*arr是首元素,首元素所占的空间是1个字节
printf("%d\n", sizeof(*arr));
// 1
printf("%d\n", sizeof(arr[1]));
// 4 满足以上条件->&数组名:数组名表示整个数组。但是数组地址也是个地址,地址的大小是4个字节
printf("%d\n", sizeof(&arr));
// 4 满足以上条件->&数组名:数组名表示整个数组。&arr + 1是跳过了整个数组后的地址,只要是地址,地址的大小就是4个字节
printf("%d\n", sizeof(&arr + 1));
// 4 &arr[0]表示第一元素的地址,&arr[0] + 1表示第二个元素的地址,地址的大小是4个字节
printf("%d\n", sizeof(&arr[0] + 1));
// 随机值 因为数组末尾没有结束标志\0,所以'\0'位置放了一个随机值。这里的arr表示首元素的地址
printf("%d\n", strlen(arr));
// 随机值 因为数组末尾没有结束标志\0,所以'\0'位置放了一个随机值。这里的arr表示首元素的地址,arr + 0还是首元素的地址
printf("%d\n", strlen(arr + 0));
// 报错 这里的arr表示首元素的地址,*arr表示解引用,找到了首元素'a','a'对应ascll码表十进制的值为97,
// 那么strlen函数就把97当作起始地址值,开始从这里向后面数数。那么自然而然就会出现错误,即非法访问内存了
//printf("%d\n", strlen(*arr));
// 报错 理由同上
//printf("%d\n", strlen(arr[1]));
// 随机值 满足以上条件->& 数组名:数组名表示整个数组。因为数组末尾没有结束标志\0,所以'\0'位置放了一个随机值。
printf("%d\n", strlen(&arr));
// 随机值 满足以上条件->& 数组名:数组名表示整个数组。&arr + 1是跳过了整个数组后的地址。
printf("%d\n", strlen(&arr + 1));
// 随机值 &arr[0]表示第一元素的地址,&arr[0] + 1表示第二个元素的地址,因为数组末尾没有结束标志\0,所以'\0'位置放了一个随机值。
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
#include <stdio.h>
int main() {
/*
* 数组名表示首元素的地址,除了以下这2种情况
* 1. sizeof(数组名):数组名表示整个数组
* 2. &数组名:数组名表示整个数组
*/
// 以下为32位平台测试
char arr[] = "abcdef";
// 7 满足以上条件->sizeof(数组名):数组名表示整个数组。因为字符串末尾隐藏了\0,所以整个数组所占的空间是7个字节
printf("%d\n", sizeof(arr));
// 4 这里的arr是首元素的地址,arr+0还是首元素的地址。地址的大小是4个字节
printf("%d\n", sizeof(arr + 0));
// 1 这里的arr是首元素的地址,*arr表示首元素。首元素所占的空间是1个字节
printf("%d\n", sizeof(*arr));
// 1 第2个元素所占的空间是1个字节
printf("%d\n", sizeof(arr[1]));
// 4 满足以上条件->&数组名:数组名表示整个数组。但是数组的地址也是地址,地址的大小是4个字节
printf("%d\n", sizeof(&arr));
// 4 满足以上条件->& 数组名:数组名表示整个数组。&arr + 1是跳过整个数组后的地址,但也是地址。地址的大小是4个字节
printf("%d\n", sizeof(&arr + 1));
// &arr[0]表示首元素的地址,&arr[0] + 1是第二个元素的地址。地址的大小是4个字节
printf("%d\n", sizeof(&arr[0] + 1));
// 6 这里的arr是首元素的地址,strlen函数会从这个地址,向后面数数,直到遇到\0,
printf("%d\n", strlen(arr));
// 6 这里的arr是首元素的地址,arr + 0 还是首元素的地址,strlen函数会从这个地址,向后面数数,直到遇到\0,
printf("%d\n", strlen(arr + 0));
// 报错 这里的arr表示首元素的地址,*arr表示解引用,找到了首元素'a','a'对应ascll码表十进制的值为97,
// 那么strlen函数就把97当作起始地址值,开始准备从这里向后面数数。那么自然而然就会出现错误,即非法访问内存了
//printf("%d\n", strlen(*arr));
// 报错 理由同上
//printf("%d\n", strlen(arr[1]));
// 6 满足以上条件->& 数组名:数组名表示整个数组。strlen函数会从起始地址开始向后数数,直到遇到\0
printf("%d\n", strlen(&arr));
// 随机值 满足以上条件->& 数组名:数组名表示整个数组。
// &arr + 1是跳过整个数组后的地址,但也是地址。
// 地址的大小是4个字节,可是我们求的不是地址大小,而是元素的个数,strlen函数会从跳过整个数组后的地址开始向后数数
// 然而这个地址处和后面没有元素,所以会出现随机值
printf("%d\n", strlen(&arr + 1));
// 5 &arr[0]首元素的地址,&arr[0] + 1 第2个元素的地址。strlen函数会从这个地址开始向后面数数,直到遇到\0
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
#include <stdio.h>
int main() {
// 以下为32位平台测试
char* p = "abcdef";
// 4 p是一个指针变量, sizeof(p)计算指针变量的大小
// 4 也可以这里理解,p指向首元素的地址(注意用词:指向),不管是什么类型的地址,地址的大小都是4个字节
printf("%d\n", sizeof(p));
// 4 p指向首元素的地址,p+1指向第二个字符的地址,不管是什么类型的地址,地址的大小都是4个字节
printf("%d\n", sizeof(p + 1));
// 1 p指向首元素的地址,*p表示解引用,找到字符'a', 字符'a'所占的空间是一个字节
printf("%d\n", sizeof(*p));
// 1 p[0] == *(p+0) p指向首元素地址,p+0还是指向首元素的地址,*(p+0)表示解引用,找到字符'a', 字符'a'所占的空间是一个字节
printf("%d\n", sizeof(p[0]));
// 4 含义如下图 &p:表示地址,不管是什么类型的地址,地址的大小都是4个字节
printf("%d\n", sizeof(&p));
// 4 含义如下图 &p+1:表示地址,不管是什么类型的地址,地址的大小都是4个字节
printf("%d\n", sizeof(&p + 1));
// 4 含义如下图 p[0]表示字符'a',&p[0]表示找到字符'a'的地址,&p[0]+1表示找到字符'b'的地址,不管是什么类型的地址,地址的大小都是4个字节
printf("%d\n", sizeof(&p[0] + 1));
// 6 p指向首元素的地址,strlen函数从这个地址处,向后面数数,直到遇到\0
printf("%d\n", strlen(p));
// 5 p指向首元素的地址,p+1指向第二个字符的地址,strlen函数从这个地址处,向后面数数,直到遇到\0
printf("%d\n", strlen(p + 1));
// 报错 p指向首元素的地址,*p表示解引用,找到了首元素'a','a'对应ascll码表十进制的值为97,
// 那么strlen函数就把97当作起始地址值,开始准备从这里向后面数数。那么自然而然就会出现错误,即非法访问内存了
//printf("%d\n", strlen(*p));
// 报错 理由同上
//printf("%d\n", strlen(p[0]));
// 随机值 &p表示起始地址,strlen函数,会从该处,开始向后面数数,但因为p里面存放的是随机地址,这个随机地址中什么时候出现\0不确定,所以才为随机值
printf("%d\n", strlen(&p));
// 随机值 理由同上
printf("%d\n", strlen(&p + 1));
// 5 p[0]表示字符'a',&p[0]表示找到字符'a'的地址,&p[0]+1表示找到字符'b'的地址,strlen函数从此处开始向后数数,直到遇到\0
printf("%d\n", strlen(&p[0] + 1));
return 0;
}
#include <stdio.h>
int main() {
// 二维数组
int a[3][4] = { 0 };
// 48 sizeof(数组名):数组名表示整个数组
printf("%d\n", sizeof(a));
// 4
printf("%d\n", sizeof(a[0][0]));
// 16 a[0]相当于第一行一维数组的数组名,sizeof(a[0])计算的是第一行的大小
printf("%d\n", sizeof(a[0]));
// 4 a[0]是第一行的数组名,数组名此时是第一行首元素的地址,a[0]+1是第一行第二个元素的地址,地址的大小是4个字节
printf("%d\n", sizeof(a[0] + 1));
// 4 *(a[0] + 1))第一行第二个元素的所占空间为4个字节
printf("%d\n", sizeof(*(a[0] + 1)));
// 4 a是二维数组的数组名,没有sizeof(a),也没有&a,所以a是首元素地址,
// 二维数组的首元素是他的第一行,a就是第一行元素的地址,a+1就是第二行首元素的地址
printf("%d\n", sizeof(a + 1));
// 16 a+1就是第二行首元素的地址,*(a[0] + 1))是第二行元素的大小
printf("%d\n", sizeof(*(a + 1)));
// &a[0] + 1第二行的地址
printf("%d\n", sizeof(&a[0] + 1));
// *(&a[0] + 1))第二行的大小
printf("%d\n", sizeof(*(&a[0] + 1)));
// 16 a是首元素的地址,第一行的地址。*a就是第一行,sizeof(*a)计算第一行的大小
printf("%d\n", sizeof(*a));
// 16 sizeof函数计算的是类型的大小,即计算的是存放了4个整型数的一维数组的大小,与该数组是否越界无关。
printf("%d\n", sizeof(a[3]));
return 0;
}
/*
int a[2][3] = { 1, 2, 3, 4, 5 ,6 };
printf("%p\n",&a[0][1]);
printf("%p\n",a[0]+1);
printf("%p\n", &a[1][1]);
printf("%p\n", a[1] + 1);
*/
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- awee.cn 版权所有 湘ICP备2023022495号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务