1、
int a[5] = {1,2,3,4,5};
//&a+1为第二批int a[5]的第一个元素地址的地址,相当于{1,2,3,4,5, x1, x2,x3,x4,x5} *(&a+1) == &x1
int b[2][3] = {{1,2,3}, {4,5,6}};
//&b+1为第二批b[2][3]的第一块元素地址的地址,相当于{{1,2,3},{4,5,6},{x1,x2,x3},{y1,y2,}} *(&b+1) == &b[2]
2、
(1)scanf(“%d%d…”, &i,&j,…)
返回值:有多少个能被成功读入就返回多少,如i,j能被读入返回2
都没有被读入返回0,读到文件末尾或者按CTRL+Z返回EOF
(2)
while(scanf(“%d”, &i) != 1) //如果输入非整数输入的东西不能被scanf接收
scanf(“%*s”); //输入留在缓冲区一直循环,加入scanf(“%*s”)
//用于接收缓冲区的字符串数据清空缓冲区
3、
(1)int a[][2]; //a是指向第一个元素的地址,第一个元素是含有两个int的数组,所以a是指向含有两个Int数组的指针,可以写成int (*a)[2] == int[2] (*a)
简单的说:a是一个指针指向含有两个Int数组的地址
(2)而int ** p中的p是指向地址的指针
不能把p=a; 两个不是同一个概念
(3)int * b[2]; //定义一个指针数组,b里面的每个元素是一个int *即地址,又b是第一个元素地址,故b是一个指向地址的指针,p = b;没有问题
4、
#include<ctype.h>头文件
isalpha() //判断一个字符是否为字母,是返回非0,否返回0
isdigit() //判断一个字符是否为数字,是返回非0,否返回0
isslower() //判断一个字符是否为小写字母,是返回非0,否返回0
issupper() //判断一个字符是否为大写字母,是返回非0,否返回0
ispunct()//判断一个字符是否标点符号,是返回非0,否返回0
isspace()//判断一个字符是否为空白字符(空格、换行、换页、回车、制表),是返回非0,否返回0
tolower() //参数字符是大写,返回小写,否则返回原始参数
tosupper() //参数字符是小写,返回大写,否则返回原始参数
5、
getchar() //读到文件结尾或者按CTRL+Z返回EOF
6、
新特性初始化数组
int a[] = {1, [3] = 20}; //1,0,0,20
int a[] ={1, [0]= 5, 3}; //5,3
7、
char arr[]和char * arr区别
char arr[] = “hello”;
char * arr = “hello”;
第一个程序数组名是指针常量不可以改变,但内容可以改变,首先char arr[]会在栈中开辟一块内存空间,然后字符串常量会拷贝一个副本储存到这个内存空间,栈中开辟的内存空间的内容可读可写
第二个是直接把字符串常量区的一个地址赋给arr,若是通过arr修改了内容也等于修改了字符串常量区的内容,这是错误的,字符串常量区只允许读不允许写
char arr[10];
char *p = “hello”;
char *q = arr;
fgets(p, 5, stdin); //error 在p指向的地址写入字符串,因p指向字符串常量区地址,可读但不可写
fgets(q, 5, stdin); //q指向arr地址,因arr是从栈中开辟的空间,可读可写,故在地址上写入字符串是对的
8、
NULL含义
NULL表示0,但不是数字0,而是表示地址编号为0,为0的地址编号不能存放任何东西。Int * p = NULL; *p = 5;是错误的。
9、
void f(int * p)
{
P = (int *)malloc(4);
}
void main()
{
int * i = NULL;
f(i);
}
通过函数给i分配内存空间,这样写是错的。因为p和i是两个独立的个体,首先把i赋给p,这时p指向i地址即NULL,然后通过函数给P分配内存,这时p不在指向i地址,而是重新指向一个分配好内存空间的地址,i依然是NULL
10、
size_t类型是sizeof运算符返回的类型,C规定sizeof运算符返回一个整数类型,但并未指定是哪种整数类型,可以是unsigned int unsigned long