|
一、能力错觉 当书本(或谷歌)摆在眼前时,大脑会产生错觉,以为学习材料也同样存入了大脑,阅读毕竟比回想简单多了。 以为反复的阅读资料就是自己已经掌握知识,这就是能力错觉。 解决能力错觉的方法:
现在网络上盛行各种it类的视频教程,我不否认不少视频教程是高质量的,但是所有视频类资料都有一个问题:
有效的解决办法是:
二、数组和指针有什么区别? 正文目录: 1. 用于声明时两者有重大区别2. 你真的理解声明和定义吗? 3. 数组和指针的底层是如何访问数据的?0 I! w/ ?+ s( N$ D' ^1 J3 S& R, V 4. 哪些场景可以用指针代替数组?( j5 t- ^9 }& T& N/ { 5. 为什么C语言要把数组形参退化为指针? 6. 如何使用指针访问多维数组? 7. 相关面试题$ x% I9 G" s. ~# h) ] 写作目的:
测试环境:
1) 误导新手的说法: 由于数组和指针的所谓等价性非常接近,不少程序员有时忽视了二者之间的其他重要区别 ,最误导新手的说法之一就是 “数组和指针是相同的",这是一种非常危险的说法。 看下面这个例子: extern int *x;extern int x[];
2) 为什么有些人会误以为指针和数组总是可以互换? 最主要原因是:" ~. ~9 o8 `1 w! m4 b3 B
2. 你真的理解声明和定义吗? 想要要真正理解为什么 extern int *x 不等于 extern int x[],我们首先需要搞清楚什么是声明,什么是定义。 1) 链接器的视角:
2) 定义和声明的联系与区别:
3) 总结成一句话:
4) 回过头来看这个例子: extern int *x;8 F+ Q4 n* `. F8 o& Zextern int x[]; z3 N2 @2 O1 H1 {% `) P: S( G 前者声明了一个指针,后者声明了一个数组,那么它们对应的指针和数组的定义(最重要的是内存分配) 能相等吗? 3. 数组和指针的底层是如何访问数据的? 现在我们来看看指针和数组的定义与使用。 1) "地址 X (Address)" 和 "地址 X 的内容(Contents of Address)" 之间的区别: 对于"地址 X" 和 "地址 X 的内容",在 C 语言中是用同一个符号来表示这两样东西,由编译器根据上下文环境判断它的具体含义。 2) 看下面这个例子: X = Y- |) y3 _0 G# l
3) 数组和指针的访问方式是不同的: char a[9] = "abcedefgh";
char *p = &c;, E% B5 E( W$ i! U* l
4) 当定义为指针 (char *p),并以数组方式 (p) 引用时会发生什么? char *p = ”abcdefgh”printf("%c\n", p[3]); char *a = ”abcdefgh” printf("%c\n", a[3]);
4. 哪些场景可以用指针代替数组? 数组和指针容易混淆使用的 2 大类场景:
1) 声明:
extern char a[]; // ok extern char *a; // error. A5 H. C. W, [6 y* |6 m
2) 在表达式中使用:
3) 几条重要的规则:
5. 为什么 C 语言要把数组形参退化为指针?1) 出于效率的考虑:
2) 出于简化编译器的考虑:
3) 看下面这个例子: static int array[10], array2[10];# k6 ^* G8 \/ ]/ r* ~3 U' R& i) M Q: s. F1 e4 E- G static void func1(int *ptr): F3 `% N7 w2 z' @1 l' o {! r, K) d) B$ ?0 h' y( q( u% ?- K9 h ptr[1] = 3; *ptr = 3; ptr = array2;0 Z2 l1 A( q3 B* v! V1 s6 }9 r } static void func2(int array[])+ C% @9 b, o5 u: {+ J) I {. ?, v! c% E$ m1 J+ _) |, L4 Z6 B array[1] = 3; *array = 3; array = array2; // OK, because array is a pointer x# f- J' ~4 X6 V+ V7 |9 N printf("*array=%d\n", *array); } int main(void)" E) G0 Y' r: m" ]! e! g { func1(array);! r0 d1 j. G; t func2(array);& G/ R5 K7 T7 A - F) U% e. h3 ]$ m, ] array[1] = 3; *array = 3; array = array2; // ERROR return 0; }" N4 ^1 p+ K# ~9 B2 z 编译运行: // main 中调用 array = array2时:11: error: assignment to expression with array type // 去掉 main / array = array2时: $ ./point_array_arg( E; N$ z4 T9 W8 v2 h *array=0) l2 @2 f" w Y& j 6. 如何使用指针访问多维数组? 1) C 语言的多维数组:
7. 相关面试题 1) 找错:计算字符串长度 下面这段程序是为了把字符串转换为大写: #include <stdio.h>1 w( t3 x: r; {8 S' X. @! e1 {" e0 {6 _. I void UpperCase(char str[]) {2 u9 S# G/ W* S) I% N int test = sizeof(str); int test2 = sizeof(str[0]); for(size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i) {! W) B4 ^& n7 O! Q1 ] j; z if('a'<=str && str<='z')0 l1 m# \% E9 E; m( ` str -= ('a'-'A');& Q; Q! g* n4 T( Z2 b" j/ o }" o! B. d- r% L8 X% { } ; `2 K9 q, i: @8 I int main(void)2 }. C9 J; d- ]3 V$ { { char str[] = "aBcDeefGHijKL";" ^; a B, U; X; ]* j( e printf("The length of str is %d\n", sizeof(str)/sizeof(str[0])); 1 F4 Q7 K9 B1 p4 Q2 M# V UpperCase(str); printf("result: %s\n", str);& D; h' E3 l+ p. p+ `" K; S return 0; } 运行结果: $ ./sizeof_array + R& f1 ~, F/ [" A, V) P) i. PThe length of str is 14) b- q5 D, c# R/ ~$ t6 o/ |. | result: ABCDEEFGHijKL 问题出在 UpperCase() 里的 sizeof(str),这里的 str 是一个指针而不是数组。 正确的写法有2种:
|
微信公众号
手机版