content
2.1 Pointers and pointer types
2.2 The meaning of pointer types
8.1 Exercise: Write a function that reverses the contents of a string.
8.2 Practice finding the sum of the first 5 terms of Sn=a+aa+aaa+aaaa+aaaaa, where a is a number,
For example: 2+22+222+2222+22222
1.1 What is a pointer
1. A pointer is the number of a smallest unit in memory, that is, an address (each space has an address)
2. The pointer that is usually spoken in spoken language usually refers to a pointer variable , which is a variable used to store a memory address. An address uniquely identifies an address space.
3: The pointer generates 32 bits: 4 bytes through the cpu on the 32-bit platform, and 32 bits: 8 bytes through the cpu on the 64-bit platform.
#include <stdio.h>
int main()
{
int a = 10;//在内存中开辟一块空间
int *p = &a;//对变量a,取出它的地址,可以使用&操作符。
//a变量占用4个字节的空间,a的4个字节的第一个字节的地址存放在p变量中,p就是一个指针变量
return 0;
}
2.1 Pointers and pointer types
Variables have different types, integer, float, etc. Does the pointer have a type?
The size of the pointer variable is 4/8 bytes, which are used to store the address
int main()
{
int a = 10;
int* pa = &a;
char ch = 'w';
char* pc = &ch;
printf("%d\n", sizeof(pa));
printf("%d\n", sizeof(pc));
return 0;
}
2.2 The meaning of pointer types
2.3 The pointer type determines how much authority the pointer has when dereferencing
Integer pointer dereference accesses 4 bytes, character pointer reference accesses 1 byte
int main()
{
int a = 0x11223344; //44 33 22 11
int* pa = &a;
*pa = 0; //00 00 00 00 操作了4个字节
char* pa = &a;
*pa = 0; //00 33 22 11 操作了1个字节
return 0;
}
2.4 The type of the pointer determines how much (distance) the pointer takes a step forward or backward
int main()
{
int a = 10;
int*pa = &a;
char* pc = &a;
printf("%p\n", pa);
printf("%p\n", pc);
printf("%p\n", pa+1);
printf("%p\n", pc+1);
return 0;
}
3.1 Wild pointer
A wild pointer is where the pointer points to is unknowable (random, incorrect, unspecified)
3.2 Cause: pointer is not initialized
int main()
{
int* p;//指针变量没有初始化,放的是随机值,随机值中的空间不属于我们,非法操作
*p = 20;
return 0;
}
3.3 Cause: pointer out-of-bounds access
int main()
{
int arr[5] = { 1,2,3,4,5 };
int i = 0;
int* p = arr;
for (i = 0; i < 10; i++)
{
printf("%d ", *p);//指针所指向的空间越界访问
p++;
}
return 0;
}
int* test()
{
int a = 10;
printf("%d\n", a);
return &a; //函数结束空间销毁,a的地址未知,非法访问内存
}
int main()
{
int*p = test();
*p = 100;
return 0;
}
3.4 Avoiding wild pointers
1. Pointer initialization
2. Beware of pointer out of bounds
3. The pointer points to the space and is set to NULL (NULL is the 0 address, only initialized if not used)
4. Avoid returning the address of a local variable
5. Check the validity of the pointer before use (assert assertion)
4.1 Pointer Arithmetic
4.2 Pointer + - Integer Relational Operation of Pointer
int values[5];
int *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)//地址有大有小,指针也有关系运算
{
*vp++ = 0;
}
4.3 Pointer-pointer (premise: two pointers must point to the same space)
int main()
{
int arr[10] = { 0 };
printf("%d\n", &arr[0] - &arr[9]);//答案是9,指针-指针得到两个指针之间的元素的个数
return 0;
}
pointer - pointer implements strlen
int my_strlen(char* str)
{
char* start = str;
while (*str)
{
str++;
}
return str - start;
}
int main()
{
char arr[] = "abcdef";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
5. Pointers and arrays
The array name represents the address of the first element of the array
But there are 2 exceptions:
sizeof (array name), the array name represents the entire array, and the size of the entire array is calculated
& array name, the array name represents the entire array, and the address of the entire array is taken out
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));//指针+-整数写法
}
return 0;
}
int main()
{
int arr[10] = { 0 };
printf("%p\n", arr);
printf("%p\n", arr+1);
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0]+1);//是一个整形指针类型,+1跳过一个整形
printf("%p\n", &arr);
printf("%p\n", &arr+1);//+1跳过一个数组,是一个数组指针类型
return 0;
}
6. Secondary pointer
int main()
{
int a = 10;
int* pa = &a;//pa是指针变量(一级指针) *是指针,int是类型
int** ppa = &pa;//ppa是一个二级指针,存放一级指针变量的地址
//int* 是一级指针变量的类型,*代表是一个指针
int*** pppa = &ppa;//pppa就是三级指针.....
//ppa如何找到a,*ppa=pa,*pa=a ->可以写成 **ppa找到a;
return 0;
}
7. Array of pointers
Is an array of pointers a pointer or an array? We have learned integer arrays: int arr[5], an array of 5 integers
An array of pointers is an array of pointers, such as int* arr[5]
int main()
{
//int arr[5];//指针数组 - 存放整型的数组
//char ch[6];//字符数组 -存放字符的数组
int a = 10;
int b = 11;
int c = 12;
int d = 13;
int e = 14;
int* arr2[5] = {&a, &b, &c, &d, &e};//指针数组
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", *(arr2[i])); //法很难看,在一级指针中不会这么用
}
return 0;
}
int main()
{
int data1[] = { 1,2,3,4,5 };
int data2[] = { 2,3,4,5,6 };
int data3[] = { 3,4,5,6,7 };
//arr就是一个指针数组
int* arr[3] = { data1 ,data2, data3 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
8.1 Exercise: Write a function that reverses the contents of a string.
思路:用指针的方式找到字符串的起始地址和结束地址,用临时变量交换
#include <assert.h>
#include <stdio.h>
void reverse(char* str)
{
assert(str);//检查要使用的指针是否为NULL
int len = strlen(str);
char* left = str;
char* right = str + len - 1;
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[100];
scanf("%s",arr);
reverse(arr);
printf("%s", arr);
return 0;
}
8.2 Practice finding the sum of the first 5 terms of Sn=a+aa+aaa+aaaa+aaaaa, where a is a number,
For example: 2+22+222+2222+22222
思路:
该表达式的第i项中有i个a数字,第i项为ret因此:可以推导出ret*10+a
int main()
{
int a = 0;
int n = 0;
scanf("%d%d", &a, &n);
int i = 0;
int sum = 0;
int ret = 0;
for (i = 0; i < n; i++)
{
ret = ret * 10 + a;
sum += ret;
}
printf("%d ", sum);
return 0;
}
8.3 Find all "daffodils" between 0 and 100000 and output.
"Daffodil number" refers to an n-digit number, and the sum of the nth power of each number is indeed equal to the number itself, such as: 153=1^3+5^3+3^3, then 153 is a "daffodil number".
思路
1. 求位数
2. 获取每个位置上的数据,并对其进行立方求和
3. 求和完成后,检测结果是否与其相等
#include <math.h>
//153
int main()
{
int i = 0;
for (i = 0; i <= 100000; i++)
{
int tmp = i;
int n = 1;
//第一步判断是几位数
while (tmp / 10)
{
n++;
tmp = tmp / 10;
}
//计算每一位次方和
tmp = i;
int sum = 0;
while (tmp)
{
sum += pow(tmp % 10, n);
tmp = tmp / 10;
}
//3.判断
if (i == sum)
{
printf("%d ", i);
}
}
return 0;
}
8.4 Printing rhombus
思路
1.为了让第一行*来到中间,其他地方要打印空格,我们先打印上面7行的*,再打印下面6行
2.第一个*左边6个空格,往下一行-1
int main()
{
int n = 0;
scanf("%d", &n);
//输入打印上半部分 n,例如上半部分为7,下半部分自动为6,方便打印成菱形
int i = 0;
for (i = 0; i < n; i++)
{
//打印一行
//打印空格
int j = 0;
for (j=0; j<n-1-i; j++)
{
printf(" ");
}
//打印* *号是1,3,5,7...往下增,i为0时打印一个*,i为1时打印三个*
for (j = 0; j < 2 * i + 1; j++)
{
printf("*");
}
printf("\n");
}
//打印下半部分 n-1
for (i = 0; i < n-1; i++)
{
//打印一行
//打印空格
int j = 0;
for (j = 0; j <= i; j++)
{
printf(" ");
}
//打印*
for (j = 0; j < (n-1-i)*2-1; j++)
{
printf("*");
}
printf("\n");
}
return 0;
}