C语言基础笔记(2)

只有十进制有正负.

常量在数据段,动态内存分配在堆,变量在栈

-----------------------------------

计算二维数组的长度

行数 row = sizeof(arr) / sizeof(arr[0]); sizeof(arr[0] 是第一行的长度

列数 col = sizeof(arr[0]) / sizeof(arr[0][0]);

二维数组作为函数参数传递是,行数无意义,不需要传,但列数一定要传,写上去,行数可以再作为一个参数传递. int func( int arr[][col],int row);通过sizeof(arr[0])可以计算出列的字节数 ,arr[][col]传递的只是一个地址,首地址,长度为4.

刷新输出缓冲区fflush(stdout);printf只有到缓冲区满,或者遇到回车才输出

如:

{

    printf("abc");

    while(1);

}

是不会输出abc的.若在c后加回车\n,则会输出.

关闭行缓冲区  stty -echo-icanon ,打开是把减号都省去stty echo icanon

------------------------------------

gets(str)接收字符串,getchar()接收一个字符

------------------------------------

定义指针int *p时,与定义普通变量int a,一样,在栈中都分配内存,只是对a而言,栈中存的是a的值,一个可变的值.然而对*p而言,栈中存的是p所指向的地址值.

0地址(NULL)不能进行操作

指针变量的加减是指该指针按单位进行运算(单位由指针类型定).intarr[4];刚 int *p = arr.则 (p+1) -arr = 1;而不是4(BYTE)

指针类型表示以指针为基址,偏移的字节数,

--------------------------------------

char *str = "abcdefg"; 定义字符串常量,里边的内容不可改,如 *str ='A',是不能把a替换成A 的

二维数组arr[row][col]中 *(arr + n) 表示取第n - 1行的首地址.而*(*arr + n) + 0) 表示取第n - 1行首元素值(二维数组是二级指针)

 const int *p(等同于intconst *p); 定义不能通过P来修改p指向的地址的内容.但该地址的可以通过定义该地址的变量来修改.如int b; p = &b; *p = 1;不允许.但b = 1 是允许.

int * const p;指p所指向的地址不能改,但内容可以改

const int * const p;则指针p只读;

---------------------------------------

char str = "abcd";这是不对的,str是字符类型,而"abcd"是一个字符串,类型不同,也不匹配.但  char *str ="abcd";是对的str是指向char型的地址,而字符串的首元素(地址)就是char 类型.

---------------------------------------

二维数组arr[3][4],arr+1指向的是第二行首地址,而arr[0]+1,是第一行第二个元素地址.

--------------------------------------

int *p[3] 这是一个指针数组,里边的每个元素都是指针.

int (*p)[3] 这是一个指向二级数组的指针.arr[3][4]; p = arr;则 *(p+1)表示第二行的首地址,*(*(p+1)+1)表示第二行第二个元素.

--------------------------------------

指针数组 int *p[3],指针的数组,

数组指针 int (*p)[3],数组的指针,定义了一个数组,数组元素存放的地地址,即二级指针.p指向数组的首地址. arr[3][2];p = arr;则在内存中的指向为

 p -> p[0] --> arr[0]

       p[1] --> arr[1]

       p[2] --> arr[2]

因此 p+1 指向p[1], 取值 *(p+1)则p[1]的值,还是一个地址,这个地址指向arr[1]的首地址,再取值*(*(p+1))才是arr[1][0]值.

二维数组 arr[3][4] 的数组名 arr 与取地址 &arr是同一个地址.arr是二级指针,而arr[0]是一级指针,但是 arr,arr[0]都是指向数组的首地址.因此**arr = *arr[0] = arr[0][0];

arr,&arr, arr[0], &arr[0]是同一个数.

----------------------------------------

 

-------------------------------------------

函数的存在代码段里,只是运行是会在栈里运行.函数名指向的地址是函数在栈的地址,在栈的地址无法获取.

------------------------------------------

malloc动态内存分配是分配连续的堆地址,若堆中没有连续的足够大的空间,则返回NULL.

malloc 至少分配16个字节,而且分配的空间是16的整数倍

----------------------------------------

free()函数是把内存块释放,但指向该内存块的指针p并没有删除,还是指针这个内存(指向的地址没变);因此释放后让p = NULL;

---------------------------------------

栈里的地址函数执行结束后会释放,所以栈里的地址不能作为返回值,但堆里的地址需要手动释放,所以从子函数返回地址给调用函数,返回地的地址应该是通过内存分配得到的地址.

---------------------------------------

void func(int *p)

{

    p = (int *)malloc(sizeof(int));

}

 

void main(void)

{

    int *s =NULL;

    func(s);

    *s = 10;

}

上边的main函数调用func函数,但是指针s指向的地址并不是p所指向的地址,也就是说s并没有指向内存分配得到的地址.因为在传参时 

   s = NULL:

      p = NULL;

func(s),只是将s的值(NULL)赋给p,因此p先指向s的值,再指向内存分配得到的首地址.而s和p是两个不同的地址,所以p的值(即p指向的地址)与s的值是两个不同的数,自然s指向的地址不会是分配得到的地址.若要得到分配的地址,可以通过二级指针实现修改如下:

void func(int **p)

{

    *p = (int *)malloc(sizeof(int));

}

 

void main(void)

{

    int *s =NULL;

    func(&s);

    *s = 10;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值