C 指针

指针与指针数组

#include <stdio.h>

void zz1(){
    char *ss = "wa ka ka";
    printf("%s\n",ss);
}

void zz2(){
    char *ss[] = {"luo bo","bai cai"};
    int i =0;
    for(i =0; i<2; i++){
        printf("ss[%d]=%s\n",i,ss[i]);
    }
}
void zz3(){
    int nn = sizeof("wa ka ka");
    printf("%d\n",nn); //9
}

void zz4(){
    int i = 99;
    int *ptr = &i;
    printf("%p\n",ptr);  //0x7ffc9bce8354
    printf("%d\n",*ptr); //99
}

int main(void){
    zz1();
    zz2();
    zz3();
    zz4();
}
"wa ka ka"是一眼看去是8个字符,C语言却认为它是9个字符,C语言的字符串的结尾有个默认的结束符,用于计算机判断该字符串结束。
char *ss = "wa ka ka";

ss是一个变量,指针类型的变量,指向了字面量"wa ka ka"的首地址,指针从首地址向下移动,遇到结束符自动结束,所以直接输出指针就输出了整个字符串。

而对于整数类型,ptr就是指针变量,存储的值为整数类型的地址,*是取地址中的值,*ptr就取出了整数99;一个整数一个存储地址足以,它不像字符串是由多个字符组成,每个字符本身就占了一个存储单元,需要指针不断地移动才能输出所有字符。

 

指针内容是全局常量

这是相对于字符数组来说的,因为数组形式的字符串是局部变量


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* zz5(){
    char *ss = "wa ka ka";
    return ss;
}

/*
char* zz6(){
    char ss[9] = "wa ka ka";
    printf("%s\n",ss);
    return ss; //这里报错,warning: function returns address of local variable [-Wreturn-local-addr]
}
*/


int main(void) {
    char *ss = zz5();
    printf("%s\n",ss);
    return 0;
}

zz5方法中,字符串指针ss指向字面量"wa ka ka",这是一个全局的常量,ss是局部变量,它返回的地址是指向全局常量的,所以其他程序仍能访问其地址;

而zz6中的ss指向的是局部变量,ss同样是返回地址,但它指向的局部变量在方法结束时已经不存在了,所以程序报错。

 

函数指针

/*
 ============================================================================
 Name        : c01.c
 Author      : tanpf
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>

int add(int a)
{
    return a+1;
}

void testp1(){
    int (* p)(int) = &add;
    puts("请输入一个int");
    int a,b;
    scanf("%d",&a);
    b = p(a);
    printf("res:%d\n",b);
}

void testp2(){
    int (* p)(int) = add;
    puts("请输入一个int");
    int a,b;
    scanf("%d",&a);
    b = p(a);
    printf("res:%d\n",b);
}

void testFunc(){
    printf("addr :%x\n",&add); //addr :4005ed
    printf("addr :%x\n",add);  //addr :4005ed

    int var[] = {1,2,3};
    printf("addr first arr:%x\n",&var);     //addr first arr:b396ed40
    printf("addr first arr:%x\n",var);      //addr first arr:b396ed40
    printf("addr first ele:%x\n",&var[0]);  //addr first arr:b396ed40
    printf("addr first ele:%x\n",&var[1]);  //addr first ele:b396ed44
}


int main(void) {
    testFunc();
    testp2();
    return 0;
}
testp1方法与testp2方法的输出结果完全一致;这是因为add本身就指向方法入口地址,&add一样是取add的入口地址;对指针来说,只需要指向访问的入口即可,所以它们的结果一致;数组同样如此。
也就是说,要将一个函数赋予“函数指针”的话,直接写函数名称或&取地址后再赋值都是可以的。
posted @ 2019-03-08 10:17  方诚  阅读(154)  评论(0编辑  收藏  举报