zoukankan      html  css  js  c++  java
  • C he 指针

    1.声明一个指向整型数组的指针

      int  (*p)[10];

    2.如果一个 一维数组matrix[10] 作为函数参数 , 则函数原型应为:

      void  func( int *ptr );  或  

      void  func( int ptr[]);

      如果一个 二维数组matrix[10][10] 作为函数参数 , 则函数原型为 :

      void  func( int (*ptr)[10] ); 或

      void  func( int ptr[][10] );

      因为 ptr 的第一个下标要根据 第二个下标(整型数组的长度)进行调整,第二个下标根据整型长度调整

      而一维的数组 作为参数时,计算下标时不需要。所以声明成

      void  func(int **ptr) ; 不正确。

    3. int  *api[10] ;

      分析:假定他是一个表达式,对他求值

        下标优先级高,所以他是某种类型的数组(包含10个元素)。然后执行间接访问操作,结果是一个整型

        所以api 是一个指向整型的指针数组。

    4. 理解指针与数组名

      例如:int b[4]  b的类型是指针常量

      例(c和指针 p98):

        源文件1中有声明:int a[10];  int *b = a;

        在源文件2中有代码:  extern int  *a;

                      extern int   b[];

                      x = a[3];  

                      y = b[3];

        则程序会失败。

        分析: 由源文件1知 a 是一个数组名,b是指针。而在文件2中,a被当成指针变量,所以a[3]的过程如下:a的内容加3,然后进行解引用;  b被当成一个数组名(指针常量),所以b[3]过程为:取出b[0]的地址(&b[0]),将他加3;

        所以这两个过程都会导致不可预知的错误。

    5. 字符串函数:

      strlen()的返回值类型是size_t(无符号整数类型),所以 strlen( a ) - strlen( b ) 总是大于等于0。如果将结果强制转换成Int,问题就能解决。

    6.注意血统问题:虽然2个指针指向同一个位置,但可能二者完全不是一种类型的。

    7.还是数组与指针:

     

     1 #include <stdio.h>
     2 
     3 int
     4 main()
     5 {
     6     int     a[4];
     7     int     *b = a;
        printf("a:%s ",a);
    8 printf("&a:%x &b:%x ", &a,&b); 9 printf("&a[0]:%x &b[0]:%x ",&a[0], &b[0]); 10 }

      输出结果如下:

      a:bf90bd80

      &a:bf90bd80  
      &b:bf90bd7c
      &a[0]:bf90bd80
      &b[0]:bf90bd80

      数组名的本质是:指向元素的指针常量。但是在 数组名当做sizeof操作符或单目操作符&的操作数时例外。(c和指针 p142)。是叫指针退化。(数组名原地就是数组内容,而指针时指向的地址)。

       看程序(coolshell):

     1 #include <stdio.h>
     2 struct str{
     3     int len;
     4     char s[0];
     5 };
     6  
     7 struct foo {
     8     struct str *a;
     9 };
    10  
    11 int main(int argc, char** argv) {
    12     struct foo f={0};
    13     if (f.a->s) {
    14         printf( f.a->s);
    15     }
    16     return 0;
    17 }

        如果将s[0],改为指针,则会在13行崩溃(coolshell);

    8.  注意数组的不完整声明(C和指针 P199)。

    9.  数组和结构的区别:

        数组元素的大小都相同,所以可以通过下表访问。而结构的成员可能时不同的类型。

        结构的变量是标量类型。

    10. 结构成员的访问采用的  相对地址

        struct foo {

          int  i;

          char  *p;

        }f;

        则  &(f->i) 和 &f 一样,而 &(f->p) == &f + 4 (具体参看 coolshell)

      可以分配给结构一个连续的区域:(利用了零长数组和相对地址,ISO C不允许)(具体coolshell)

     1 #include <stdlib.h>
     2 #include <string.h>
     3  
     4 struct line {
     5    int length;
     6    char contents[0]; // C99的玩法是:char contents[]; 没有指定数组长度
     7 };
     8  
     9 int main(){
    10     int this_length=10;
    11     struct line *thisline = (struct line *)
    12                      malloc (sizeof (struct line) + this_length);
    13     thisline->length = this_length;
    14     memset(thisline->contents, 'a', this_length);
    15     return 0;
    16 }
  • 相关阅读:
    条款41:了解隐式接口和编译期多态
    条款41:了解隐式接口和编译期多态
    虚机制
    条款31:将文件间的编译依存关系降至最低
    条款30:透彻了解inlining的里里外外
    条款28:避免返回handles 指向对象内部成分
    条款27:尽量少做转型动作
    条款26:尽可能延后变量定义式的出现时间
    条款25: 考虑写出一个不抛异常的swap函数
    APP测试工程师面试题:之一
  • 原文地址:https://www.cnblogs.com/shaughn/p/3636292.html
Copyright © 2011-2022 走看看